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. */ }
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); } }
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; }
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); } }
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, ®s[i * (acells + scells)], sizeof(int32_t) * acells); else addr = regs[i * (acells + scells)]; if (scells > 1) memcpy(&size, ®s[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, ®s[i * (acells + scells)], sizeof(int32_t) * acells); else addr = regs[i * (acells + scells)]; if (scells > 1) memcpy(&size, ®s[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; }
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); }
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; }