static int gdc_attach(device_t dev) { gdc_softc_t *sc; int error; error = gdc_alloc_resource(dev); if (error) return (error); sc = device_get_softc(dev); error = gdc_attach_unit(device_get_unit(dev), sc, device_get_flags(dev)); if (error) { gdc_release_resource(dev); return error; } #ifdef FB_INSTALL_CDEV /* attach a virtual frame buffer device */ error = fb_attach(makedev(0, GDC_MKMINOR(unit)), sc->adp, &gdc_cdevsw); if (error) { gdc_release_resource(dev); return error; } #endif /* FB_INSTALL_CDEV */ if (bootverbose) (*vidsw[sc->adp->va_index]->diag)(sc->adp, bootverbose); return 0; }
static int isavga_attach(device_t dev) { vga_softc_t *sc; int unit; int rid; int error; unit = device_get_unit(dev); sc = device_get_softc(dev); rid = 0; bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 0, RF_ACTIVE | RF_SHAREABLE); rid = 0; bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 0, RF_ACTIVE | RF_SHAREABLE); error = vga_attach_unit(unit, sc, device_get_flags(dev)); if (error) return error; #ifdef FB_INSTALL_CDEV /* attach a virtual frame buffer device */ sc->devt = make_dev(&isavga_ops, VGA_MKMINOR(unit), 0, 0, 02660, "vga%x", VGA_MKMINOR(unit)); reference_dev(sc->devt); error = fb_attach(sc->devt, sc->adp); if (error) return error; #endif /* FB_INSTALL_CDEV */ if (bootverbose) (*vidsw[sc->adp->va_index]->diag)(sc->adp, bootverbose); #if 0 /* experimental */ device_add_child(dev, "fb", -1); bus_generic_attach(dev); #endif return 0; }
static int isavga_attach(device_t dev) { vga_softc_t *sc; int unit; int rid; int error; unit = device_get_unit(dev); sc = device_get_softc(dev); rid = 0; bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 0, RF_ACTIVE | RF_SHAREABLE); rid = 0; bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 0, RF_ACTIVE | RF_SHAREABLE); error = vga_attach_unit(unit, sc, device_get_flags(dev)); if (error) return (error); #ifdef FB_INSTALL_CDEV /* attach a virtual frame buffer device */ error = fb_attach(VGA_MKMINOR(unit), sc->adp, &isavga_cdevsw); if (error) return (error); #endif /* FB_INSTALL_CDEV */ if (0 && bootverbose) vidd_diag(sc->adp, bootverbose); #if 0 /* experimental */ device_add_child(dev, "fb", -1); bus_generic_attach(dev); #endif return (0); }
/* * Attach a display. We need to notice if it is the console, too. */ static void bw2attach(device_t parent, device_t self, void *args) { struct bw2_softc *sc = device_private(self); struct fbdevice *fb = &sc->sc_fb; struct confargs *ca = args; struct fbtype *fbt; void *p4reg; int p4id, tmp; int pixeloffset; /* offset to framebuffer */ sc->sc_dev = self; fbt = &fb->fb_fbtype; fbt->fb_type = FBTYPE_SUN2BW; fbt->fb_width = 1152; /* default - see below */ fbt->fb_height = 900; /* default - see below */ fbt->fb_depth = 1; fbt->fb_cmsize = 0; fbt->fb_size = BW2_FBSIZE; /* default - see below */ fb->fb_driver = &bw2fbdriver; fb->fb_private = sc; fb->fb_name = device_xname(self); fb->fb_flags = device_cfdata(self)->cf_flags; /* Set up default pixel offset. May be changed below. */ pixeloffset = 0; /* Does it have a P4 register? */ p4reg = bus_mapin(ca->ca_bustype, ca->ca_paddr, 4); p4id = fb_pfour_id(p4reg); if (p4id != P4_NOTFOUND) fb->fb_pfour = p4reg; else bus_mapout(p4reg, 4); switch (p4id) { case P4_NOTFOUND: pixeloffset = 0; break; case P4_ID_BW: pixeloffset = P4_BW_OFF; break; default: aprint_error("%s: bad p4id=0x%x\n", fb->fb_name, p4id); /* Must be some kinda color... */ /* FALLTHROUGH */ case P4_ID_COLOR8P1: case P4_ID_COLOR24: sc->sc_ovtype = p4id; pixeloffset = P4_COLOR_OFF_OVERLAY; break; } sc->sc_phys = ca->ca_paddr + pixeloffset; /* * Determine width and height as follows: * If it has a P4 register, use that; * else if unit==0, use the EEPROM size, * else make our best guess. */ if (fb->fb_pfour) fb_pfour_setsize(fb); /* XXX device_unit() abuse */ else if (device_unit(self) == 0) fb_eeprom_setsize(fb); else { /* Guess based on machine ID. */ switch (cpu_machine_id) { #ifdef _SUN3_ case ID_SUN3_60: /* * Only the model 60 can have hi-res. * Look at the "resolution" jumper. */ tmp = bus_peek(BUS_OBMEM, BW2_CR_PADDR, 1); if ((tmp != -1) && (tmp & 0x80) == 0) goto high_res; break; case ID_SUN3_260: /* The Sun3/260 is ALWAYS high-resolution! */ /* fall through */ high_res: fbt->fb_width = 1600; fbt->fb_height = 1280; fbt->fb_size = BW2_FBSIZE_HIRES; break; #endif /* SUN3 */ default: /* Leave the defaults set above. */ break; } } aprint_normal(" (%dx%d)\n", fbt->fb_width, fbt->fb_height); /* Make sure video is on. */ tmp = 1; bw2svideo(fb, &tmp); /* Let /dev/fb know we are here. */ fb_attach(fb, 1); }
/* * Attach a display. We need to notice if it is the console, too. */ static void cgeightattach(struct device *parent, struct device *self, void *aux) { #if defined(SUN4) union obio_attach_args *uoba = aux; struct obio4_attach_args *oba = &uoba->uoba_oba4; struct cgeight_softc *sc = device_private(self); struct fbdevice *fb = &sc->sc_fb; bus_space_handle_t bh; volatile struct bt_regs *bt; int ramsize, i, isconsole; sc->sc_bustag = oba->oba_bustag; sc->sc_paddr = (bus_addr_t)oba->oba_paddr; /* Map the pfour register. */ if (bus_space_map(oba->oba_bustag, oba->oba_paddr, sizeof(uint32_t), BUS_SPACE_MAP_LINEAR, &bh) != 0) { printf("%s: cannot map pfour register\n", self->dv_xname); return; } fb->fb_pfour = (volatile uint32_t *)bh; fb->fb_driver = &cgeightfbdriver; fb->fb_device = &sc->sc_dev; fb->fb_type.fb_type = FBTYPE_MEMCOLOR; fb->fb_flags = device_cfdata(&sc->sc_dev)->cf_flags & FB_USERMASK; fb->fb_flags |= FB_PFOUR; ramsize = PFOUR_COLOR_OFF_END - PFOUR_COLOR_OFF_OVERLAY; fb->fb_type.fb_depth = 24; fb_setsize_eeprom(fb, fb->fb_type.fb_depth, 1152, 900); sc->sc_fb.fb_type.fb_cmsize = 256; sc->sc_fb.fb_type.fb_size = ramsize; printf(": cgeight/p4, %d x %d", fb->fb_type.fb_width, fb->fb_type.fb_height); 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_P4OPT) isconsole = fb_is_console(0); } #if 0 /* * We don't do any of the console handling here. Instead, * we let the bwtwo driver pick up the overlay plane and * use it instead. Rconsole should have better performance * with the 1-bit depth. * -- Jason R. Thorpe <*****@*****.**> */ /* * 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. */ if (isconsole) { /* XXX this is kind of a waste */ fb->fb_pixels = mapiodev(ca->ca_ra.ra_reg, PFOUR_COLOR_OFF_OVERLAY, ramsize); } #endif /* Map the Brooktree. */ if (bus_space_map(oba->oba_bustag, oba->oba_paddr + PFOUR_COLOR_OFF_CMAP, sizeof(struct fbcontrol), BUS_SPACE_MAP_LINEAR, &bh) != 0) { printf("%s: cannot map control registers\n", self->dv_xname); return; } sc->sc_fbc = (volatile struct fbcontrol *)bh; #if 0 /* XXX thorpej ??? */ /* tell the enable plane to look at the mono image */ memset(ca->ca_ra.ra_vaddr, 0xff, sc->sc_fb.fb_type.fb_width * sc->sc_fb.fb_type.fb_height / 8); #endif /* grab initial (current) color map */ bt = &sc->sc_fbc->fbc_dac; bt->bt_addr = 0; for (i = 0; i < 256 * 3 / 4; i++) sc->sc_cmap.cm_chip[i] = bt->bt_cmap; BT_INIT(bt, 0); #if 0 /* see above */ if (isconsole) { printf(" (console)\n"); #if defined(RASTERCONSOLE) && 0 /* XXX been told it doesn't work well. */ fbrcons_init(fb); #endif } else #endif /* 0 */ printf("\n"); /* * Even though we're not using rconsole, we'd still like * to notice if we're the console framebuffer. */ fb_attach(&sc->sc_fb, isconsole); #endif }
int pcigfb_attach(device_t dev) { int s; gfb_softc_t sc; video_adapter_t *adp; int unit, flags, error, rid, va_index; #ifdef __alpha__ struct ctb *ctb; #endif /* __alpha__ */ s = splimp(); error = 0; unit = device_get_unit(dev); flags = device_get_flags(dev); sc = device_get_softc(dev); sc->rev = pci_get_revid(dev); rid = GFB_MEM_BASE_RID; sc->res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 1, RF_ACTIVE|PCI_RF_DENSE); if(sc->res == NULL) { device_printf(dev, "couldn't map memory\n"); goto fail; } sc->btag = rman_get_bustag(sc->res); sc->bhandle = rman_get_bushandle(sc->res); /* Allocate interrupt (irq)... */ rid = 0x0; sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_SHAREABLE|RF_ACTIVE); if(sc->irq == NULL) { device_printf(dev, "Couldn't map interrupt\n"); goto fail; } if((va_index = vid_find_adapter(sc->driver_name, unit)) < 0) { sc->adp = (video_adapter_t *)malloc(sizeof(video_adapter_t), M_DEVBUF, M_NOWAIT); adp = sc->adp; bzero(adp, sizeof(video_adapter_t)); vid_init_struct(adp, sc->driver_name, sc->type, unit); if(vid_register(adp) < 0) { free(sc->adp, M_DEVBUF); goto fail; } adp->va_flags |= V_ADP_REGISTERED; adp->va_model = sc->model; adp->va_mem_base = (vm_offset_t)rman_get_virtual(sc->res); adp->va_mem_size = rman_get_end(sc->res) - rman_get_start(sc->res); adp->va_io_base = NULL; adp->va_io_size = 0; adp->va_crtc_addr = NULL; gfb_device_softcs[sc->model][unit] = sc; sc->gfbc = (struct gfb_conf *)malloc(sizeof(struct gfb_conf), M_DEVBUF, M_NOWAIT); bzero(sc->gfbc, sizeof(struct gfb_conf)); if((*vidsw[adp->va_index]->init)(unit, adp, flags)) { device_printf(dev, "Couldn't initialize adapter\n"); vid_unregister(adp); gfb_device_softcs[sc->model][unit] = NULL; free(sc->gfbc, M_DEVBUF); free(sc->adp, M_DEVBUF); goto fail; } sc->gfbc->palette.red = (u_char *)malloc(sc->gfbc->palette.count, M_DEVBUF, M_NOWAIT); sc->gfbc->palette.green = (u_char *)malloc(sc->gfbc->palette.count, M_DEVBUF, M_NOWAIT); sc->gfbc->palette.blue = (u_char *)malloc(sc->gfbc->palette.count, M_DEVBUF, M_NOWAIT); sc->gfbc->cursor_palette.red = (u_char *)malloc(sc->gfbc->cursor_palette.count, M_DEVBUF, M_NOWAIT); sc->gfbc->cursor_palette.green = (u_char *)malloc(sc->gfbc->cursor_palette.count, M_DEVBUF, M_NOWAIT); sc->gfbc->cursor_palette.blue = (u_char *)malloc(sc->gfbc->cursor_palette.count, M_DEVBUF, M_NOWAIT); if(gfb_init(unit, adp, flags)) { device_printf(dev, "Couldn't initialize framebuffer\n"); vid_unregister(adp); gfb_device_softcs[sc->model][unit] = NULL; free(sc->gfbc->cursor_palette.blue, M_DEVBUF); free(sc->gfbc->cursor_palette.green, M_DEVBUF); free(sc->gfbc->cursor_palette.red, M_DEVBUF); free(sc->gfbc->palette.blue, M_DEVBUF); free(sc->gfbc->palette.green, M_DEVBUF); free(sc->gfbc->palette.red, M_DEVBUF); free(sc->gfbc, M_DEVBUF); free(sc->adp, M_DEVBUF); goto fail; } } else { (*vidsw[va_index]->probe)(unit, &adp, (void *)sc->driver_name, flags); sc->adp = adp; sc->gfbc = gfb_device_softcs[sc->model][unit]->gfbc; gfb_device_softcs[sc->model][unit] = sc; } /* This is a back-door for PCI devices--since FreeBSD no longer supports PCI configuration-space accesses during the *configure() phase for video adapters, we cannot identify a PCI device as the console during the first call to sccnattach(). There must be a second chance for PCI adapters to be recognized as the console, and this is it... */ #ifdef __alpha__ ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off); if (ctb->ctb_term_type == 3) /* Display adapter */ sccnattach(); #endif /* __alpha__ */ device_printf(dev, "Board type %s\n", sc->gfbc->name); device_printf(dev, "%d x %d, %dbpp, %s RAMDAC\n", sc->adp->va_info.vi_width, sc->adp->va_info.vi_height, sc->adp->va_info.vi_depth, sc->gfbc->ramdac_name); #ifdef FB_INSTALL_CDEV /* attach a virtual frame buffer device */ error = fb_attach(makedev(0, unit), sc->adp, sc->cdevsw); if(error) goto fail; if(bootverbose) (*vidsw[sc->adp->va_index]->diag)(sc->adp, bootverbose); #if experimental device_add_child(dev, "fb", -1); bus_generic_attach(dev); #endif /*experimental*/ #endif /*FB_INSTALL_CDEV*/ goto done; fail: if(sc->intrhand != NULL) { bus_teardown_intr(dev, sc->irq, sc->intrhand); sc->intrhand = NULL; } if(sc->irq != NULL) { rid = 0x0; bus_release_resource(dev, SYS_RES_IRQ, rid, sc->irq); sc->irq = NULL; } if(sc->res != NULL) { rid = GFB_MEM_BASE_RID; bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->res); sc->res = NULL; } error = ENXIO; done: splx(s); return(error); }
void cgthreeattach(struct cgthree_softc *sc, const char *name, int isconsole) { int i; struct fbdevice *fb = &sc->sc_fb; struct wsemuldisplaydev_attach_args aa; struct rasops_info *ri = &cg3_console_screen.scr_ri; unsigned long defattr; volatile struct fbcontrol *fbc = sc->sc_fbc; volatile struct bt_regs *bt = &fbc->fbc_dac; fb->fb_driver = &cgthreefbdriver; fb->fb_type.fb_cmsize = 256; fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes; printf(": %s, %d x %d", name, fb->fb_type.fb_width, fb->fb_type.fb_height); /* Transfer video magic to board, if it's not running */ if ((fbc->fbc_ctrl & FBC_TIMING) == 0) { int sense = (fbc->fbc_status & FBS_MSENSE); /* Search table for video timings fitting this monitor */ for (i = 0; i < sizeof(cg3_videoctrl)/sizeof(cg3_videoctrl[0]); i++) { int j; if (sense != cg3_videoctrl[i].sense) continue; printf(" setting video ctrl"); for (j = 0; j < 12; j++) fbc->fbc_vcontrol[j] = cg3_videoctrl[i].vctrl[j]; fbc->fbc_ctrl |= FBC_TIMING; break; } } /* make sure we are not blanked */ cgthree_set_video(sc, 1); BT_INIT(bt, 0); if (isconsole) { printf(" (console)\n"); } else printf("\n"); fb_attach(fb, isconsole); sc->sc_width = fb->fb_type.fb_width; sc->sc_stride = fb->fb_type.fb_width; sc->sc_height = fb->fb_type.fb_height; /* setup rasops and so on for wsdisplay */ sc->sc_mode = WSDISPLAYIO_MODE_EMUL; vcons_init(&sc->vd, sc, &cgthree_defaultscreen, &cgthree_accessops); sc->vd.init_screen = cgthree_init_screen; if(isconsole) { /* we mess with cg3_console_screen only once */ vcons_init_screen(&sc->vd, &cg3_console_screen, 1, &defattr); memset(sc->sc_fb.fb_pixels, (defattr >> 16) & 0xff, sc->sc_stride * sc->sc_height); cg3_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; cgthree_defaultscreen.textops = &ri->ri_ops; cgthree_defaultscreen.capabilities = ri->ri_caps; cgthree_defaultscreen.nrows = ri->ri_rows; cgthree_defaultscreen.ncols = ri->ri_cols; sc->vd.active = &cg3_console_screen; wsdisplay_cnattach(&cgthree_defaultscreen, ri, 0, 0, defattr); vcons_replay_msgbuf(&cg3_console_screen); } else { /* * we're not the console so we just clear the screen and don't * set up any sort of text display */ }
void bwtwoattach(struct bwtwo_softc *sc, const char *name, int isconsole) { struct fbdevice *fb = &sc->sc_fb; int isoverlay; #if NWSDISPLAY > 0 struct wsemuldisplaydev_attach_args aa; struct rasops_info *ri = &bw2_console_screen.scr_ri; unsigned long defattr = 0; #endif /* Fill in the remaining fbdevice values */ fb->fb_driver = &bwtwofbdriver; fb->fb_device = sc->sc_dev; fb->fb_type.fb_type = FBTYPE_SUN2BW; fb->fb_type.fb_cmsize = 0; fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes; printf(": %s, %d x %d", name, fb->fb_type.fb_width, fb->fb_type.fb_height); /* Are we an overlay bw2? */ if ((fb->fb_flags & FB_PFOUR) == 0 || (sc->sc_ovtype == BWO_NONE)) isoverlay = 0; else isoverlay = 1; /* Insure video is enabled */ sc->sc_set_video(sc, 1); if (isconsole) { printf(" (console)\n"); #ifdef RASTERCONSOLE /* * XXX rcons doesn't seem to work properly on the overlay * XXX plane. This is a temporary kludge until someone * XXX fixes it. */ if (!isoverlay) fbrcons_init(fb); #endif } else printf("\n"); if (isoverlay) { const char *ovnam; switch (sc->sc_ovtype) { case BWO_CGFOUR: ovnam = "cgfour"; break; case BWO_CGEIGHT: ovnam = "cgeight"; break; default: ovnam = "unknown"; break; } printf("%s: %s overlay plane\n", device_xname(sc->sc_dev), ovnam); } /* * If we're on an overlay plane of a color framebuffer, * then we don't force the issue in fb_attach() because * we'd like the color framebuffer to actually be the * "console framebuffer". We're only around to speed * up rconsole. */ if (isoverlay) fb_attach(fb, 0); else fb_attach(fb, isconsole); #if NWSDISPLAY > 0 sc->sc_width = fb->fb_type.fb_width; sc->sc_stride = fb->fb_type.fb_width/8; sc->sc_height = fb->fb_type.fb_height; /* setup rasops and so on for wsdisplay */ sc->sc_mode = WSDISPLAYIO_MODE_EMUL; vcons_init(&sc->vd, sc, &bwtwo_defaultscreen, &bwtwo_accessops); sc->vd.init_screen = bwtwo_init_screen; if(isconsole && !isoverlay) { /* we mess with bw2_console_screen only once */ vcons_init_screen(&sc->vd, &bw2_console_screen, 1, &defattr); bw2_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; bwtwo_defaultscreen.textops = &ri->ri_ops; bwtwo_defaultscreen.capabilities = ri->ri_caps; bwtwo_defaultscreen.nrows = ri->ri_rows; bwtwo_defaultscreen.ncols = ri->ri_cols; sc->vd.active = &bw2_console_screen; wsdisplay_cnattach(&bwtwo_defaultscreen, ri, 0, 0, defattr); } else { /* * we're not the console so we just clear the screen and don't * set up any sort of text display */ if (bwtwo_defaultscreen.textops == NULL) { /* * ugly, but... * we want the console settings to win, so we only * touch anything when we find an untouched screen * definition. In this case we fill it from fb to * avoid problems in case no bwtwo is the console */ bwtwo_defaultscreen.textops = &ri->ri_ops; bwtwo_defaultscreen.capabilities = ri->ri_caps; bwtwo_defaultscreen.nrows = ri->ri_rows; bwtwo_defaultscreen.ncols = ri->ri_cols; } } aa.scrdata = &bwtwo_screenlist; if (isoverlay) aa.console = 0; else aa.console = isconsole; aa.accessops = &bwtwo_accessops; aa.accesscookie = &sc->vd; config_found(sc->sc_dev, &aa, wsemuldisplaydevprint); #endif }
/* * Attach a display. We need to notice if it is the console, too. */ static void p9100_sbus_attach(struct device *parent, struct device *self, void *args) { struct p9100_softc *sc = device_private(self); struct sbus_attach_args *sa = args; struct fbdevice *fb = &sc->sc_fb; int isconsole; int node; int i, j; uint8_t ver; #if NWSDISPLAY > 0 struct wsemuldisplaydev_attach_args aa; struct rasops_info *ri; unsigned long defattr; #endif sc->sc_last_offset = 0xffffffff; /* Remember cookies for p9100_mmap() */ sc->sc_bustag = sa->sa_bustag; sc->sc_ctl_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base); sc->sc_ctl_psize = 0x8000;/*(bus_size_t)sa->sa_reg[0].oa_size;*/ sc->sc_cmd_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_reg[1].oa_space, sa->sa_reg[1].oa_base); sc->sc_cmd_psize = (bus_size_t)sa->sa_reg[1].oa_size; sc->sc_fb_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_reg[2].oa_space, sa->sa_reg[2].oa_base); sc->sc_fb_psize = (bus_size_t)sa->sa_reg[2].oa_size; fb->fb_driver = &p9100fbdriver; fb->fb_device = &sc->sc_dev; fb->fb_flags = device_cfdata(&sc->sc_dev)->cf_flags & FB_USERMASK; #ifdef PNOZZ_EMUL_CG3 fb->fb_type.fb_type = FBTYPE_SUN3COLOR; #else fb->fb_type.fb_type = FBTYPE_P9100; #endif fb->fb_pixels = NULL; sc->sc_mode = WSDISPLAYIO_MODE_EMUL; node = sa->sa_node; isconsole = fb_is_console(node); if (!isconsole) { aprint_normal("\n"); aprint_error_dev(self, "fatal error: PROM didn't configure device\n"); return; } /* * When the ROM has mapped in a p9100 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. */ if (sbus_bus_map(sc->sc_bustag, sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base, /* * XXX for some reason the SBus resources don't cover * all registers, so we just map what we need */ /*sc->sc_ctl_psize*/ 0x8000, /*BUS_SPACE_MAP_LINEAR*/0, &sc->sc_ctl_memh) != 0) { aprint_error_dev(self, "cannot map control registers\n"); return; } if (sa->sa_npromvaddrs != 0) fb->fb_pixels = (void *)sa->sa_promvaddrs[0]; if (fb->fb_pixels == NULL) { if (sbus_bus_map(sc->sc_bustag, sa->sa_reg[2].oa_space, sa->sa_reg[2].oa_base, sc->sc_fb_psize, BUS_SPACE_MAP_LINEAR, &sc->sc_fb_memh) != 0) { aprint_error_dev(self, "cannot map framebuffer\n"); return; } fb->fb_pixels = (char *)sc->sc_fb_memh; } else { sc->sc_fb_memh = (bus_space_handle_t) fb->fb_pixels; } i = p9100_ctl_read_4(sc, 0x0004); switch ((i >> 26) & 7) { case 5: fb->fb_type.fb_depth = 32; break; case 7: fb->fb_type.fb_depth = 24; break; case 3: fb->fb_type.fb_depth = 16; break; case 2: fb->fb_type.fb_depth = 8; break; default: { panic("pnozz: can't determine screen depth (0x%02x)", i); } } sc->sc_depth = (fb->fb_type.fb_depth >> 3); /* XXX for some reason I get a kernel trap with this */ sc->sc_width = prom_getpropint(node, "width", 800); sc->sc_height = prom_getpropint(node, "height", 600); sc->sc_stride = prom_getpropint(node, "linebytes", sc->sc_width * (fb->fb_type.fb_depth >> 3)); /* check the RAMDAC */ ver = p9100_ramdac_read_ctl(sc, DAC_VERSION); p9100_init_engine(sc); fb_setsize_obp(fb, fb->fb_type.fb_depth, sc->sc_width, sc->sc_height, node); sbus_establish(&sc->sc_sd, &sc->sc_dev); bus_intr_establish(sc->sc_bustag, sa->sa_pri, IPL_BIO, p9100_intr, sc); fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes; printf(": rev %d / %x, %dx%d, depth %d mem %x", (i & 7), ver, fb->fb_type.fb_width, fb->fb_type.fb_height, fb->fb_type.fb_depth, (unsigned int)sc->sc_fb_psize); fb->fb_type.fb_cmsize = prom_getpropint(node, "cmsize", 256); if ((1 << fb->fb_type.fb_depth) != fb->fb_type.fb_cmsize) printf(", %d entry colormap", fb->fb_type.fb_cmsize); /* Initialize the default color map. */ /*bt_initcmap(&sc->sc_cmap, 256);*/ j = 0; for (i = 0; i < 256; i++) { sc->sc_cmap.cm_map[i][0] = rasops_cmap[j]; j++; sc->sc_cmap.cm_map[i][1] = rasops_cmap[j]; j++; sc->sc_cmap.cm_map[i][2] = rasops_cmap[j]; j++; } p9100loadcmap(sc, 0, 256); /* make sure we are not blanked */ if (isconsole) p9100_set_video(sc, 1); if (shutdownhook_establish(p9100_shutdown, sc) == NULL) { panic("%s: could not establish shutdown hook", device_xname(&sc->sc_dev)); } if (isconsole) { printf(" (console)\n"); #ifdef RASTERCONSOLE /*p9100loadcmap(sc, 255, 1);*/ fbrcons_init(fb); #endif } else printf("\n"); #if NWSDISPLAY > 0 wsfont_init(); vcons_init(&sc->vd, sc, &p9100_defscreendesc, &p9100_accessops); sc->vd.init_screen = p9100_init_screen; vcons_init_screen(&sc->vd, &p9100_console_screen, 1, &defattr); p9100_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; sc->sc_bg = (defattr >> 16) & 0xff; p9100_clearscreen(sc); ri = &p9100_console_screen.scr_ri; p9100_defscreendesc.nrows = ri->ri_rows; p9100_defscreendesc.ncols = ri->ri_cols; p9100_defscreendesc.textops = &ri->ri_ops; p9100_defscreendesc.capabilities = ri->ri_caps; if(isconsole) { wsdisplay_cnattach(&p9100_defscreendesc, ri, 0, 0, defattr); } aa.console = isconsole; aa.scrdata = &p9100_screenlist; aa.accessops = &p9100_accessops; aa.accesscookie = &sc->vd; config_found(self, &aa, wsemuldisplaydevprint); #endif /* cursor sprite handling */ p9100_init_cursor(sc); /* attach the fb */ fb_attach(fb, isconsole); /* register with power management */ sc->sc_video = 1; sc->sc_powerstate = PWR_RESUME; powerhook_establish(device_xname(&sc->sc_dev), p9100_power_hook, sc); #if NTCTRL > 0 /* register callback for external monitor status change */ tadpole_register_callback(p9100_set_extvga, sc); #endif }
/* * Attach a display. We need to notice if it is the console, too. */ void cgfourteenattach(device_t parent, device_t self, void *aux) { union obio_attach_args *uoba = aux; struct sbus_attach_args *sa = &uoba->uoba_sbus; struct cgfourteen_softc *sc = device_private(self); struct fbdevice *fb = &sc->sc_fb; bus_space_handle_t bh; int node, ramsize; volatile uint32_t *lut; int i, isconsole; sc->sc_dev = self; node = sa->sa_node; /* Remember cookies for cgfourteenmmap() */ sc->sc_bustag = sa->sa_bustag; fb->fb_driver = &cgfourteenfbdriver; fb->fb_device = sc->sc_dev; /* Mask out invalid flags from the user. */ fb->fb_flags = device_cfdata(sc->sc_dev)->cf_flags & FB_USERMASK; /* * We're emulating a cg3/8, so represent ourselves as one */ #ifdef CG14_CG8 fb->fb_type.fb_type = FBTYPE_MEMCOLOR; fb->fb_type.fb_depth = 32; #else fb->fb_type.fb_type = FBTYPE_SUN3COLOR; fb->fb_type.fb_depth = 8; #endif fb_setsize_obp(fb, sc->sc_fb.fb_type.fb_depth, 1152, 900, node); ramsize = roundup(fb->fb_type.fb_height * fb->fb_linebytes, NBPG); fb->fb_type.fb_cmsize = CG14_CLUT_SIZE; fb->fb_type.fb_size = ramsize + COLOUR_OFFSET; if (sa->sa_nreg < 2) { printf("%s: only %d register sets\n", self->dv_xname, sa->sa_nreg); return; } bcopy(sa->sa_reg, sc->sc_physadr, sa->sa_nreg * sizeof(struct sbus_reg)); sc->sc_vramsize = sc->sc_physadr[CG14_PXL_IDX].sbr_size; printf(": %d MB VRAM", (uint32_t)(sc->sc_vramsize >> 20)); /* * Now map in the 8 useful pages of registers */ if (sa->sa_size < 0x10000) { #ifdef DIAGNOSTIC printf("warning: can't find all cgfourteen registers...\n"); #endif sa->sa_size = 0x10000; } if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, sa->sa_offset, sa->sa_size, BUS_SPACE_MAP_LINEAR, &bh) != 0) { printf("%s: cannot map control registers\n", self->dv_xname); return; } sc->sc_regh = bh; sc->sc_ctl = (struct cg14ctl *) (bh); sc->sc_hwc = (struct cg14curs *) (bh + CG14_OFFSET_CURS); sc->sc_dac = (struct cg14dac *) (bh + CG14_OFFSET_DAC); sc->sc_xlut = (struct cg14xlut *) (bh + CG14_OFFSET_XLUT); sc->sc_clut1 = (struct cg14clut *) (bh + CG14_OFFSET_CLUT1); sc->sc_clut2 = (struct cg14clut *) (bh + CG14_OFFSET_CLUT2); sc->sc_clut3 = (struct cg14clut *) (bh + CG14_OFFSET_CLUT3); sc->sc_clutincr = (u_int *) (bh + CG14_OFFSET_CLUTINCR); /* * Let the user know that we're here */ #ifdef CG14_CG8 printf(": cgeight emulated at %dx%dx24bpp", fb->fb_type.fb_width, fb->fb_type.fb_height); #else printf(": cgthree emulated at %dx%dx8bpp", fb->fb_type.fb_width, fb->fb_type.fb_height); #endif /* * Enable the video. */ cg14_set_video(sc, 1); /* * Grab the initial colormap */ lut = sc->sc_clut1->clut_lut; for (i = 0; i < CG14_CLUT_SIZE; i++) sc->sc_cmap.cm_chip[i] = lut[i]; /* See if we're the console */ isconsole = fb_is_console(node); #if defined(RASTERCONSOLE) if (isconsole) { printf(" (console)\n"); /* *sbus*_bus_map? but that's how we map the regs... */ if (sbus_bus_map( sc->sc_bustag, sc->sc_physadr[CG14_PXL_IDX].sbr_slot, sc->sc_physadr[CG14_PXL_IDX].sbr_offset + 0x03800000, 1152 * 900, BUS_SPACE_MAP_LINEAR, &bh) != 0) { printf("%s: cannot map pixels\n", device_xname(sc->sc_dev)); return; } sc->sc_rcfb = sc->sc_fb; sc->sc_rcfb.fb_type.fb_type = FBTYPE_SUN3COLOR; sc->sc_rcfb.fb_type.fb_depth = 8; sc->sc_rcfb.fb_linebytes = 1152; sc->sc_rcfb.fb_type.fb_size = roundup(1152*900,NBPG); sc->sc_rcfb.fb_pixels = (void *)bh; printf("vram at %p\n",(void *)bh); /* XXX should use actual screen size */ for (i = 0; i < 1152 * 900; i++) ((unsigned char *)bh)[i] = 0; fbrcons_init(&sc->sc_rcfb); cg14_set_rcons_luts(sc); sc->sc_ctl->ctl_mctl = CG14_MCTL_ENABLEVID | CG14_MCTL_PIXMODE_32 | CG14_MCTL_POWERCTL; } else printf("\n"); #endif #if NWSDISPLAY > 0 if (sbus_bus_map( sc->sc_bustag, sc->sc_physadr[CG14_PXL_IDX].sbr_slot, sc->sc_physadr[CG14_PXL_IDX].sbr_offset, ramsize, BUS_SPACE_MAP_LINEAR, &bh) != 0) { printf("%s: cannot map pixels\n", device_xname(sc->sc_dev)); return; } sc->sc_fb.fb_pixels = bus_space_vaddr(sc->sc_bustag, bh); if (isconsole) printf(" (console)\n"); else printf("\n"); sc->sc_depth = 8; cg14_setup_wsdisplay(sc, isconsole); #endif /* Attach to /dev/fb */ fb_attach(&sc->sc_fb, isconsole); }