Пример #1
0
static int
igsfb_ofbus_match(device_t parent, cfdata_t match, void *aux)
{
	struct ofbus_attach_args *oba = aux;

	if (of_compatible(oba->oba_phandle, compat_strings) < 0)
		return 0;

	return 10;	/* beat vga etc. */
}
Пример #2
0
static void
add_model_specifics(prop_dictionary_t dict)
{
	const char *bl_rev_models[] = {
		"PowerBook4,3", "PowerBook6,3", "PowerBook6,5", NULL};
	int node;

	node = OF_finddevice("/");

	if (of_compatible(node, bl_rev_models) != -1) {
		prop_dictionary_set_bool(dict, "backlight_level_reverted", 1);
	}
}
Пример #3
0
int
wdc_obio_match(device_t parent, cfdata_t match, void *aux)
{
	struct confargs *ca = aux;

	/* XXX should not use name */
	if (strcmp(ca->ca_name, "ATA") == 0 ||
	    strcmp(ca->ca_name, "ata") == 0 ||
	    strcmp(ca->ca_name, "ata0") == 0 ||
	    strcmp(ca->ca_name, "ide") == 0)
		return 1;

	if (of_compatible(ca->ca_node, ata_names) >= 0)
		return 1;

	return 0;
}
Пример #4
0
static void
fix_cardbus_bridge(int node, pci_chipset_tag_t pc, pcitag_t tag)
{
	uint32_t bus_number = 0xffffffff;
	pcireg_t bi;
	int bus, dev, fn, ih, len;
	char path[256];

#if PB3400_CARDBUS_HACK
	int root_node;

	root_node = OF_finddevice("/");
	if (of_compatible(root_node, pb3400_compat) != -1) {

		bus_number = cardbus_number;
		cardbus_number++;
	} else {
#endif		
		ih = OF_open(path);
		OF_call_method("load-ata", ih, 0, 0);
		OF_close(ih);

		OF_getprop(node, "AAPL,bus-id", &bus_number,
		    sizeof(bus_number));
#if PB3400_CARDBUS_HACK
	}
#endif
	if (bus_number != 0xffffffff) {

		len = OF_package_to_path(node, path, sizeof(path));
		path[len] = 0;
		aprint_verbose("\n%s: fixing bus number to %d", path, bus_number);
		pci_decompose_tag(pc, tag, &bus, &dev, &fn);
		bi = pci_conf_read(pc, tag, PPB_REG_BUSINFO);
		bi &= 0xff000000;
		/* XXX subordinate is always 32 here */
		bi |= (bus & 0xff) | (bus_number << 8) | 0x200000;
		pci_conf_write(pc, tag, PPB_REG_BUSINFO, bi);
	}
}
Пример #5
0
static void
pmu_attach(device_t parent, device_t self, void *aux)
{
	struct confargs *ca = aux;
	struct pmu_softc *sc = device_private(self);
#if notyet
	struct i2cbus_attach_args iba;
#endif
	uint32_t regs[16];
	int irq = ca->ca_intr[0];
	int node, extint_node, root_node;
	int nbat = 1, i, pmnode;
	int type = IST_EDGE;
	uint8_t cmd[2] = {2, 0};
	uint8_t resp[16];
	char name[256];

	extint_node = of_getnode_byname(OF_parent(ca->ca_node), "extint-gpio1");
	if (extint_node) {

		OF_getprop(extint_node, "interrupts", &irq, 4);
		type = IST_LEVEL;
	}

	aprint_normal(" irq %d: ", irq);

	sc->sc_dev = self;
	sc->sc_node = ca->ca_node;
	sc->sc_memt = ca->ca_tag;

	root_node = OF_finddevice("/");

	sc->sc_error = 0;
	sc->sc_autopoll = 0;
	sc->sc_pending_eject = 0;
	sc->sc_brightness = sc->sc_brightness_wanted = 0x80;
	sc->sc_volume = sc->sc_volume_wanted = 0x80;
	sc->sc_flags = 0;
	sc->sc_callback = NULL;
	sc->sc_lid_closed = 0;

	if (bus_space_map(sc->sc_memt, ca->ca_reg[0] + ca->ca_baseaddr,
	    ca->ca_reg[1], 0, &sc->sc_memh) != 0) {
		aprint_error_dev(self, "unable to map registers\n");
		return;
	}
	sc->sc_ih = intr_establish(irq, type, IPL_TTY, pmu_intr, sc);

	pmu_init(sc);

	sc->sc_pmu_ops.cookie = sc;
	sc->sc_pmu_ops.do_command = pmu_send;
	sc->sc_pmu_ops.register_callback = pmu_register_callback;

	if (pmu0 == NULL)
		pmu0 = sc;

	pmu_send(sc, PMU_SYSTEM_READY, 1, cmd, 16, resp);

	/* check what kind of PMU we're talking to */
	if (pmu_send(sc, PMU_GET_VERSION, 0, cmd, 16, resp) > 1)
		aprint_normal(" rev. %d", resp[1]);
	aprint_normal("\n");

	node = OF_child(sc->sc_node);

	while (node != 0) {

		if (OF_getprop(node, "name", name, 256) == 0)
			goto next;

		if (strncmp(name, "pmu-i2c", 8) == 0) {
			aprint_normal_dev(self, "initializing IIC bus\n");
			goto next;
		}
		if (strncmp(name, "adb", 4) == 0) {
			aprint_normal_dev(self, "initializing ADB\n");
			sc->sc_adbops.cookie = sc;
			sc->sc_adbops.send = pmu_adb_send;
			sc->sc_adbops.poll = pmu_adb_poll;
			sc->sc_adbops.autopoll = pmu_autopoll;
			sc->sc_adbops.set_handler = pmu_adb_set_handler;
#if NNADB > 0
			config_found_ia(self, "adb_bus", &sc->sc_adbops,
			    nadb_print);
#endif
			goto next;
		}
		if (strncmp(name, "rtc", 4) == 0) {

			aprint_normal_dev(self, "initializing RTC\n");
			sc->sc_todr.todr_gettime = pmu_todr_get;
			sc->sc_todr.todr_settime = pmu_todr_set;
			sc->sc_todr.cookie = sc;
			todr_attach(&sc->sc_todr);
			goto next;
		}
		if (strncmp(name, "battery", 8) == 0)
			goto next;

		aprint_normal_dev(self, "%s not configured\n", name);
next:
		node = OF_peer(node);
	}

	if (OF_finddevice("/bandit/ohare") != -1) {
		aprint_normal_dev(self, "enabling ohare backlight control\n");
		sc->sc_flags |= PMU_HAS_BACKLIGHT_CONTROL;
		cmd[0] = 0;
		cmd[1] = 0;
		memset(resp, 0, 6);
		if (pmu_send(sc, PMU_READ_BRIGHTNESS, 1, cmd, 16, resp) > 1) {
			sc->sc_brightness_wanted = resp[1];
			pmu_update_brightness(sc);
		}
	}

	/* attach batteries */
	if (of_compatible(root_node, has_legacy_battery) != -1) {

		pmu_attach_legacy_battery(sc);
	} else if (of_compatible(root_node, has_two_smart_batteries) != -1) {

		pmu_attach_smart_battery(sc, 0);
		pmu_attach_smart_battery(sc, 1);
	} else {

		/* check how many batteries we have */
		pmnode = of_getnode_byname(ca->ca_node, "power-mgt");
		if (pmnode == -1)
			goto bat_done;
		if (OF_getprop(pmnode, "prim-info", regs, sizeof(regs)) < 24)
			goto bat_done;
		nbat = regs[6] >> 16;
		for (i = 0; i < nbat; i++)
			pmu_attach_smart_battery(sc, i);
	}
bat_done:

#if notyet
	memset(&iba, 0, sizeof(iba));
	iba.iba_tag = &sc->sc_i2c;
	sc->sc_i2c.ic_cookie = sc;
	sc->sc_i2c.ic_acquire_bus = pmu_i2c_acquire_bus;
	sc->sc_i2c.ic_release_bus = pmu_i2c_release_bus;
	sc->sc_i2c.ic_send_start = NULL;
	sc->sc_i2c.ic_send_stop = NULL;
	sc->sc_i2c.ic_initiate_xfer = NULL;
	sc->sc_i2c.ic_read_byte = NULL;
	sc->sc_i2c.ic_write_byte = NULL;
	sc->sc_i2c.ic_exec = pmu_i2c_exec;
	config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print);
