/* * Attach all the sub-devices we can find */ void obio_attach(struct device *parent, struct device *self, void *aux) { struct obio_softc *sc = (struct obio_softc *)self; struct pci_attach_args *pa = aux; struct confargs ca; bus_space_handle_t bsh; int node, child, namelen, error; u_int reg[20]; int intr[6], parent_intr = 0, parent_nintr = 0; char name[32]; char compat[32]; #ifdef OBIO_SPEED_CONTROL sc->sc_voltage = -1; sc->sc_busspeed = -1; #endif switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_APPLE_GC: case PCI_PRODUCT_APPLE_OHARE: case PCI_PRODUCT_APPLE_HEATHROW: case PCI_PRODUCT_APPLE_PADDINGTON: case PCI_PRODUCT_APPLE_KEYLARGO: case PCI_PRODUCT_APPLE_PANGEA_MACIO: case PCI_PRODUCT_APPLE_INTREPID: node = pcidev_to_ofdev(pa->pa_pc, pa->pa_tag); if (node == -1) node = OF_finddevice("mac-io"); if (node == -1) node = OF_finddevice("/pci/mac-io"); break; case PCI_PRODUCT_APPLE_K2: node = OF_finddevice("mac-io"); break; default: node = -1; break; } if (node == -1) panic("macio not found or unknown"); sc->sc_node = node; #if defined (PMAC_G5) if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg)) < 20) { return; } #else if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg)) < 12) return; #endif /* PMAC_G5 */ /* * XXX * This relies on the primary obio always attaching first which is * true on the PowerBook 3400c and similar machines but may or may * not work on others. We can't rely on the node name since Apple * didn't follow anything remotely resembling a consistent naming * scheme. */ if (obio0 == NULL) obio0 = sc; ca.ca_baseaddr = reg[2]; ca.ca_tag = pa->pa_memt; sc->sc_tag = pa->pa_memt; error = bus_space_map (pa->pa_memt, ca.ca_baseaddr, 0x80, 0, &bsh); if (error) panic(": failed to map mac-io %#x", ca.ca_baseaddr); sc->sc_bh = bsh; printf(": addr 0x%x\n", ca.ca_baseaddr); /* Enable internal modem (KeyLargo) */ if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_KEYLARGO) { aprint_normal("%s: enabling KeyLargo internal modem\n", self->dv_xname); bus_space_write_4(ca.ca_tag, bsh, 0x40, bus_space_read_4(ca.ca_tag, bsh, 0x40) & ~(1<<25)); } /* Enable internal modem (Pangea) */ if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_PANGEA_MACIO) { /* set reset */ bus_space_write_1(ca.ca_tag, bsh, 0x006a + 0x03, 0x04); /* power modem on */ bus_space_write_1(ca.ca_tag, bsh, 0x006a + 0x02, 0x04); /* unset reset */ bus_space_write_1(ca.ca_tag, bsh, 0x006a + 0x03, 0x05); } /* Gatwick and Paddington use same product ID */ namelen = OF_getprop(node, "compatible", compat, sizeof(compat)); if (strcmp(compat, "gatwick") == 0) { parent_nintr = OF_getprop(node, "AAPL,interrupts", intr, sizeof(intr)); parent_intr = intr[0]; } else { /* Enable CD and microphone sound input. */ if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_PADDINGTON) bus_space_write_1(ca.ca_tag, bsh, 0x37, 0x03); } for (child = OF_child(node); child; child = OF_peer(child)) { namelen = OF_getprop(child, "name", name, sizeof(name)); if (namelen < 0) continue; if (namelen >= sizeof(name)) continue; #ifdef OBIO_SPEED_CONTROL if (strcmp(name, "gpio") == 0) { obio_setup_gpios(sc, child); continue; } #endif name[namelen] = 0; ca.ca_name = name; ca.ca_node = child; ca.ca_tag = pa->pa_memt; ca.ca_nreg = OF_getprop(child, "reg", reg, sizeof(reg)); if (strcmp(compat, "gatwick") != 0) { ca.ca_nintr = OF_getprop(child, "AAPL,interrupts", intr, sizeof(intr)); if (ca.ca_nintr == -1) ca.ca_nintr = OF_getprop(child, "interrupts", intr, sizeof(intr)); } else { intr[0] = parent_intr; ca.ca_nintr = parent_nintr; } ca.ca_reg = reg; ca.ca_intr = intr; config_found(self, &ca, obio_print); } }
static void ofbattach(device_t parent, device_t self, void *aux) { struct ofb_softc *sc = device_private(self); struct pci_attach_args *pa = aux; struct wsemuldisplaydev_attach_args a; struct rasops_info *ri = &rascons_console_screen.scr_ri; long defattr; int console, node, sub; char devinfo[256]; sc->sc_dev = self; pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); printf(": %s\n", devinfo); if (console_node == 0) return; node = pcidev_to_ofdev(pa->pa_pc, pa->pa_tag); console = (node == console_node); if (!console) { /* check if any of the childs matches */ sub = OF_child(node); while ((sub != 0) && (sub != console_node)) { sub = OF_peer(sub); } if (sub == console_node) { console = true; } } sc->sc_memt = pa->pa_memt; sc->sc_iot = pa->pa_iot; sc->sc_pc = pa->pa_pc; sc->sc_pcitag = pa->pa_tag; sc->sc_mode = WSDISPLAYIO_MODE_EMUL; if (!console) return; vcons_init(&sc->vd, sc, &rascons_stdscreen, &ofb_accessops); sc->vd.init_screen = ofb_init_screen; sc->sc_node = console_node; sc->sc_ih = console_instance; vcons_init_screen(&sc->vd, &rascons_console_screen, 1, &defattr); rascons_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; printf("%s: %d x %d, %dbpp\n", device_xname(self), ri->ri_width, ri->ri_height, ri->ri_depth); sc->sc_fbaddr = 0; if (OF_getprop(sc->sc_node, "address", &sc->sc_fbaddr, 4) != 4) OF_interpret("frame-buffer-adr", 0, 1, &sc->sc_fbaddr); if (sc->sc_fbaddr == 0) { printf("%s: Unable to find the framebuffer address.\n", device_xname(sc->sc_dev)); return; } sc->sc_fbsize = round_page(ri->ri_stride * ri->ri_height); /* XXX */ if (OF_getprop(sc->sc_node, "assigned-addresses", sc->sc_addrs, sizeof(sc->sc_addrs)) == -1) { sc->sc_node = OF_parent(sc->sc_node); OF_getprop(sc->sc_node, "assigned-addresses", sc->sc_addrs, sizeof(sc->sc_addrs)); } ofb_init_cmap(sc); a.console = console; a.scrdata = &ofb_screenlist; a.accessops = &ofb_accessops; a.accesscookie = &sc->vd; config_found(self, &a, wsemuldisplaydevprint); config_found_ia(self, "drm", aux, ofb_drm_print); }