void gfb_attach(struct device *parent, struct device *self, void *aux) { struct gfb_softc *sc = (struct gfb_softc *)self; struct mainbus_attach_args *ma = aux; extern int fbnode; sc->sc_bt = ma->ma_bustag; printf("\n"); if (bus_space_map(ma->ma_bustag, ma->ma_reg[6].ur_paddr, ma->ma_reg[6].ur_len, BUS_SPACE_MAP_LINEAR, &sc->sc_pixel_h)) return; sc->sc_console = (fbnode == ma->ma_node); sc->sc_node = ma->ma_node; fb_setsize(&sc->sc_sunfb, 32, 1152, 900, sc->sc_node, 0); /* linesize has a fixed value, compensate */ sc->sc_sunfb.sf_linebytes = 16384; sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_height * 16384; sc->sc_sunfb.sf_ro.ri_bits = (void *)bus_space_vaddr(sc->sc_bt, sc->sc_pixel_h); sc->sc_sunfb.sf_ro.ri_hw = sc; fbwscons_init(&sc->sc_sunfb, 0, sc->sc_console); if (sc->sc_console) fbwscons_console_init(&sc->sc_sunfb, -1); fbwscons_attach(&sc->sc_sunfb, &gfb_accessops, sc->sc_console); return; }
void cgeightattach(struct device *parent, struct device *self, void *args) { struct cgeight_softc *sc = (struct cgeight_softc *)self; struct confargs *ca = args; int node = 0; volatile struct bt_regs *bt; int isconsole = 0; /* Map the pfour register. */ SET(sc->sc_sunfb.sf_flags, FB_PFOUR); sc->sc_sunfb.sf_pfour = (volatile u_int32_t *) mapiodev(ca->ca_ra.ra_reg, 0, sizeof(u_int32_t)); if (cputyp == CPU_SUN4) { struct eeprom *eep = (struct eeprom *)eeprom_va; /* * Assume this is the console if there's no eeprom info * to be found. */ if (eep == NULL || eep->ee_diag.eed_console == EED_CONS_P4) isconsole = 1; } /* Map the Brooktree. */ sc->sc_fbc = (volatile struct fbcontrol *) mapiodev(ca->ca_ra.ra_reg, PFOUR_COLOR_OFF_CMAP, sizeof(struct fbcontrol)); sc->sc_phys = ca->ca_ra.ra_reg[0]; /* enable video */ fb_pfour_burner(sc, 1, 0); bt = &sc->sc_fbc->fbc_dac; BT_INIT(bt, 0); fb_setsize(&sc->sc_sunfb, 1, 1152, 900, node, ca->ca_bustype); sc->sc_sunfb.sf_ro.ri_hw = sc; /* * Map the overlay and overlay enable planes. */ sc->sc_enable = (volatile u_char *)mapiodev(ca->ca_ra.ra_reg, PFOUR_COLOR_OFF_ENABLE, round_page(sc->sc_sunfb.sf_fbsize)); sc->sc_sunfb.sf_ro.ri_bits = mapiodev(ca->ca_ra.ra_reg, PFOUR_COLOR_OFF_OVERLAY, round_page(sc->sc_sunfb.sf_fbsize)); cgeight_reset(sc, WSDISPLAYIO_MODE_EMUL); printf(": p4, %dx%d", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); fbwscons_init(&sc->sc_sunfb, isconsole); if (isconsole) fbwscons_console_init(&sc->sc_sunfb, -1); fbwscons_attach(&sc->sc_sunfb, &cgeight_accessops, isconsole); }
void tcxattach(struct device *parent, struct device *self, void *args) { struct tcx_softc *sc = (struct tcx_softc *)self; struct confargs *ca = args; int node, pri; int isconsole = 0; char *nam = NULL; vaddr_t thc_offset; pri = ca->ca_ra.ra_intr[0].int_pri; printf(" pri %d: ", pri); node = ca->ca_ra.ra_node; isconsole = node == fbnode; if (ca->ca_ra.ra_nreg < TCX_NREG) { printf("expected %d registers, got %d\n", TCX_NREG, ca->ca_ra.ra_nreg); return; } nam = getpropstring(node, "model"); if (*nam != '\0') printf("%s, ", nam); /* * Copy the register address spaces needed for mmap operation. */ sc->sc_phys[0] = ca->ca_ra.ra_reg[TCX_REG_DFB8]; sc->sc_phys[1] = ca->ca_ra.ra_reg[TCX_REG_DFB24]; /* * Can't trust the PROM range len here, it is only 4 bytes on the * 8-bit model. Not that it matters much anyway since we map in * pages. */ sc->sc_bt = (volatile struct bt_regs *) mapiodev(&ca->ca_ra.ra_reg[TCX_REG_CMAP], 0, sizeof *sc->sc_bt); /* * For some reason S24 PROM sets up TEC and THC ranges at the * right addresses (701000 and 301000), while 8 bit TCX doesn't * (and uses 70000 and 30000) - be sure to only compensate on 8 bit * models. */ if (((vaddr_t)ca->ca_ra.ra_reg[TCX_REG_THC].rr_paddr & 0x1000) != 0) thc_offset = 0; else thc_offset = 0x1000; sc->sc_thc = (volatile struct tcx_thc *) mapiodev(&ca->ca_ra.ra_reg[TCX_REG_THC], thc_offset, sizeof *sc->sc_thc); /* * Find out frame buffer geometry, so that we know how much * memory to map. */ fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype); sc->sc_dfb8 = mapiodev(&ca->ca_ra.ra_reg[TCX_REG_DFB8], 0, round_page(sc->sc_sunfb.sf_fbsize)); /* * If the frame buffer advertizes itself as the 8 bit model, or * if the PROM ranges are too small, limit ourselves to 8 bit * operations. * * Further code needing to know which capabilities the frame buffer * has will rely on sc_cplane being non-zero if 24 bit operation * is possible. */ if (!node_has_property(node, "tcx-8-bit") && ca->ca_ra.ra_reg[TCX_REG_RDFB32].rr_len >= sc->sc_sunfb.sf_fbsize * 4) { sc->sc_cplane = (paddr_t)ca->ca_ra.ra_reg[TCX_REG_RDFB32].rr_paddr; } printf("%dx%dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height, sc->sc_cplane == 0 ? 8 : 24); /* * Set up mappings for the acceleration code. This may fail. */ tcx_accel_init(sc, ca); /* reset cursor & frame buffer controls */ tcx_reset(sc, 8); /* enable video */ tcx_burner(sc, 1, 0); sc->sc_sunfb.sf_ro.ri_hw = sc; sc->sc_sunfb.sf_ro.ri_bits = (void *)sc->sc_dfb8; fbwscons_init(&sc->sc_sunfb, isconsole); fbwscons_setcolormap(&sc->sc_sunfb, tcx_setcolor); /* * Now plug accelerated console routines, if possible. */ tcx_accel_plug(sc, ca); sc->sc_ih.ih_fun = tcx_intr; sc->sc_ih.ih_arg = sc; intr_establish(pri, &sc->sc_ih, IPL_FB, self->dv_xname); if (isconsole) { fbwscons_console_init(&sc->sc_sunfb, -1); shutdownhook_establish(tcx_prom, sc); } fbwscons_attach(&sc->sc_sunfb, &tcx_accessops, isconsole); }
void cgtwoattach(struct device *parent, struct device *self, void *args) { struct cgtwo_softc *sc = (struct cgtwo_softc *)self; struct confargs *ca = args; int node = 0; int isconsole = 0; if (CPU_ISSUN4) { struct eeprom *eep = (struct eeprom *)eeprom_va; /* * Assume this is the console if there's no eeprom info * to be found. */ if (eep == NULL || eep->eeConsole == EE_CONS_COLOR) isconsole = 1; } /* * When the ROM has mapped in a cgtwo display, the address * maps only the video RAM, so in any case we have to map the * registers ourselves. */ sc->sc_phys = ca->ca_ra.ra_reg[0]; /* Apparently, the pixels are 32-bit data space */ sc->sc_phys.rr_iospace = PMAP_VME32; sc->sc_reg = (volatile struct cg2statusreg *) mapiodev(ca->ca_ra.ra_reg, CG2_ROPMEM_OFF + offsetof(struct cg2fb, status.reg), sizeof(struct cg2statusreg)); sc->sc_ppmask = (volatile u_short *) mapiodev(ca->ca_ra.ra_reg, CG2_ROPMEM_OFF + offsetof(struct cg2fb, ppmask.reg), sizeof(u_short)); sc->sc_cmap = (volatile u_short *) mapiodev(ca->ca_ra.ra_reg, CG2_ROPMEM_OFF + offsetof(struct cg2fb, redmap), 3 * CG2_CMSIZE * sizeof(u_short)); /* enable video */ *sc->sc_ppmask = 0xffff; /* enable all color planes... */ cgtwo_burner(sc, 1, 0); /* ... and video signals */ fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype); sc->sc_sunfb.sf_ro.ri_bits = mapiodev(&sc->sc_phys, CG2_PIXMAP_OFF, round_page(sc->sc_sunfb.sf_fbsize)); sc->sc_sunfb.sf_ro.ri_hw = sc; fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR); fbwscons_setcolormap(&sc->sc_sunfb, cgtwo_setcolor); printf(": %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); if (isconsole) { fbwscons_console_init(&sc->sc_sunfb, -1); } fbwscons_attach(&sc->sc_sunfb, &cgtwo_accessops, isconsole); }
void cgtwelveattach(struct device *parent, struct device *self, void *args) { struct cgtwelve_softc *sc = (struct cgtwelve_softc *)self; struct confargs *ca = args; int node; int isconsole = 0; char *ps; node = ca->ca_ra.ra_node; printf(": %s", getpropstring(node, "model")); ps = getpropstring(node, "dev_id"); if (*ps != '\0') printf(" (%s)", ps); printf("\n"); isconsole = node == fbnode; sc->sc_phys = ca->ca_ra.ra_reg[0]; /* * Map registers */ sc->sc_dpu = (struct cgtwelve_dpu *)mapiodev(ca->ca_ra.ra_reg, CG12_OFF_DPU, sizeof(struct cgtwelve_dpu)); sc->sc_apu = (struct cgtwelve_apu *)mapiodev(ca->ca_ra.ra_reg, CG12_OFF_APU, sizeof(struct cgtwelve_apu)); sc->sc_ramdac = (struct cgtwelve_dac *)mapiodev(ca->ca_ra.ra_reg, CG12_OFF_DAC, sizeof(struct cgtwelve_dac)); /* * The console is using the 1-bit overlay plane, while the prom * will correctly report 32 bit depth. */ fb_setsize(&sc->sc_sunfb, 1, CG12_WIDTH, CG12_HEIGHT, node, ca->ca_bustype); sc->sc_sunfb.sf_depth = 1; sc->sc_sunfb.sf_linebytes = sc->sc_sunfb.sf_width / 8; sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_height * sc->sc_sunfb.sf_linebytes; sc->sc_highres = sc->sc_sunfb.sf_width == CG12_WIDTH_HR; /* * Map planes */ sc->sc_overlay = mapiodev(ca->ca_ra.ra_reg, sc->sc_highres ? CG12_OFF_OVERLAY0_HR : CG12_OFF_OVERLAY0, round_page(sc->sc_highres ? CG12_SIZE_OVERLAY_HR : CG12_SIZE_OVERLAY)); sc->sc_inten = mapiodev(ca->ca_ra.ra_reg, sc->sc_highres ? CG12_OFF_INTEN_HR : CG12_OFF_INTEN, round_page(sc->sc_highres ? CG12_SIZE_COLOR24_HR : CG12_SIZE_COLOR24)); /* reset cursor & frame buffer controls */ sc->sc_sunfb.sf_depth = 0; /* force action */ cgtwelve_reset(sc, 1); sc->sc_sunfb.sf_ro.ri_bits = (void *)sc->sc_overlay; sc->sc_sunfb.sf_ro.ri_hw = sc; fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR); if (isconsole) { fbwscons_console_init(&sc->sc_sunfb, -1); shutdownhook_establish(cgtwelve_prom, sc); } printf("%s: %dx%d", self->dv_xname, sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); ps = getpropstring(node, "ucoderev"); if (*ps != '\0') printf(", microcode rev. %s", ps); printf("\n"); fbwscons_attach(&sc->sc_sunfb, &cgtwelve_accessops, isconsole); }
/* * Attach an MGX frame buffer. * This will keep the frame buffer in the actual PROM mode, and attach * a wsdisplay child device to itself. */ void mgxattach(struct device *parent, struct device *self, void *args) { struct mgx_softc *sc = (struct mgx_softc *)self; struct sbus_attach_args *sa = args; bus_space_tag_t bt; bus_space_handle_t bh; int node, fbsize; int isconsole; uint16_t chipid; bt = sa->sa_bustag; node = sa->sa_node; printf(": %s", getpropstring(node, "model")); isconsole = node == fbnode; /* Check registers */ if (sa->sa_nreg < MGX_NREG) { printf("\n%s: expected %d registers, got %d\n", self->dv_xname, MGX_NREG, sa->sa_nreg); return; } sc->sc_bustag = bt; if (sbus_bus_map(bt, sa->sa_reg[MGX_REG_CRTC].sbr_slot, sa->sa_reg[MGX_REG_CRTC].sbr_offset, PAGE_SIZE, BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("\n%s: couldn't map crtc registers\n", self->dv_xname); return; } sc->sc_vidc = (vaddr_t)bus_space_vaddr(bt, bh); sc->sc_bustag = bt; if (sbus_bus_map(bt, sa->sa_reg[MGX_REG_ATREG].sbr_slot, sa->sa_reg[MGX_REG_ATREG].sbr_offset + MGX_REG_ATREG_OFFSET, MGX_REG_ATREG_SIZE, BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("\n%s: couldn't map crtc registers\n", self->dv_xname); /* XXX unmap vidc */ return; } sc->sc_xreg = (vaddr_t)bus_space_vaddr(bt, bh); /* * Check the chip ID. If it's not an AT24, prefer not to access * the extended registers at all. */ chipid = mgx_read_2(sc->sc_xreg, ATR_ID); if (chipid != ID_AT24) { sc->sc_xreg = (vaddr_t)0; } /* enable video */ mgx_burner(sc, 1, 0); fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0); /* Sanity check frame buffer memory */ fbsize = getpropint(node, "fb_size", 0); if (fbsize != 0 && sc->sc_sunfb.sf_fbsize > fbsize) { printf("\n%s: expected at least %d bytes of vram, but card " "only provides %d\n", self->dv_xname, sc->sc_sunfb.sf_fbsize, fbsize); return; } /* Map the frame buffer memory area we're interested in */ sc->sc_paddr = sbus_bus_addr(bt, sa->sa_reg[MGX_REG_VRAM8].sbr_slot, sa->sa_reg[MGX_REG_VRAM8].sbr_offset); if (sbus_bus_map(bt, sa->sa_reg[MGX_REG_VRAM8].sbr_slot, sa->sa_reg[MGX_REG_VRAM8].sbr_offset, round_page(sc->sc_sunfb.sf_fbsize), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("\n%s: couldn't map video memory\n", self->dv_xname); /* XXX unmap vidc and xreg */ return; } sc->sc_sunfb.sf_ro.ri_bits = bus_space_vaddr(bt, bh); sc->sc_sunfb.sf_ro.ri_hw = sc; printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); fbwscons_init(&sc->sc_sunfb, 0, isconsole); bzero(sc->sc_cmap, sizeof(sc->sc_cmap)); fbwscons_setcolormap(&sc->sc_sunfb, mgx_setcolor); if (chipid != ID_AT24) { printf("%s: unexpected engine id %04x\n", self->dv_xname, chipid); } mgx_ras_init(sc, chipid); if (isconsole) fbwscons_console_init(&sc->sc_sunfb, -1); fbwscons_attach(&sc->sc_sunfb, &mgx_accessops, isconsole); }
void cgfourattach(struct device *parent, struct device *self, void *args) { struct cgfour_softc *sc = (struct cgfour_softc *)self; struct confargs *ca = args; int node = 0; volatile struct bt_regs *bt; int isconsole = 0; printf(": p4"); /* Map the pfour register. */ SET(sc->sc_sunfb.sf_flags, FB_PFOUR); sc->sc_sunfb.sf_pfour = (volatile u_int32_t *) mapiodev(ca->ca_ra.ra_reg, 0, sizeof(u_int32_t)); if (cputyp == CPU_SUN4) { struct eeprom *eep = (struct eeprom *)eeprom_va; /* * Assume this is the console if there's no eeprom info * to be found. */ if (eep == NULL || eep->eeConsole == EE_CONS_P4OPT) isconsole = 1; } /* * When the ROM has mapped in a cgfour display, the address * maps only the video RAM, so in any case we have to map the * registers ourselves. We only need the video RAM if we are * going to print characters via rconsole. */ sc->sc_phys = ca->ca_ra.ra_reg[0]; /* enable video */ fb_pfour_burner(sc, 1, 0); bt = &sc->sc_fbc->fbc_dac; BT_INIT(bt, 24); /* * XXX should initialize the enable plane, instead of expecting the * PROM to do so for us */ fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype); /* * XXX this only maps the color plane, not the overlay or the enable * planes */ sc->sc_sunfb.sf_ro.ri_bits = mapiodev(ca->ca_ra.ra_reg, PFOUR_COLOR_OFF_COLOR, round_page(sc->sc_sunfb.sf_fbsize)); sc->sc_sunfb.sf_ro.ri_hw = sc; fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR); fbwscons_setcolormap(&sc->sc_sunfb, cgfour_setcolor); printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); if (isconsole) { fbwscons_console_init(&sc->sc_sunfb, -1); } fbwscons_attach(&sc->sc_sunfb, &cgfour_accessops, isconsole); }
/** * radeon_driver_load_kms - Main load function for KMS. * * @dev: drm dev pointer * @flags: device flags * * This is the main load function for KMS (all asics). * It calls radeon_device_init() to set up the non-display * parts of the chip (asic init, CP, writeback, etc.), and * radeon_modeset_init() to set up the display parts * (crtcs, encoders, hotplug detect, etc.). * Returns 0 on success, error on failure. */ void radeondrm_attach_kms(struct device *parent, struct device *self, void *aux) { struct radeon_device *rdev = (struct radeon_device *)self; struct drm_device *dev; struct pci_attach_args *pa = aux; const struct drm_pcidev *id_entry; int is_agp; pcireg_t type; uint8_t iobar; #if defined(__sparc64__) || defined(__macppc__) extern int fbnode; #endif id_entry = drm_find_description(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id), radeondrm_pciidlist); rdev->flags = id_entry->driver_data; rdev->pc = pa->pa_pc; rdev->pa_tag = pa->pa_tag; rdev->iot = pa->pa_iot; rdev->memt = pa->pa_memt; rdev->dmat = pa->pa_dmat; #if defined(__sparc64__) || defined(__macppc__) if (fbnode == PCITAG_NODE(rdev->pa_tag)) rdev->console = 1; #else if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY && PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA && (pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) & (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) == (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) { rdev->console = 1; #if NVGA > 0 vga_console_attached = 1; #endif } #endif #define RADEON_PCI_MEM 0x10 #define RADEON_PCI_IO 0x14 #define RADEON_PCI_MMIO 0x18 #define RADEON_PCI_IO2 0x20 type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM); if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM || pci_mapreg_info(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM, type, &rdev->fb_aper_offset, &rdev->fb_aper_size, NULL)) { printf(": can't get frambuffer info\n"); return; } if (PCI_MAPREG_MEM_TYPE(type) != PCI_MAPREG_MEM_TYPE_64BIT) iobar = RADEON_PCI_IO; else iobar = RADEON_PCI_IO2; if (pci_mapreg_map(pa, iobar, PCI_MAPREG_TYPE_IO, 0, NULL, &rdev->rio_mem, NULL, &rdev->rio_mem_size, 0)) { printf(": can't map IO space\n"); return; } type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MMIO); if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM || pci_mapreg_map(pa, RADEON_PCI_MMIO, type, 0, NULL, &rdev->rmmio, &rdev->rmmio_base, &rdev->rmmio_size, 0)) { printf(": can't map mmio space\n"); return; } if (pci_intr_map(pa, &rdev->intrh) != 0) { printf(": couldn't map interrupt\n"); return; } printf(": %s\n", pci_intr_string(pa->pa_pc, rdev->intrh)); #ifdef notyet mtx_init(&rdev->swi_lock, IPL_TTY); #endif /* update BUS flag */ if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL)) { rdev->flags |= RADEON_IS_AGP; } else if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIEXPRESS, NULL, NULL)) { rdev->flags |= RADEON_IS_PCIE; } else { rdev->flags |= RADEON_IS_PCI; } DRM_DEBUG("%s card detected\n", ((rdev->flags & RADEON_IS_AGP) ? "AGP" : (((rdev->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); is_agp = pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL); dev = (struct drm_device *)drm_attach_pci(&kms_driver, pa, is_agp, self); rdev->ddev = dev; rdev->irqh = pci_intr_establish(pa->pa_pc, rdev->intrh, IPL_TTY, radeon_driver_irq_handler_kms, rdev->ddev, rdev->dev.dv_xname); if (rdev->irqh == NULL) { printf("%s: couldn't establish interrupt\n", rdev->dev.dv_xname); return; } #ifdef __sparc64__ { struct rasops_info *ri; int node, console; node = PCITAG_NODE(pa->pa_tag); console = (fbnode == node); fb_setsize(&rdev->sf, 8, 1152, 900, node, 0); /* * The firmware sets up the framebuffer such that at starts at * an offset from the start of video memory. */ rdev->fb_offset = bus_space_read_4(rdev->memt, rdev->rmmio, RADEON_CRTC_OFFSET); if (bus_space_map(rdev->memt, rdev->fb_aper_offset + rdev->fb_offset, rdev->sf.sf_fbsize, BUS_SPACE_MAP_LINEAR, &rdev->memh)) { printf("%s: can't map video memory\n", rdev->dev.dv_xname); return; } ri = &rdev->sf.sf_ro; ri->ri_bits = bus_space_vaddr(rdev->memt, rdev->memh); ri->ri_hw = rdev; ri->ri_updatecursor = NULL; fbwscons_init(&rdev->sf, RI_VCONS | RI_WRONLY | RI_BSWAP, console); if (console) fbwscons_console_init(&rdev->sf, -1); } #endif rdev->shutdown = true; if (rootvp == NULL) mountroothook_establish(radeondrm_attachhook, rdev); else radeondrm_attachhook(rdev); }
void cgthreeattach(struct device *parent, struct device *self, void *aux) { struct cgthree_softc *sc = (struct cgthree_softc *)self; struct sbus_attach_args *sa = aux; int node, console; const char *nam; node = sa->sa_node; sc->sc_bustag = sa->sa_bustag; sc->sc_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_slot, sa->sa_offset); fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0); if (sa->sa_nreg != 1) { printf(": expected %d registers, got %d\n", 1, sa->sa_nreg); goto fail; } /* * Map just CTRL and video RAM. */ if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot, sa->sa_reg[0].sbr_offset + CGTHREE_CTRL_OFFSET, CGTHREE_CTRL_SIZE, 0, 0, &sc->sc_ctrl_regs) != 0) { printf(": cannot map ctrl registers\n"); goto fail_ctrl; } if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot, sa->sa_reg[0].sbr_offset + CGTHREE_VID_OFFSET, sc->sc_sunfb.sf_fbsize, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_vid_regs) != 0) { printf(": cannot map vid registers\n"); goto fail_vid; } nam = getpropstring(node, "model"); if (*nam == '\0') nam = sa->sa_name; printf(": %s", nam); console = cgthree_is_console(node); cgthree_reset(sc); cgthree_burner(sc, 1, 0); sc->sc_sunfb.sf_ro.ri_bits = (void *)bus_space_vaddr(sc->sc_bustag, sc->sc_vid_regs); sc->sc_sunfb.sf_ro.ri_hw = sc; printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); /* * If the framebuffer width is under 1024x768, which is the case for * some clones on laptops, as well as with the VS10-EK, switch from * the PROM font to the more adequate 8x16 font here. * However, we need to adjust two things in this case: * - the display row should be overrided from the current PROM metrics, * to prevent us from overwriting the last few lines of text. * - if the 80x34 screen would make a large margin appear around it, * choose to clear the screen rather than keeping old prom output in * the margins. * XXX there should be a rasops "clear margins" feature */ fbwscons_init(&sc->sc_sunfb, console && (sc->sc_sunfb.sf_width >= 1024) ? 0 : RI_CLEAR); fbwscons_setcolormap(&sc->sc_sunfb, cgthree_setcolor); if (console) { fbwscons_console_init(&sc->sc_sunfb, sc->sc_sunfb.sf_width >= 1024 ? -1 : 0); } fbwscons_attach(&sc->sc_sunfb, &cgthree_accessops, console); return; fail_vid: bus_space_unmap(sa->sa_bustag, sc->sc_ctrl_regs, CGTHREE_CTRL_SIZE); fail_ctrl: fail: ; }
void gfxp_attach(struct device *parent, struct device *self, void *aux) { struct gfxp_softc *sc = (struct gfxp_softc *)self; struct pci_attach_args *pa = aux; struct rasops_info *ri; int node, console, flags; char *model; sc->sc_pcitag = pa->pa_tag; node = PCITAG_NODE(pa->pa_tag); console = gfxp_is_console(node); printf("\n"); model = getpropstring(node, "model"); printf("%s: %s", self->dv_xname, model); if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, PM2_PCI_MEM_LE, PCI_MAPREG_TYPE_MEM, &sc->sc_membase_le, &sc->sc_memsize_le, NULL)) sc->sc_memsize_le = 0; if (pci_mapreg_map(pa, PM2_PCI_MEM_BE, PCI_MAPREG_TYPE_MEM, BUS_SPACE_MAP_LINEAR, &sc->sc_memt, &sc->sc_memh, &sc->sc_membase_be, &sc->sc_memsize_be, 0)) { printf("\n%s: can't map video memory\n", self->dv_xname); return; } if (pci_mapreg_map(pa, PM2_PCI_MMIO, PCI_MAPREG_TYPE_MEM, 0, &sc->sc_mmiot, &sc->sc_mmioh, &sc->sc_mmiobase, &sc->sc_mmiosize, 0)) { bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_memsize_be); printf("\n%s: can't map mmio\n", self->dv_xname); return; } fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0); printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); ri = &sc->sc_sunfb.sf_ro; ri->ri_bits = bus_space_vaddr(sc->sc_memt, sc->sc_memh); ri->ri_hw = sc; flags = RI_BSWAP; if (sc->sc_sunfb.sf_depth == 32) { ri->ri_rnum = 8; ri->ri_rpos = 16; ri->ri_gnum = 8; ri->ri_gpos = 8; ri->ri_bnum = 8; ri->ri_bpos = 0; flags &= ~RI_BSWAP; } fbwscons_init(&sc->sc_sunfb, flags, console); fbwscons_setcolormap(&sc->sc_sunfb, gfxp_setcolor); sc->sc_mode = WSDISPLAYIO_MODE_EMUL; gfxp_init(sc); ri->ri_ops.copyrows = gfxp_copyrows; ri->ri_ops.copycols = gfxp_copycols; ri->ri_ops.eraserows = gfxp_eraserows; ri->ri_ops.erasecols = gfxp_erasecols; if (console) fbwscons_console_init(&sc->sc_sunfb, -1); fbwscons_attach(&sc->sc_sunfb, &gfxp_accessops, console); }
void p9000attach(struct device *parent, struct device *self, void *args) { struct p9000_softc *sc = (struct p9000_softc *)self; struct confargs *ca = args; int node, pri, row, isconsole, scr; struct device *btdev; extern struct cfdriver btcham_cd; pri = ca->ca_ra.ra_intr[0].int_pri; printf(" pri %d", pri); #ifdef DIAGNOSTIC if (ca->ca_ra.ra_nreg < P9000_NREG) { printf(": expected %d registers, got only %d\n", P9000_NREG, ca->ca_ra.ra_nreg); return; } #endif /* * Find the RAMDAC device. It should have attached before, since it * attaches at obio. If, for some reason, it did not, it's not worth * going any further. * * We rely upon the PROM to properly initialize the RAMDAC in a safe * mode. */ btdev = btcham_cd.cd_ndevs != 0 ? btcham_cd.cd_devs[0] : NULL; if (btdev != NULL) sc->sc_ramdac = ((struct bt445_softc *)btdev)->sc_regs; if (sc->sc_ramdac == NULL) { printf(": bt445 did not attach previously\n"); return; } sc->sc_phys = ca->ca_ra.ra_reg[P9000_REG_VRAM]; sc->sc_ctl = mapiodev(&(ca->ca_ra.ra_reg[P9000_REG_CTL]), 0, ca->ca_ra.ra_reg[0].rr_len); sc->sc_cmd = mapiodev(&(ca->ca_ra.ra_reg[P9000_REG_CMD]), 0, ca->ca_ra.ra_reg[1].rr_len); node = ca->ca_ra.ra_node; isconsole = node == fbnode; fb_setsize(&sc->sc_sunfb, 8, 640, 480, node, ca->ca_bustype); sc->sc_sunfb.sf_ro.ri_bits = mapiodev(&sc->sc_phys, 0, round_page(sc->sc_sunfb.sf_fbsize)); sc->sc_sunfb.sf_ro.ri_hw = sc; P9000_SELECT_SCR(sc); scr = P9000_READ_CTL(sc, P9000_SYSTEM_CONFIG); printf(": rev %x, %dx%d\n", scr & SCR_ID_MASK, sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); /* Disable frame buffer interrupts */ P9000_SELECT_SCR(sc); P9000_WRITE_CTL(sc, P9000_INTERRUPT_ENABLE, IER_MASTER_ENABLE | 0); sc->sc_ih.ih_fun = p9000_intr; sc->sc_ih.ih_arg = sc; intr_establish(pri, &sc->sc_ih, IPL_FB, self->dv_xname); /* * If the framebuffer width is under 1024x768, we will switch from the * PROM font to the more adequate 8x16 font here. * However, we need to adjust two things in this case: * - the display row should be overrided from the current PROM metrics, * to prevent us from overwriting the last few lines of text. * - if the 80x34 screen would make a large margin appear around it, * choose to clear the screen rather than keeping old prom output in * the margins. * XXX there should be a rasops "clear margins" feature */ fbwscons_init(&sc->sc_sunfb, isconsole && (sc->sc_sunfb.sf_width >= 1024) ? 0 : RI_CLEAR); fbwscons_setcolormap(&sc->sc_sunfb, p9000_setcolor); /* * Plug-in accelerated console operations. */ if (sc->sc_sunfb.sf_dev.dv_cfdata->cf_flags != 0) p9000_ras_init(sc); /* enable video */ p9000_burner(sc, 1, 0); if (isconsole) { if (sc->sc_sunfb.sf_width < 1024) row = 0; /* screen has been cleared above */ else row = -1; fbwscons_console_init(&sc->sc_sunfb, row); } fbwscons_attach(&sc->sc_sunfb, &p9000_accessops, isconsole); }
void bwtwoattach(struct device *parent, struct device *self, void *args) { struct bwtwo_softc *sc = (struct bwtwo_softc *)self; struct confargs *ca = args; int node = ca->ca_ra.ra_node; int isconsole = 0; int sbus = 1; char *nam; printf(": "); /* * Map the control register. */ #if defined(SUN4) if (CPU_ISSUN4 && ca->ca_bustype == BUS_OBIO && fb_pfour_id(ca->ca_ra.ra_vaddr) != PFOUR_NOTPFOUR) { SET(sc->sc_sunfb.sf_flags, FB_PFOUR); sc->sc_sunfb.sf_pfour = (volatile u_int32_t *) mapiodev(ca->ca_ra.ra_reg, 0, sizeof(u_int32_t)); } else #endif { sc->sc_reg = (volatile struct fbcontrol *) mapiodev(ca->ca_ra.ra_reg, BWREG_REG, sizeof(struct fbcontrol)); } /* Set up default pixel offset. May be changed below. */ sc->sc_pixeloffset = BWREG_MEM; switch (ca->ca_bustype) { case BUS_OBIO: if (CPU_ISSUN4M) /* 4m has framebuffer on obio */ goto obp_name; sbus = node = 0; #if defined(SUN4) if (ISSET(sc->sc_sunfb.sf_flags, FB_PFOUR)) { nam = "p4"; sc->sc_pixeloffset = PFOUR_BW_OFF; } else #endif nam = NULL; break; case BUS_VME32: case BUS_VME16: sbus = node = 0; nam = NULL; break; case BUS_SBUS: obp_name: #if defined(SUN4C) || defined(SUN4M) nam = getpropstring(node, "model"); #endif break; } if (nam != NULL && *nam != '\0') printf("%s, ", nam); #if defined(SUN4) if (CPU_ISSUN4) { struct eeprom *eep = (struct eeprom *)eeprom_va; int constype = ISSET(sc->sc_sunfb.sf_flags, FB_PFOUR) ? EE_CONS_P4OPT : EE_CONS_BW; /* * Assume this is the console if there's no eeprom info * to be found. */ if (eep == NULL || eep->eeConsole == constype) isconsole = 1; else /* * On sun4 systems without on-board framebuffers (such as * the 4/3xx models), the PROM will accept the EE_CONS_BW * setting although the framebuffer is a P4. * Accept this setting as well. */ if (eep->eeConsole == EE_CONS_BW) isconsole = 1; } #endif if (CPU_ISSUN4COR4M) isconsole = node == fbnode; sc->sc_phys = ca->ca_ra.ra_reg[0]; sc->sc_bustype = ca->ca_bustype; /* enable video */ bwtwo_burner(sc, 1, 0); fb_setsize(&sc->sc_sunfb, 1, 1152, 900, node, ca->ca_bustype); printf("%dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); sc->sc_sunfb.sf_ro.ri_bits = mapiodev(ca->ca_ra.ra_reg, sc->sc_pixeloffset, round_page(sc->sc_sunfb.sf_fbsize)); sc->sc_sunfb.sf_ro.ri_hw = sc; fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR); if (isconsole) { fbwscons_console_init(&sc->sc_sunfb, -1); } fbwscons_attach(&sc->sc_sunfb, &bwtwo_accessops, isconsole); }
void cgsixattach(struct device *parent, struct device *self, void *aux) { struct cgsix_softc *sc = (struct cgsix_softc *)self; struct sbus_attach_args *sa = aux; int node, console; u_int32_t fhc, rev; const char *nam; node = sa->sa_node; sc->sc_bustag = sa->sa_bustag; sc->sc_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_slot, sa->sa_offset); if (sa->sa_nreg != 1) { printf(": expected %d registers, got %d\n", 1, sa->sa_nreg); goto fail; } fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0); /* * Map just BT, FHC, FBC, THC, and video RAM. */ if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot, sa->sa_reg[0].sbr_offset + CGSIX_BT_OFFSET, CGSIX_BT_SIZE, 0, 0, &sc->sc_bt_regs) != 0) { printf(": cannot map bt registers\n"); goto fail_bt; } if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot, sa->sa_reg[0].sbr_offset + CGSIX_FHC_OFFSET, CGSIX_FHC_SIZE, 0, 0, &sc->sc_fhc_regs) != 0) { printf(": cannot map fhc registers\n"); goto fail_fhc; } if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot, sa->sa_reg[0].sbr_offset + CGSIX_THC_OFFSET, CGSIX_THC_SIZE, 0, 0, &sc->sc_thc_regs) != 0) { printf(": cannot map thc registers\n"); goto fail_thc; } if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot, sa->sa_reg[0].sbr_offset + CGSIX_VID_OFFSET, sc->sc_sunfb.sf_fbsize, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_vid_regs) != 0) { printf(": cannot map vid registers\n"); goto fail_vid; } if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot, sa->sa_reg[0].sbr_offset + CGSIX_TEC_OFFSET, CGSIX_TEC_SIZE, 0, 0, &sc->sc_tec_regs) != 0) { printf(": cannot map tec registers\n"); goto fail_tec; } if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot, sa->sa_reg[0].sbr_offset + CGSIX_FBC_OFFSET, CGSIX_FBC_SIZE, 0, 0, &sc->sc_fbc_regs) != 0) { printf(": cannot map fbc registers\n"); goto fail_fbc; } if ((sc->sc_ih = bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_TTY, 0, cgsix_intr, sc, self->dv_xname)) == NULL) { printf(": couldn't establish interrupt, pri %d\n%s", INTLEV(sa->sa_pri), self->dv_xname); } /* if prom didn't initialize us, do it the hard way */ if (OF_getproplen(node, "width") != sizeof(u_int32_t)) cgsix_hardreset(sc); nam = getpropstring(node, "model"); if (*nam == '\0') nam = sa->sa_name; printf(": %s", nam); console = cgsix_is_console(node); fhc = FHC_READ(sc); rev = (fhc & FHC_REV_MASK) >> FHC_REV_SHIFT; cgsix_reset(sc, rev); cgsix_burner(sc, 1, 0); sc->sc_sunfb.sf_ro.ri_bits = (void *)bus_space_vaddr(sc->sc_bustag, sc->sc_vid_regs); sc->sc_sunfb.sf_ro.ri_hw = sc; printf(", %dx%d, rev %d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height, rev); fbwscons_init(&sc->sc_sunfb, 0, console); fbwscons_setcolormap(&sc->sc_sunfb, cgsix_setcolor); /* * Old rev. cg6 cards do not like the current acceleration code. * * Some hints from Sun point out at timing and cache problems, which * will be investigated later. */ if (rev < 5) sc->sc_sunfb.sf_dev.dv_cfdata->cf_flags |= CG6_CFFLAG_NOACCEL; if ((sc->sc_sunfb.sf_dev.dv_cfdata->cf_flags & CG6_CFFLAG_NOACCEL) == 0) { sc->sc_sunfb.sf_ro.ri_ops.copyrows = cgsix_ras_copyrows; sc->sc_sunfb.sf_ro.ri_ops.copycols = cgsix_ras_copycols; sc->sc_sunfb.sf_ro.ri_ops.eraserows = cgsix_ras_eraserows; sc->sc_sunfb.sf_ro.ri_ops.erasecols = cgsix_ras_erasecols; sc->sc_sunfb.sf_ro.ri_do_cursor = cgsix_ras_do_cursor; cgsix_ras_init(sc); } if (console) fbwscons_console_init(&sc->sc_sunfb, -1); fbwscons_attach(&sc->sc_sunfb, &cgsix_accessops, console); return; fail_fbc: bus_space_unmap(sa->sa_bustag, sc->sc_tec_regs, CGSIX_TEC_SIZE); fail_tec: bus_space_unmap(sa->sa_bustag, sc->sc_vid_regs, sc->sc_sunfb.sf_fbsize); fail_vid: bus_space_unmap(sa->sa_bustag, sc->sc_thc_regs, CGSIX_THC_SIZE); fail_thc: bus_space_unmap(sa->sa_bustag, sc->sc_fhc_regs, CGSIX_FHC_SIZE); fail_fhc: bus_space_unmap(sa->sa_bustag, sc->sc_bt_regs, CGSIX_BT_SIZE); fail_bt: fail: return; }
/* * Attach a display. */ void p9100attach(struct device *parent, struct device *self, void *args) { struct p9100_softc *sc = (struct p9100_softc *)self; struct rasops_info *ri = &sc->sc_sunfb.sf_ro; struct confargs *ca = args; struct romaux *ra = &ca->ca_ra; int node, pri, scr, force_reset; int isconsole, fontswitch, clear = 0; pri = ca->ca_ra.ra_intr[0].int_pri; printf(" pri %d", pri); #ifdef DIAGNOSTIC if (ra->ra_nreg < P9100_NREG) { printf(": expected %d registers, got only %d\n", P9100_NREG, ra->ra_nreg); return; } #endif sc->sc_flags = SCF_INTERNAL; sc->sc_mapmode = WSDISPLAYIO_MODE_EMUL; bcopy(ra->ra_reg, sc->sc_phys, sizeof(sc->sc_phys)); sc->sc_ctl = mapiodev(&ra->ra_reg[P9100_REG_CTL], 0, ra->ra_reg[P9100_REG_CTL].rr_len); sc->sc_cmd = mapiodev(&ra->ra_reg[P9100_REG_CMD], 0, ra->ra_reg[P9100_REG_CMD].rr_len); #ifdef FIDDLE_WITH_PCI_REGISTERS sc->sc_pci = (struct p9100_pci *) mapiodev(&ra->ra_reg[P9100_REG_CONFIG], 0, ra->ra_reg[P9100_REG_CONFIG].rr_len); #endif node = ra->ra_node; isconsole = node == fbnode; P9100_SELECT_SCR(sc); scr = P9100_READ_CTL(sc, P9000_SYSTEM_CONFIG); switch (scr & SCR_PIXEL_MASK) { default: #ifdef DIAGNOSTIC printf(": unknown color depth code 0x%x", scr & SCR_PIXEL_MASK); #endif /* FALLTHROUGH */ case SCR_PIXEL_32BPP: case SCR_PIXEL_24BPP: case SCR_PIXEL_16BPP: force_reset = 1; break; case SCR_PIXEL_8BPP: force_reset = 0; break; } fb_setsize(&sc->sc_sunfb, 8, LCD_WIDTH, LCD_HEIGHT, node, ca->ca_bustype); #if 0 /* * The PROM will initialize us in 800x600x8 mode anyway. If it * does not, we'll force this mode right now. */ if (sc->sc_sunfb.sf_width != LCD_WIDTH || sc->sc_sunfb.sf_depth != 8 || sc->sc_sunfb.sf_height != LCD_HEIGHT || force_reset != 0) { sc->sc_sunfb.sf_width = LCD_WIDTH; sc->sc_sunfb.sf_height = LCD_HEIGHT; sc->sc_sunfb.sf_depth = 8; sc->sc_sunfb.sf_linebytes = LCD_WIDTH; printf("\n"); p9100_initialize_ramdac(sc, LCD_WIDTH, 8); printf("%s", self->dv_xname); clear = 1; } #endif #if NTCTRL > 0 /* * We want to run the frame buffer in 8bpp mode for the emulation mode, * and use a potentially better mode for the mapped (X11) mode. * Eventually this will become runtime user-selectable. */ sc->sc_mapwidth = LCD_WIDTH; sc->sc_mapheight = LCD_HEIGHT; sc->sc_mapdepth = 8; if (sc->sc_mapwidth != sc->sc_sunfb.sf_width || sc->sc_mapdepth != sc->sc_sunfb.sf_depth) SET(sc->sc_flags, SCF_MAPPEDSWITCH); #endif ri->ri_bits = mapiodev(&ra->ra_reg[P9100_REG_VRAM], 0, sc->sc_vramsize = round_page(ra->ra_reg[P9100_REG_VRAM].rr_len)); ri->ri_hw = sc; printf(": rev %x, %dx%d\n", scr & SCR_ID_MASK, LCD_WIDTH, LCD_HEIGHT); /* Disable frame buffer interrupts */ P9100_SELECT_SCR(sc); P9100_WRITE_CTL(sc, P9000_INTERRUPT_ENABLE, IER_MASTER_ENABLE | 0); sc->sc_ih.ih_fun = p9100_intr; sc->sc_ih.ih_arg = sc; intr_establish(pri, &sc->sc_ih, IPL_FB, self->dv_xname); /* * Try to get a copy of the PROM font. * * If we can, we still need to adjust the visible portion of the * display, as the PROM output is offset two chars to the left. * * If we can't, we'll switch to the 8x16 font, and we'll need to adjust * two things: * - the display row should be overrided from the current PROM metrics, * to prevent us from overwriting the last few lines of text. * - if the 80x34 screen would make a large margin appear around it, * choose to clear the screen rather than keeping old prom output in * the margins. * XXX there should be a rasops "clear margins" feature */ fontswitch = p9100_pick_romfont(sc); /* * Register the external video control callback with tctrl; tctrl * will invoke it immediately to set the appropriate behaviour. * If tctrl is not configured, simply enable external video. */ #if NTCTRL > 0 tadpole_register_extvideo(p9100_external_video, sc); #else p9100_external_video(sc, 1); #endif if (isconsole == 0 || fontswitch) clear = 1; fbwscons_init(&sc->sc_sunfb, clear ? RI_CLEAR : 0); if (clear == 0) { ri->ri_bits -= 2 * ri->ri_xscale; ri->ri_xorigin -= 2 * ri->ri_xscale; } fbwscons_setcolormap(&sc->sc_sunfb, p9100_setcolor); /* * Plug-in accelerated console operations. */ if (sc->sc_sunfb.sf_dev.dv_cfdata->cf_flags != 0) p9100_ras_init(sc); /* enable video */ p9100_burner(sc, 1, 0); if (isconsole) { fbwscons_console_init(&sc->sc_sunfb, clear ? 0 : -1); #if NTCTRL > 0 shutdownhook_establish(p9100_prom, sc); #endif } fbwscons_attach(&sc->sc_sunfb, &p9100_accessops, isconsole); }
void cgthreeattach(struct device *parent, struct device *self, void *args) { struct cgthree_softc *sc = (struct cgthree_softc *)self; struct confargs *ca = args; int node, pri, isrdi = 0, i; volatile struct bt_regs *bt; int isconsole; char *nam; pri = ca->ca_ra.ra_intr[0].int_pri; printf(" pri %d: ", pri); node = ca->ca_ra.ra_node; if (strcmp(ca->ca_ra.ra_name, "cgRDI") == 0) { isrdi = 1; nam = "cgRDI"; } else nam = getpropstring(node, "model"); if (nam != NULL && *nam != '\0') printf("%s, ", nam); isconsole = node == fbnode; sc->sc_fbc = (volatile struct fbcontrol *) mapiodev(ca->ca_ra.ra_reg, CG3REG_REG, sizeof(struct fbcontrol)); /* Transfer video magic to board, if it's not running */ if (isrdi == 0 && (sc->sc_fbc->fbc_ctrl & FBC_TIMING) == 0) for (i = 0; i < sizeof(cg3_videoctrl)/sizeof(cg3_videoctrl[0]); i++) { volatile struct fbcontrol *fbc = sc->sc_fbc; if (cg3_videoctrl[i].sense == 0xff || (fbc->fbc_status & FBS_MSENSE) == cg3_videoctrl[i].sense) { int j; #ifdef DEBUG printf(" (setting video ctrl)"); #endif for (j = 0; j < 12; j++) fbc->fbc_vcontrol[j] = cg3_videoctrl[i].vctrl[j]; fbc->fbc_ctrl |= FBC_TIMING; break; } } sc->sc_phys = ca->ca_ra.ra_reg[0]; sc->sc_ih.ih_fun = cgthree_intr; sc->sc_ih.ih_arg = sc; intr_establish(pri, &sc->sc_ih, IPL_FB, self->dv_xname); /* enable video */ cgthree_burner(sc, 1, 0); bt = &sc->sc_fbc->fbc_dac; BT_INIT(bt, 0); fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype); sc->sc_sunfb.sf_ro.ri_bits = mapiodev(ca->ca_ra.ra_reg, CG3REG_MEM, round_page(sc->sc_sunfb.sf_fbsize)); sc->sc_sunfb.sf_ro.ri_hw = sc; printf("%dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); /* * If the framebuffer width is under 1024x768, which is the case for * some clones on laptops, as well as with the VS10-EK, switch from * the PROM font to the more adequate 8x16 font here. * However, we need to adjust two things in this case: * - the display row should be overrided from the current PROM metrics, * to prevent us from overwriting the last few lines of text. * - if the 80x34 screen would make a large margin appear around it, * choose to clear the screen rather than keeping old prom output in * the margins. * XXX there should be a rasops "clear margins" feature */ fbwscons_init(&sc->sc_sunfb, isconsole && (sc->sc_sunfb.sf_width >= 1024) ? 0 : RI_CLEAR); fbwscons_setcolormap(&sc->sc_sunfb, cgthree_setcolor); if (isconsole) { fbwscons_console_init(&sc->sc_sunfb, sc->sc_sunfb.sf_width >= 1024 ? -1 : 0); } fbwscons_attach(&sc->sc_sunfb, &cgthree_accessops, isconsole); }
/** * radeon_driver_load_kms - Main load function for KMS. * * @dev: drm dev pointer * @flags: device flags * * This is the main load function for KMS (all asics). * It calls radeon_device_init() to set up the non-display * parts of the chip (asic init, CP, writeback, etc.), and * radeon_modeset_init() to set up the display parts * (crtcs, encoders, hotplug detect, etc.). * Returns 0 on success, error on failure. */ void radeondrm_attach_kms(struct device *parent, struct device *self, void *aux) { struct radeon_device *rdev = (struct radeon_device *)self; struct drm_device *dev; struct pci_attach_args *pa = aux; const struct drm_pcidev *id_entry; int is_agp; pcireg_t type; uint8_t iobar; #if !defined(__sparc64__) pcireg_t addr, mask; int s; #endif #if defined(__sparc64__) || defined(__macppc__) extern int fbnode; #endif id_entry = drm_find_description(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id), radeondrm_pciidlist); rdev->flags = id_entry->driver_data; rdev->pc = pa->pa_pc; rdev->pa_tag = pa->pa_tag; rdev->iot = pa->pa_iot; rdev->memt = pa->pa_memt; rdev->dmat = pa->pa_dmat; #if defined(__sparc64__) || defined(__macppc__) if (fbnode == PCITAG_NODE(rdev->pa_tag)) rdev->console = 1; #else if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY && PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA && (pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) & (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) == (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) { rdev->console = 1; #if NVGA > 0 vga_console_attached = 1; #endif } #if NEFIFB > 0 if (efifb_is_console(pa)) { rdev->console = 1; efifb_cndetach(); } #endif #endif #define RADEON_PCI_MEM 0x10 #define RADEON_PCI_IO 0x14 #define RADEON_PCI_MMIO 0x18 #define RADEON_PCI_IO2 0x20 type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM); if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM || pci_mapreg_info(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM, type, &rdev->fb_aper_offset, &rdev->fb_aper_size, NULL)) { printf(": can't get frambuffer info\n"); return; } if (PCI_MAPREG_MEM_TYPE(type) != PCI_MAPREG_MEM_TYPE_64BIT) iobar = RADEON_PCI_IO; else iobar = RADEON_PCI_IO2; if (pci_mapreg_map(pa, iobar, PCI_MAPREG_TYPE_IO, 0, NULL, &rdev->rio_mem, NULL, &rdev->rio_mem_size, 0)) { printf(": can't map IO space\n"); return; } type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MMIO); if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM || pci_mapreg_map(pa, RADEON_PCI_MMIO, type, 0, NULL, &rdev->rmmio, &rdev->rmmio_base, &rdev->rmmio_size, 0)) { printf(": can't map mmio space\n"); return; } #if !defined(__sparc64__) /* * Make sure we have a base address for the ROM such that we * can map it later. */ s = splhigh(); addr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG); pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, ~PCI_ROM_ENABLE); mask = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG); pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, addr); splx(s); if (addr == 0 && PCI_ROM_SIZE(mask) != 0 && pa->pa_memex) { bus_size_t size, start, end; bus_addr_t base; size = PCI_ROM_SIZE(mask); start = max(PCI_MEM_START, pa->pa_memex->ex_start); end = min(PCI_MEM_END, pa->pa_memex->ex_end); if (extent_alloc_subregion(pa->pa_memex, start, end, size, size, 0, 0, 0, &base) == 0) pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, base); } #endif #ifdef notyet mtx_init(&rdev->swi_lock, IPL_TTY); #endif /* update BUS flag */ if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL)) { rdev->flags |= RADEON_IS_AGP; } else if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIEXPRESS, NULL, NULL)) { rdev->flags |= RADEON_IS_PCIE; } else { rdev->flags |= RADEON_IS_PCI; } DRM_DEBUG("%s card detected\n", ((rdev->flags & RADEON_IS_AGP) ? "AGP" : (((rdev->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); is_agp = pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL); printf("\n"); kms_driver.num_ioctls = radeon_max_kms_ioctl; dev = (struct drm_device *)drm_attach_pci(&kms_driver, pa, is_agp, rdev->console, self); rdev->ddev = dev; rdev->pdev = dev->pdev; rdev->family = rdev->flags & RADEON_FAMILY_MASK; if (!radeon_msi_ok(rdev)) pa->pa_flags &= ~PCI_FLAGS_MSI_ENABLED; rdev->msi_enabled = 0; if (pci_intr_map_msi(pa, &rdev->intrh) == 0) rdev->msi_enabled = 1; else if (pci_intr_map(pa, &rdev->intrh) != 0) { printf(": couldn't map interrupt\n"); return; } printf("%s: %s\n", rdev->dev.dv_xname, pci_intr_string(pa->pa_pc, rdev->intrh)); rdev->irqh = pci_intr_establish(pa->pa_pc, rdev->intrh, IPL_TTY, radeon_driver_irq_handler_kms, rdev->ddev, rdev->dev.dv_xname); if (rdev->irqh == NULL) { printf("%s: couldn't establish interrupt\n", rdev->dev.dv_xname); return; } #ifdef __sparc64__ { struct rasops_info *ri; int node, console; node = PCITAG_NODE(pa->pa_tag); console = (fbnode == node); fb_setsize(&rdev->sf, 8, 1152, 900, node, 0); /* * The firmware sets up the framebuffer such that at starts at * an offset from the start of video memory. */ rdev->fb_offset = bus_space_read_4(rdev->memt, rdev->rmmio, RADEON_CRTC_OFFSET); if (bus_space_map(rdev->memt, rdev->fb_aper_offset + rdev->fb_offset, rdev->sf.sf_fbsize, BUS_SPACE_MAP_LINEAR, &rdev->memh)) { printf("%s: can't map video memory\n", rdev->dev.dv_xname); return; } ri = &rdev->sf.sf_ro; ri->ri_bits = bus_space_vaddr(rdev->memt, rdev->memh); ri->ri_hw = rdev; ri->ri_updatecursor = NULL; fbwscons_init(&rdev->sf, RI_VCONS | RI_WRONLY | RI_BSWAP, console); if (console) fbwscons_console_init(&rdev->sf, -1); } #endif rdev->shutdown = true; config_mountroot(self, radeondrm_attachhook); }
/* * Attach and initialize a cgtwelve. */ void cgtwelveattach(struct device *parent, struct device *self, void *args) { struct cgtwelve_softc *sc = (struct cgtwelve_softc *)self; struct sbus_attach_args *sa = args; bus_space_tag_t bt; bus_space_handle_t bh; int node, isconsole = 0; char *ps; bt = sa->sa_bustag; node = sa->sa_node; printf(": %s", getpropstring(node, "model")); ps = getpropstring(node, "dev_id"); if (*ps != '\0') printf(" (%s)", ps); printf("\n"); isconsole = node == fbnode; if (sa->sa_nreg == 0) { printf("%s: no SBus registers!\n", self->dv_xname); return; } sc->sc_bustag = bt; /* * Map registers */ if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + CG12_OFF_DPU, sizeof(struct cgtwelve_dpu), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("%s: can't map DPU registers\n", self->dv_xname); return; } sc->sc_dpu = bus_space_vaddr(bt, bh); if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + CG12_OFF_APU, sizeof(struct cgtwelve_apu), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("%s: can't map APU registers\n", self->dv_xname); return; } sc->sc_apu = bus_space_vaddr(bt, bh); if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + CG12_OFF_DAC, sizeof(struct cgtwelve_dac), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("%s: can't map RAMDAC registers\n", self->dv_xname); return; } sc->sc_ramdac = bus_space_vaddr(bt, bh); /* * The console is using the 1-bit overlay plane, while the prom * will correctly report 32 bit depth. */ fb_setsize(&sc->sc_sunfb, 1, CG12_WIDTH, CG12_HEIGHT, node, 0); sc->sc_sunfb.sf_depth = 1; sc->sc_sunfb.sf_linebytes = sc->sc_sunfb.sf_width / 8; sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_height * sc->sc_sunfb.sf_linebytes; sc->sc_highres = sc->sc_sunfb.sf_width == CG12_WIDTH_HR; /* * Map planes */ if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + (sc->sc_highres ? CG12_OFF_OVERLAY0_HR : CG12_OFF_OVERLAY0), round_page(sc->sc_highres ? CG12_SIZE_OVERLAY_HR : CG12_SIZE_OVERLAY), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("%s: can't map overlay plane\n", self->dv_xname); return; } sc->sc_overlay = bus_space_vaddr(bt, bh); if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + (sc->sc_highres ? CG12_OFF_INTEN_HR : CG12_OFF_INTEN), round_page(sc->sc_highres ? CG12_SIZE_COLOR24_HR : CG12_SIZE_COLOR24), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("%s: can't map color plane\n", self->dv_xname); return; } sc->sc_inten = bus_space_vaddr(bt, bh); sc->sc_paddr = sbus_bus_addr(bt, sa->sa_slot, sa->sa_offset + (sc->sc_highres ? CG12_OFF_INTEN_HR : CG12_OFF_INTEN)); /* reset cursor & frame buffer controls */ sc->sc_sunfb.sf_depth = 0; /* force action */ cgtwelve_reset(sc, 1); sc->sc_sunfb.sf_ro.ri_bits = (void *)sc->sc_overlay; sc->sc_sunfb.sf_ro.ri_hw = sc; fbwscons_init(&sc->sc_sunfb, 0, isconsole); if (isconsole) { fbwscons_console_init(&sc->sc_sunfb, -1); shutdownhook_establish(cgtwelve_prom, sc); } printf("%s: %dx%d", self->dv_xname, sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); ps = getpropstring(node, "ucoderev"); if (*ps != '\0') printf(", microcode rev. %s", ps); printf("\n"); fbwscons_attach(&sc->sc_sunfb, &cgtwelve_accessops, isconsole); }
/* * Attach and initialize a vigra display, as well as a child wsdisplay. */ void vigraattach(struct device *parent, struct device *self, void *args) { struct vigra_softc *sc = (struct vigra_softc *)self; struct sbus_attach_args *sa = args; bus_space_tag_t bt; bus_space_handle_t bh; int node, row, isconsole = 0; char *nam; bt = sa->sa_bustag; node = sa->sa_node; nam = getpropstring(node, "model"); if (*nam == '\0') nam = (char *)sa->sa_name; printf(": %s", nam); isconsole = node == fbnode; if (sa->sa_nreg < VIGRA_NREG) { printf("\n%s: expected %d registers, got %d", self->dv_xname, VIGRA_NREG, sa->sa_nreg); return; } /* * Check whether we are using an G300 or an G335 chip. * The VS10 and VS12 use the G300, while the VS11 uses a G335. */ sc->sc_g300 = strncmp(nam, "VIGRA,vs11", strlen("VIGRA,vs11")); sc->sc_bustag = bt; if (sbus_bus_map(bt, sa->sa_reg[VIGRA_REG_CSR].sbr_slot, sa->sa_reg[VIGRA_REG_CSR].sbr_offset, sa->sa_reg[VIGRA_REG_CSR].sbr_size, BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("\n%s: can't map control registers\n", self->dv_xname); return; } sc->sc_regs = bus_space_vaddr(bt, bh); if (sbus_bus_map(bt, sa->sa_reg[VIGRA_REG_RAMDAC].sbr_slot, sa->sa_reg[VIGRA_REG_RAMDAC].sbr_offset, sa->sa_reg[VIGRA_REG_RAMDAC].sbr_size, BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("\n%s: can't map ramdac registers\n", self->dv_xname); return; } sc->sc_ramdac = bus_space_vaddr(bt, bh); /* enable video */ vigra_burner(sc, 1, 0); fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0); if (sbus_bus_map(bt, sa->sa_reg[VIGRA_REG_VRAM].sbr_slot, sa->sa_reg[VIGRA_REG_VRAM].sbr_offset, round_page(sc->sc_sunfb.sf_fbsize), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("\n%s: can't map video memory\n", self->dv_xname); return; } sc->sc_sunfb.sf_ro.ri_bits = bus_space_vaddr(bt, bh); sc->sc_sunfb.sf_ro.ri_hw = sc; sc->sc_paddr = sbus_bus_addr(bt, sa->sa_reg[VIGRA_REG_VRAM].sbr_slot, sa->sa_reg[VIGRA_REG_VRAM].sbr_offset); printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); if ((sc->sc_ih = bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_TTY, 0, vigra_intr, sc, self->dv_xname)) == NULL) { printf("%s: couldn't establish interrupt, pri %d\n", self->dv_xname, INTLEV(sa->sa_pri)); } /* * If the framebuffer width is under 1024x768, we will switch from the * PROM font to the more adequate 8x16 font here. * However, we need to adjust two things in this case: * - the display row should be overrided from the current PROM metrics, * to prevent us from overwriting the last few lines of text. * - if the 80x34 screen would make a large margin appear around it, * choose to clear the screen rather than keeping old prom output in * the margins. * XXX there should be a rasops "clear margins" feature * * Also, in 1280x1024 resolution, the PROM display is not centered * vertically (why? no other frame buffer does this in such a mode!), * so be lazy and clear the screen here too anyways... */ fbwscons_init(&sc->sc_sunfb, isconsole && (sc->sc_sunfb.sf_width != 800 && sc->sc_sunfb.sf_width != 1280) ? 0 : RI_CLEAR); fbwscons_setcolormap(&sc->sc_sunfb, vigra_setcolor); if (isconsole) { switch (sc->sc_sunfb.sf_width) { case 640: row = sc->sc_sunfb.sf_ro.ri_rows - 1; break; case 800: case 1280: row = 0; /* screen has been cleared above */ break; default: row = -1; break; } fbwscons_console_init(&sc->sc_sunfb, row); } fbwscons_attach(&sc->sc_sunfb, &vigra_accessops, isconsole); }