#endif
	
	if (kthread_create(PRI_NONE, 0, NULL, pmu_thread, sc, &sc->sc_thread,
	    "%s", "pmu") != 0) {
		aprint_error_dev(self, "unable to create event kthread\n");
	}

	sc->sc_lidswitch.smpsw_name = "Lid switch";
	sc->sc_lidswitch.smpsw_type = PSWITCH_TYPE_LID;
	if (sysmon_pswitch_register(&sc->sc_lidswitch) != 0)
		aprint_error_dev(self,
		    "unable to register lid switch with sysmon\n");
}
/*
 * This is called during initppc, before the system is really initialized.
 * It shall provide the total and the available regions of RAM.
 * Both lists must have a zero-size entry as terminator.
 * The available regions need not take the kernel into account, but needs
 * to provide space for two additional entry beyond the terminating one.
 */
void
mem_regions(struct mem_region **memp, struct mem_region **availp)
{
	const char *macrisc[] = {"MacRISC", "MacRISC2", "MacRISC4", NULL};
	int hroot, hmem, i, cnt, memcnt, regcnt, acells, scells;
	int numregs;
	uint32_t regs[OFMEM_REGIONS * 4]; /* 2 values + 2 for 64bit */

	DPRINTF("calling mem_regions\n");
	/* determine acell size */
	if ((hroot = OF_finddevice("/")) == -1)
		goto error;
	cnt = OF_getprop(hroot, "#address-cells", &acells, sizeof(int));
	if (cnt <= 0)
		acells = 1;

	/* determine scell size */
	cnt = OF_getprop(hroot, "#size-cells", &scells, sizeof(int));
	if (cnt <= 0)
		scells = 1;

	/* Get memory */
	memset(regs, 0, sizeof(regs));
	if ((hmem = OF_finddevice("/memory")) == -1)
		goto error;
	regcnt = OF_getprop(hmem, "reg", regs,
	    sizeof(regs[0]) * OFMEM_REGIONS * 4);
	if (regcnt <= 0)
		goto error;

	/* how many mem regions did we get? */
	numregs = regcnt / (sizeof(uint32_t) * (acells + scells));
	DPRINTF("regcnt=%d num=%d acell=%d scell=%d\n",
	    regcnt, numregs, acells, scells);

	/* move the data into OFmem */
	memset(OFmem, 0, sizeof(OFmem));
	for (i = 0, memcnt = 0; i < numregs; i++) {
		uint64_t addr, size;

		if (acells > 1)
			memcpy(&addr, &regs[i * (acells + scells)],
			    sizeof(int32_t) * acells);
		else
			addr = regs[i * (acells + scells)];

		if (scells > 1)
			memcpy(&size, &regs[i * (acells + scells) + acells],
			    sizeof(int32_t) * scells);
		else
			size = regs[i * (acells + scells) + acells];

		/* skip entry of 0 size */
		if (size == 0)
			continue;
#ifndef _LP64
		if (addr > 0xFFFFFFFF || size > 0xFFFFFFFF ||
			(addr + size) > 0xFFFFFFFF) {
			aprint_error("Base addr of %llx or size of %llx too"
			    " large for 32 bit OS. Skipping.", addr, size);
			continue;
		}
#endif
		OFmem[memcnt].start = addr;
		OFmem[memcnt].size = size;
		aprint_normal("mem region %d start=%llx size=%llx\n",
		    memcnt, addr, size);
		memcnt++;
	}

	DPRINTF("available\n");

	/* now do the same thing again, for the available counts */
	memset(regs, 0, sizeof(regs));
	regcnt = OF_getprop(hmem, "available", regs,
	    sizeof(regs[0]) * OFMEM_REGIONS * 4);
	if (regcnt <= 0)
		goto error;

	DPRINTF("%08x %08x %08x %08x\n", regs[0], regs[1], regs[2], regs[3]);

	/*
	 * according to comments in FreeBSD all Apple OF has 32bit values in
	 * "available", no matter what the cell sizes are
	 */
	if (of_compatible(hroot, macrisc) != -1) {
		DPRINTF("this appears to be a mac...\n");
		acells = 1;
		scells = 1;
	}
		
	/* how many mem regions did we get? */
	numregs = regcnt / (sizeof(uint32_t) * (acells + scells));
	DPRINTF("regcnt=%d num=%d acell=%d scell=%d\n",
	    regcnt, numregs, acells, scells);

	DPRINTF("to OF_avail\n");

	/* move the data into OFavail */
	memset(OFavail, 0, sizeof(OFavail));
	for (i = 0, cnt = 0; i < numregs; i++) {
		uint64_t addr, size;

		DPRINTF("%d\n", i);
		if (acells > 1)
			memcpy(&addr, &regs[i * (acells + scells)],
			    sizeof(int32_t) * acells);
		else
			addr = regs[i * (acells + scells)];

		if (scells > 1)
			memcpy(&size, &regs[i * (acells + scells) + acells],
			    sizeof(int32_t) * scells);
		else
			size = regs[i * (acells + scells) + acells];
		/* skip entry of 0 size */
		if (size == 0)
			continue;
#ifndef _LP64
		if (addr > 0xFFFFFFFF || size > 0xFFFFFFFF ||
			(addr + size) > 0xFFFFFFFF) {
			aprint_verbose("Base addr of %llx or size of %llx too"
			    " large for 32 bit OS. Skipping.", addr, size);
			continue;
		}
#endif
		OFavail[cnt].start = addr;
		OFavail[cnt].size = size;
		aprint_normal("avail region %d start=%llx size=%llx\n",
		    cnt, addr, size);
		cnt++;
	}

	if (strncmp(model_name, "Pegasos", 7) == 0) {
		/*
		 * Some versions of SmartFirmware, only recognize the first
		 * 256MB segment as available. Work around it and add an
		 * extra entry to OFavail[] to account for this.
		 */
#define AVAIL_THRESH (0x10000000-1)
		if (((OFavail[cnt-1].start + OFavail[cnt-1].size +
		    AVAIL_THRESH) & ~AVAIL_THRESH) <
		    (OFmem[memcnt-1].start + OFmem[memcnt-1].size)) {

			OFavail[cnt].start =
			    (OFavail[cnt-1].start + OFavail[cnt-1].size +
			    AVAIL_THRESH) & ~AVAIL_THRESH;
			OFavail[cnt].size =
			    OFmem[memcnt-1].size - OFavail[cnt].start;
			aprint_normal("WARNING: add memory segment %lx - %lx,"
			    "\nWARNING: which was not recognized by "
			    "the Firmware.\n",
			    (unsigned long)OFavail[cnt].start,
			    (unsigned long)OFavail[cnt].start +
			    OFavail[cnt].size);
			cnt++;
		}
	}

	*memp = OFmem;
	*availp = OFavail;
	return;

error:
#if defined (MAMBO)
	printf("no memory, assuming 512MB\n");

	OFmem[0].start = 0x0;
	OFmem[0].size = 0x20000000;
	
	OFavail[0].start = 0x3000;
	OFavail[0].size = 0x20000000 - 0x3000;

	*memp = OFmem;
	*availp = OFavail;
#else
	panic("no memory?");
#endif
	return;
}
Пример #7
0
static void
obio_setup_gpios(struct obio_softc *sc, int node)
{
    uint32_t gpio_base, reg[6];
    const struct sysctlnode *sysctl_node, *me, *freq;
    struct cpufreq *cf = &sc->sc_cf;
    char name[32];
    int child, use_dfs, cpunode, hiclock;

    if (of_compatible(sc->sc_node, keylargo) == -1)
        return;

    if (OF_getprop(node, "reg", reg, sizeof(reg)) < 4)
        return;

    gpio_base = reg[0];
    DPRINTF("gpio_base: %02x\n", gpio_base);

    /* now look for voltage and bus speed gpios */
    use_dfs = 0;
    for (child = OF_child(node); child; child = OF_peer(child)) {

        if (OF_getprop(child, "name", name, sizeof(name)) < 1)
            continue;

        if (OF_getprop(child, "reg", reg, sizeof(reg)) < 4)
            continue;

        /*
         * These register offsets either have to be added to the obio
         * base address or to the gpio base address. This differs
         * even in the same OF-tree! So we guess the offset is
         * based on obio when it is larger than the gpio_base.
         */
        if (reg[0] >= gpio_base)
            reg[0] -= gpio_base;

        if (strcmp(name, "frequency-gpio") == 0) {
            DPRINTF("found frequency_gpio at %02x\n", reg[0]);
            sc->sc_busspeed = gpio_base + reg[0];
        }
        if (strcmp(name, "voltage-gpio") == 0) {
            DPRINTF("found voltage_gpio at %02x\n", reg[0]);
            sc->sc_voltage = gpio_base + reg[0];
        }
        if (strcmp(name, "cpu-vcore-select") == 0) {
            DPRINTF("found cpu-vcore-select at %02x\n", reg[0]);
            sc->sc_voltage = gpio_base + reg[0];
            /* frequency gpio is not needed, we use cpu's DFS */
            use_dfs = 1;
        }
    }

    if ((sc->sc_voltage < 0) || (sc->sc_busspeed < 0 && !use_dfs))
        return;

    printf("%s: enabling Intrepid CPU speed control\n",
           device_xname(sc->sc_dev));

    sc->sc_spd_lo = curcpu()->ci_khz / 1000;
    hiclock = 0;
    cpunode = OF_finddevice("/cpus/@0");
    OF_getprop(cpunode, "clock-frequency", &hiclock, 4);
    if (hiclock != 0)
        sc->sc_spd_hi = (hiclock + 500000) / 1000000;
    printf("hiclock: %d\n", sc->sc_spd_hi);

    sysctl_node = NULL;

    if (sysctl_createv(NULL, 0, NULL,
                       &me,
                       CTLFLAG_READWRITE, CTLTYPE_NODE, "intrepid", NULL, NULL,
                       0, NULL, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL) != 0)
        printf("couldn't create 'intrepid' node\n");

    if (sysctl_createv(NULL, 0, NULL,
                       &freq,
                       CTLFLAG_READWRITE, CTLTYPE_NODE, "frequency", NULL, NULL,
                       0, NULL, 0, CTL_MACHDEP, me->sysctl_num, CTL_CREATE, CTL_EOL) != 0)
        printf("couldn't create 'frequency' node\n");

    if (sysctl_createv(NULL, 0, NULL,
                       &sysctl_node,
                       CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
                       CTLTYPE_INT, "target", "CPU speed", sysctl_cpuspeed_temp,
                       0, (void *)sc, 0, CTL_MACHDEP, me->sysctl_num, freq->sysctl_num,
                       CTL_CREATE, CTL_EOL) == 0) {
    } else
        printf("couldn't create 'target' node\n");

    if (sysctl_createv(NULL, 0, NULL,
                       &sysctl_node,
                       CTLFLAG_READWRITE,
                       CTLTYPE_INT, "current", NULL, sysctl_cpuspeed_cur,
                       1, (void *)sc, 0, CTL_MACHDEP, me->sysctl_num, freq->sysctl_num,
                       CTL_CREATE, CTL_EOL) == 0) {
    } else
        printf("couldn't create 'current' node\n");

    if (sysctl_createv(NULL, 0, NULL,
                       &sysctl_node,
                       CTLFLAG_READWRITE,
                       CTLTYPE_STRING, "available", NULL, sysctl_cpuspeed_available,
                       2, (void *)sc, 0, CTL_MACHDEP, me->sysctl_num, freq->sysctl_num,
                       CTL_CREATE, CTL_EOL) == 0) {
    } else
        printf("couldn't create 'available' node\n");
    printf("speed: %d\n", curcpu()->ci_khz);

    /* support cpufreq */
    snprintf(cf->cf_name, CPUFREQ_NAME_MAX, "Intrepid");
    cf->cf_state[0].cfs_freq = sc->sc_spd_hi;
    cf->cf_state[1].cfs_freq = sc->sc_spd_lo;
    cf->cf_state_count = 2;
    cf->cf_mp = FALSE;
    cf->cf_cookie = sc;
    cf->cf_get_freq = obio_get_freq;
    cf->cf_set_freq = obio_set_freq;
    /*
     * XXX
     * cpufreq_register() calls xc_broadcast() which relies on kthreads
     * running so we need to postpone it
     */
    config_interrupts(sc->sc_dev, obio_setup_cpufreq);
}
Пример #8
0
int
igsfb_ofbus_cnattach(bus_space_tag_t iot, bus_space_tag_t memt)
{
	struct igsfb_devconfig *dc;
	int ret;
	int chosen_phandle, igs_node;
	int stdout_ihandle, stdout_phandle;
	uint32_t regs[16];
	char mode_buffer[64];

	stdout_phandle = 0;

	/* first find out if there's a CyberPro at all in this machine */
	igs_node = OF_finddevice("/vlbus/display");
	if (igs_node == -1)
		return ENXIO;
	if (of_compatible(igs_node, compat_strings) < 0) 
		return ENXIO;

	/*
	 * now we know there's a CyberPro in this machine so map it into
	 * kernel space, even if it's not the console
	 */
	if (OF_getprop(igs_node, "reg", regs, sizeof(regs)) <= 0)
		return ENXIO;

	igsfb_mem_paddr = be32toh(regs[13]);
	/* 4MB VRAM aperture, bufferable and cacheable */
	igsfb_mem_vaddr = ofw_map(igsfb_mem_paddr, 0x00400000, L2_B);
	/* MMIO registers */
	igsfb_mmio_vaddr = ofw_map(igsfb_mem_paddr + IGS_MEM_MMIO_SELECT,
	    0x00100000, 0);

	memcpy(&igsfb_memt, memt, sizeof(struct bus_space));
	igsfb_memt.bs_cookie = (void *)igsfb_mem_vaddr;
	memcpy(&igsfb_iot, memt, sizeof(struct bus_space));
	igsfb_iot.bs_cookie = (void *)igsfb_mmio_vaddr;

	/*
	 * check if the firmware output device is indeed the CyberPro
	 */
	if ((chosen_phandle = OF_finddevice("/chosen")) == -1 ||
	    OF_getprop(chosen_phandle, "stdout", &stdout_ihandle, 
	    sizeof(stdout_ihandle)) != sizeof(stdout_ihandle)) {
		return ENXIO;
	}
	stdout_ihandle = of_decode_int((void *)&stdout_ihandle);
	stdout_phandle = OF_instance_to_package(stdout_ihandle);

	if (stdout_phandle != igs_node)
		return ENXIO;

	/* ok, now setup and attach the console */
	dc = &igsfb_console_dc;
	ret = igsfb_setup_dc(dc);
	if (ret)
		return ret;

	if (of_get_mode_string(mode_buffer, sizeof(mode_buffer))) {
		strcpy(dc->dc_modestring, mode_buffer);
	}	

	ret = igsfb_cnattach_subr(dc);
	if (ret)
		return ret;

	igsfb_ofbus_console = 1;
	igsfb_ofbus_phandle = stdout_phandle;
#if (NIGSFB_OFBUS > 0) || (NVGA_OFBUS > 0)
	console_ihandle = stdout_ihandle;
#endif
	return 0;
}