/* * 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 }
/* * 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 }
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. */ 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); }