/* * Attach.. plug pointer in and print some info. * Then try and attach a wsdisplay or ite to us. * Note: self is NULL durring console init. */ void grfattach(device_t parent, device_t self, void *aux) { #if NWSDISPLAY > 0 struct wsemuldisplaydev_attach_args wa; long defattr; #endif struct grf_softc *gp; int maj; gp = device_private(parent); gp->g_device = self; grfsp[gp->g_unit] = gp; /* * find our major device number */ maj = cdevsw_lookup_major(&grf_cdevsw); gp->g_grfdev = makedev(maj, gp->g_unit); if (self != NULL) { printf(": width %d height %d", gp->g_display.gd_dwidth, gp->g_display.gd_dheight); if (gp->g_display.gd_colors == 2) printf(" monochrome\n"); else printf(" colors %d\n", gp->g_display.gd_colors); #if NWSDISPLAY > 0 vcons_init(&gp->g_vd, gp, gp->g_screens[0], gp->g_accessops); gp->g_vd.init_screen = grf_init_screen; if (gp->g_flags & GF_CONSOLE) { console_vcons.scr_flags |= VCONS_SCREEN_IS_STATIC; vcons_init_screen(&gp->g_vd, &console_vcons, 1, &defattr); gp->g_screens[0]->textops = &console_vcons.scr_ri.ri_ops; wsdisplay_cnattach(gp->g_screens[0], &console_vcons.scr_ri, 0, 0, defattr); vcons_replay_msgbuf(&console_vcons); } /* attach wsdisplay */ wa.console = (gp->g_flags & GF_CONSOLE) != 0; wa.scrdata = &gp->g_screenlist; wa.accessops = gp->g_accessops; wa.accesscookie = &gp->g_vd; config_found(self, &wa, wsemuldisplaydevprint); #endif /* NWSDISPLAY > 0 */ } #if NWSDISPLAY == 0 /* * try and attach an ite */ amiga_config_found(cfdata, self, gp, grfprint); #endif }
static void vidcvideo_attach(device_t parent, device_t self, void *aux) { struct vidcvideo_softc *sc = device_private(self); struct fb_devconfig *dc; struct wsemuldisplaydev_attach_args waa; long defattr; sc->sc_dev = self; dc = sc->sc_dc = &vidcvideo_console_dc; /* * for reasons which are crazy we init vidcvideo twice, * the second time sets up the cursor */ vidcvideo_init(); if (!vidcvideo_is_console) { vidcvideo_getdevconfig(videomemory.vidm_vbase, videomemory.vidm_size, sc->sc_dc); } vcons_init(&dc->dc_vd, dc, &vidcvideo_stdscreen, &vidcvideo_accessops); dc->dc_vd.init_screen = vidcvideoinit_screen; vcons_init_screen(&dc->dc_vd, &dc->dc_console, 1, &defattr); dc->dc_console.scr_flags |= VCONS_SCREEN_IS_STATIC; vidcvideo_printdetails(); aprint_normal(": mode %s, %dbpp\n", dc->mode_info.timings.name, dc->dc_depth); /* set up interrupt flags */ vidcvideo_queue_dc_change(dc, WSDISPLAY_CMAP_DOLUT); /* Establish an interrupt handler, and clear any pending interrupts */ dc->dc_ih = intr_claim(IRQ_FLYBACK, IPL_TTY, "vblank", vidcvideointr, dc); waa.console = (vidcvideo_is_console ? 1 : 0); waa.scrdata = &vidcvideo_screenlist; waa.accessops = &vidcvideo_accessops; waa.accesscookie = &dc->dc_vd; config_found(self, &waa, wsemuldisplaydevprint); }
static void newport_attach(device_t parent, device_t self, void *aux) { struct gio_attach_args *ga = aux; struct newport_softc *sc = device_private(self); struct wsemuldisplaydev_attach_args wa; unsigned long defattr; sc->sc_dev = self; if (newport_is_console && ga->ga_addr == newport_console_dc.dc_addr) { wa.console = 1; sc->sc_dc = &newport_console_dc; } else { wa.console = 0; sc->sc_dc = malloc(sizeof(struct newport_devconfig), M_DEVBUF, M_WAITOK | M_ZERO); if (sc->sc_dc == NULL) panic("newport_attach: out of memory"); newport_attach_common(sc->sc_dc, ga); } aprint_naive(": Display adapter\n"); aprint_normal(": SGI NG1 (board revision %d, cmap revision %d, xmap revision %d, vc2 revision %d), depth %d\n", sc->sc_dc->dc_boardrev, sc->sc_dc->dc_cmaprev, sc->sc_dc->dc_xmaprev, sc->sc_dc->dc_vc2rev, sc->sc_dc->dc_depth); vcons_init(&sc->sc_dc->dc_vd, sc->sc_dc, sc->sc_dc->dc_screen, &newport_accessops); sc->sc_dc->dc_vd.init_screen = newport_init_screen; if (newport_is_console) { newport_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; vcons_init_screen(&sc->sc_dc->dc_vd, &newport_console_screen, 1, &defattr); sc->sc_dc->dc_screen->textops = &newport_console_screen.scr_ri.ri_ops; memcpy(&newport_textops, &newport_console_screen.scr_ri.ri_ops, sizeof(struct wsdisplay_emulops)); vcons_replay_msgbuf(&newport_console_screen); } wa.scrdata = &newport_screenlist; wa.accessops = &newport_accessops; wa.accesscookie = &sc->sc_dc->dc_vd; config_found(sc->sc_dev, &wa, wsemuldisplaydevprint); }
static void zx_attach(device_t parent, device_t self, void *args) { struct zx_softc *sc; struct sbus_attach_args *sa; bus_space_handle_t bh; bus_space_tag_t bt; struct fbdevice *fb; #if NWSDISPLAY > 0 struct wsemuldisplaydev_attach_args aa; struct rasops_info *ri = &zx_console_screen.scr_ri; unsigned long defattr; #endif int isconsole, width, height; sc = device_private(self); sc->sc_dv = self; sa = args; fb = &sc->sc_fb; bt = sa->sa_bustag; sc->sc_bt = bt; sc->sc_paddr = sbus_bus_addr(bt, sa->sa_slot, sa->sa_offset); if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_SS0, 0x800000, BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE, &bh) != 0) { aprint_error_dev(self, "can't map bits\n"); return; } fb->fb_pixels = (void *)bus_space_vaddr(bt, bh); sc->sc_pixels = (uint32_t *)fb->fb_pixels; if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LC_SS0_USR, PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) { aprint_error_dev(self, "can't map zc\n"); return; } sc->sc_bhzc = bh; if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS0, PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) { aprint_error_dev(self, "can't map ld/ss0\n"); return; } sc->sc_bhzdss0 = bh; if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS1, PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) { aprint_error_dev(self, "can't map ld/ss1\n"); return; } sc->sc_bhzdss1 = bh; if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CROSS, PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) { aprint_error_dev(self, "can't map zx\n"); return; } sc->sc_bhzx = bh; if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CURSOR, PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) { aprint_error_dev(self, "can't map zcu\n"); return; } sc->sc_bhzcu = bh; fb->fb_driver = &zx_fbdriver; fb->fb_device = sc->sc_dv; fb->fb_flags = device_cfdata(sc->sc_dv)->cf_flags & FB_USERMASK; fb->fb_pfour = NULL; fb->fb_linebytes = prom_getpropint(sa->sa_node, "linebytes", 8192); width = prom_getpropint(sa->sa_node, "width", 1280); height = prom_getpropint(sa->sa_node, "height", 1024); fb_setsize_obp(fb, 32, width, height, sa->sa_node); fb->fb_type.fb_cmsize = 256; fb->fb_type.fb_depth = 32; fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes; fb->fb_type.fb_type = FBTYPE_SUNLEO; printf(": %d x %d", fb->fb_type.fb_width, fb->fb_type.fb_height); isconsole = fb_is_console(sa->sa_node); if (isconsole) printf(" (console)"); printf("\n"); if (sa->sa_nintr != 0) bus_intr_establish(bt, sa->sa_pri, IPL_NONE, zx_intr, sc); sc->sc_cmap = malloc(768, M_DEVBUF, M_NOWAIT); zx_reset(sc); #if NWSDISPLAY > 0 sc->sc_width = fb->fb_type.fb_width; sc->sc_stride = 8192; /* 32 bit */ sc->sc_height = fb->fb_type.fb_height; /* setup rasops and so on for wsdisplay */ wsfont_init(); sc->sc_mode = WSDISPLAYIO_MODE_EMUL; sc->sc_bg = WS_DEFAULT_BG; vcons_init(&sc->vd, sc, &zx_defaultscreen, &zx_accessops); sc->vd.init_screen = zx_init_screen; if (isconsole) { /* we mess with zx_console_screen only once */ vcons_init_screen(&sc->vd, &zx_console_screen, 1, &defattr); zx_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; zx_defaultscreen.textops = &ri->ri_ops; zx_defaultscreen.capabilities = WSSCREEN_WSCOLORS; zx_defaultscreen.nrows = ri->ri_rows; zx_defaultscreen.ncols = ri->ri_cols; zx_fillrect(sc, 0, 0, width, height, ri->ri_devcmap[defattr >> 16], ZX_STD_ROP); wsdisplay_cnattach(&zx_defaultscreen, ri, 0, 0, defattr); vcons_replay_msgbuf(&zx_console_screen); } else { /* * we're not the console so we just clear the screen and don't * set up any sort of text display */ if (zx_defaultscreen.textops == NULL) {
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 */ }
static void ofbattach(device_t parent, device_t self, void *aux) { struct ofb_softc *sc = device_private(self); struct pci_attach_args *pa = aux; struct wsemuldisplaydev_attach_args a; struct rasops_info *ri = &rascons_console_screen.scr_ri; long defattr; int console, node, sub; char devinfo[256]; sc->sc_dev = self; pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); printf(": %s\n", devinfo); if (console_node == 0) return; node = pcidev_to_ofdev(pa->pa_pc, pa->pa_tag); console = (node == console_node); if (!console) { /* check if any of the childs matches */ sub = OF_child(node); while ((sub != 0) && (sub != console_node)) { sub = OF_peer(sub); } if (sub == console_node) { console = true; } } sc->sc_memt = pa->pa_memt; sc->sc_iot = pa->pa_iot; sc->sc_pc = pa->pa_pc; sc->sc_pcitag = pa->pa_tag; sc->sc_mode = WSDISPLAYIO_MODE_EMUL; if (!console) return; vcons_init(&sc->vd, sc, &rascons_stdscreen, &ofb_accessops); sc->vd.init_screen = ofb_init_screen; sc->sc_node = console_node; sc->sc_ih = console_instance; vcons_init_screen(&sc->vd, &rascons_console_screen, 1, &defattr); rascons_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; printf("%s: %d x %d, %dbpp\n", device_xname(self), ri->ri_width, ri->ri_height, ri->ri_depth); sc->sc_fbaddr = 0; if (OF_getprop(sc->sc_node, "address", &sc->sc_fbaddr, 4) != 4) OF_interpret("frame-buffer-adr", 0, 1, &sc->sc_fbaddr); if (sc->sc_fbaddr == 0) { printf("%s: Unable to find the framebuffer address.\n", device_xname(sc->sc_dev)); return; } sc->sc_fbsize = round_page(ri->ri_stride * ri->ri_height); /* XXX */ if (OF_getprop(sc->sc_node, "assigned-addresses", sc->sc_addrs, sizeof(sc->sc_addrs)) == -1) { sc->sc_node = OF_parent(sc->sc_node); OF_getprop(sc->sc_node, "assigned-addresses", sc->sc_addrs, sizeof(sc->sc_addrs)); } ofb_init_cmap(sc); a.console = console; a.scrdata = &ofb_screenlist; a.accessops = &ofb_accessops; a.accesscookie = &sc->vd; config_found(self, &a, wsemuldisplaydevprint); config_found_ia(self, "drm", aux, ofb_drm_print); }
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 }
static void igmafb_attach(device_t parent, device_t self, void *aux) { struct igmafb_softc *sc = device_private(self); struct igma_attach_args *iaa = (struct igma_attach_args *)aux; struct rasops_info *ri; prop_dictionary_t dict; bool is_console; unsigned long defattr; struct wsemuldisplaydev_attach_args waa; sc->sc_dev = self; aprint_normal("\n"); dict = device_properties(self); prop_dictionary_get_bool(dict, "is_console", &is_console); if (iaa->iaa_console) is_console = true; sc->sc_chip = iaa->iaa_chip; sc->sc_fbaddr = bus_space_vaddr(sc->sc_chip.gmt, sc->sc_chip.gmh); sc->sc_fbsize = 16 * 1024 * 1024; igmafb_guess_size(sc, &sc->sc_width, &sc->sc_height); sc->sc_depth = 32; sc->sc_stride = (sc->sc_width*4 + 511)/512*512; aprint_normal("%s: %d x %d, %d bit, stride %d\n", device_xname(self), sc->sc_width, sc->sc_height, sc->sc_depth, sc->sc_stride); aprint_normal("%s: %d MB video memory at 0x%p\n", device_xname(self), (int)sc->sc_fbsize >> 20, (void *)sc->sc_chip.gmb); sc->sc_vga_save = kmem_alloc(256*1024, KM_SLEEP); igmafb_get_brightness(sc, &sc->sc_brightness); igmafb_get_brightness_max(sc, &sc->sc_brightness_max); sc->sc_backlight = sc->sc_brightness != 0; sc->sc_defaultscreen_descr = (struct wsscreen_descr) { "default", 0, 0, NULL, 8, 16, WSSCREEN_WSCOLORS | WSSCREEN_HILIT, NULL }; sc->sc_screens[0] = &sc->sc_defaultscreen_descr; sc->sc_screenlist = (struct wsscreen_list) { 1, sc->sc_screens }; vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr, &igmafb_accessops); sc->vd.init_screen = igmafb_init_screen; /* enable hardware display */ igmafb_set_mode(sc, true); ri = &sc->sc_console_screen.scr_ri; if (is_console) { vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, &defattr); sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC | VCONS_NO_COPYROWS | VCONS_NO_COPYCOLS; vcons_redraw_screen(&sc->sc_console_screen); sc->sc_defaultscreen_descr.textops = &ri->ri_ops; sc->sc_defaultscreen_descr.capabilities = ri->ri_caps; sc->sc_defaultscreen_descr.nrows = ri->ri_rows; sc->sc_defaultscreen_descr.ncols = ri->ri_cols; wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0, defattr); vcons_replay_msgbuf(&sc->sc_console_screen); } else { if (sc->sc_console_screen.scr_ri.ri_rows == 0) { /* do some minimal setup to avoid weirdness later */ vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, &defattr); } else (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr); } waa.console = is_console; waa.scrdata = &sc->sc_screenlist; waa.accessops = &igmafb_accessops; waa.accesscookie = &sc->vd; config_found(sc->sc_dev, &waa, wsemuldisplaydevprint); } /* * wsdisplay accessops */ static int igmafb_ioctl(void *v, void *vs, u_long cmd, void *data, int flags, struct lwp *l) { struct vcons_data *vd = v; struct igmafb_softc *sc = vd->cookie; struct wsdisplay_fbinfo *wdf; struct vcons_screen *ms = vd->active; struct wsdisplayio_fbinfo *fbi; struct wsdisplay_param *param; int val; switch (cmd) { case WSDISPLAYIO_GTYPE: *(u_int *)data = WSDISPLAY_TYPE_PCIMISC; return 0; case WSDISPLAYIO_GINFO: if (ms == NULL) return ENODEV; wdf = data; wdf->width = ms->scr_ri.ri_width; wdf->height = ms->scr_ri.ri_height; wdf->depth = ms->scr_ri.ri_depth; wdf->cmsize = 256; /* XXX */ return 0; case WSDISPLAYIO_LINEBYTES: if (ms == NULL) return ENODEV; *(u_int *)data = ms->scr_ri.ri_stride; return 0; case WSDISPLAYIO_GET_FBINFO: fbi = data; return wsdisplayio_get_fbinfo(&ms->scr_ri, fbi); case WSDISPLAYIO_SVIDEO: val = (*(u_int *)data) != WSDISPLAYIO_VIDEO_OFF; sc->sc_backlight = val; if (val) igmafb_set_brightness(sc, sc->sc_brightness); else igmafb_set_brightness(sc, 0); return 0; case WSDISPLAYIO_GETPARAM: param = (struct wsdisplay_param *)data; switch (param->param) { case WSDISPLAYIO_PARAM_BRIGHTNESS: param->min = 0; param->max = 255; if (sc->sc_backlight) igmafb_get_brightness(sc, &val); else val = sc->sc_brightness; val = val * 255 / sc->sc_brightness_max; param->curval = val; return 0; case WSDISPLAYIO_PARAM_BACKLIGHT: param->min = 0; param->max = 1; param->curval = sc->sc_backlight; return 0; } return EPASSTHROUGH; case WSDISPLAYIO_SETPARAM: param = (struct wsdisplay_param *)data; switch (param->param) { case WSDISPLAYIO_PARAM_BRIGHTNESS: val = param->curval; if (val < 0) val = 0; if (val > 255) val = 255; val = val * sc->sc_brightness_max / 255; sc->sc_brightness = val; if (sc->sc_backlight) igmafb_set_brightness(sc, val); return 0; case WSDISPLAYIO_PARAM_BACKLIGHT: val = param->curval; sc->sc_backlight = val; if (val) igmafb_set_brightness(sc, sc->sc_brightness); else igmafb_set_brightness(sc, 0); return 0; } return EPASSTHROUGH; } return EPASSTHROUGH; } static paddr_t igmafb_mmap(void *v, void *vs, off_t offset, int prot) { struct vcons_data *vd = v; struct igmafb_softc *sc = vd->cookie; if ((offset & PAGE_MASK) != 0) return -1; if (offset < 0 || offset >= sc->sc_fbsize) return -1; return bus_space_mmap(sc->sc_chip.gmt, sc->sc_chip.gmb, offset, prot, BUS_SPACE_MAP_LINEAR); } static void igmafb_pollc(void *v, int on) { struct vcons_data *vd = v; struct igmafb_softc *sc = vd->cookie; if (sc == NULL) return; if (sc->sc_console_screen.scr_vd == NULL) return; if (on) vcons_enable_polling(&sc->vd); else vcons_disable_polling(&sc->vd); } static void igmafb_init_screen(void *cookie, struct vcons_screen *scr, int existing, long *defattr) { struct igmafb_softc *sc = cookie; struct rasops_info *ri = &scr->scr_ri; memset(ri, 0, sizeof(struct rasops_info)); ri->ri_depth = sc->sc_depth; ri->ri_width = sc->sc_width; ri->ri_height = sc->sc_height; ri->ri_stride = sc->sc_stride; ri->ri_flg = RI_CENTER | RI_FULLCLEAR; ri->ri_bits = (char *)sc->sc_fbaddr; if (existing) { ri->ri_flg |= RI_CLEAR; } switch (sc->sc_depth) { case 32: ri->ri_rnum = 8; ri->ri_gnum = 8; ri->ri_bnum = 8; ri->ri_rpos = 16; ri->ri_gpos = 8; ri->ri_bpos = 0; break; } rasops_init(ri, 0, 0); ri->ri_caps = WSSCREEN_WSCOLORS; rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight, sc->sc_width / ri->ri_font->fontwidth); ri->ri_hw = scr; } static void igmafb_guess_size(struct igmafb_softc *sc, int *widthp, int *heightp) { const struct igma_chip *cd = &sc->sc_chip; const struct igma_chip_ops *co = cd->ops; int pipe = cd->use_pipe; u_int32_t r; r = co->read_reg(cd, PIPE_HTOTAL(pipe)); *widthp = PIPE_HTOTAL_GET_ACTIVE(r); r = co->read_reg(cd, PIPE_VTOTAL(pipe)); *heightp = PIPE_VTOTAL_GET_ACTIVE(r); aprint_normal("%s: vga active size %d x %d\n", device_xname(sc->sc_dev), *widthp, *heightp); if (*widthp < 640 || *heightp < 400) { r = co->read_reg(cd, PF_WINSZ(pipe)); *widthp = PF_WINSZ_GET_WIDTH(r); *heightp = PF_WINSZ_GET_HEIGHT(r); aprint_normal("%s: window size %d x %d\n", device_xname(sc->sc_dev), *widthp, *heightp); } if (*widthp < 640) *widthp = 640; if (*heightp < 400) *heightp = 400; } static void igmafb_set_mode(struct igmafb_softc *sc, bool enable) { const struct igma_chip *cd = &sc->sc_chip; const struct igma_chip_ops *co = cd->ops; int pipe = cd->use_pipe; u_int32_t r; u_int8_t b; int i; if (enable) { /* disable VGA machinery */ b = co->read_vga(cd, 0x01); co->write_vga(cd, 0x01, b | 0x20); /* disable VGA compatible display */ r = co->read_reg(cd, sc->sc_chip.vga_cntrl); co->write_reg(cd, sc->sc_chip.vga_cntrl, r | VGA_CNTRL_DISABLE); /* save VGA memory */ memcpy(sc->sc_vga_save, sc->sc_fbaddr, 256*1024); /* configure panel fitter */ co->write_reg(cd, PF_WINPOS(pipe), PF_WINPOS_VAL(0, 0)); co->write_reg(cd, PF_WINSZ(pipe), PF_WINSZ_VAL(sc->sc_width, sc->sc_height)); /* pipe size */ co->write_reg(cd, PIPE_SRCSZ(pipe), PIPE_SRCSZ_VAL(sc->sc_width, sc->sc_height)); /* enable pipe */ co->write_reg(cd, PIPE_CONF(pipe), PIPE_CONF_ENABLE | PIPE_CONF_8BPP); /* configure planes */ r = co->read_reg(cd, PRI_CTRL(pipe)); r &= ~(PRI_CTRL_PIXFMTMSK | PRI_CTRL_TILED); r |= PRI_CTRL_ENABLE | PRI_CTRL_BGR; co->write_reg(cd, PRI_CTRL(pipe), r | cd->pri_cntrl); co->write_reg(cd, PRI_LINOFF(pipe), 0); co->write_reg(cd, PRI_STRIDE(pipe), sc->sc_stride); co->write_reg(cd, PRI_SURF(pipe), 0); co->write_reg(cd, PRI_TILEOFF(pipe), 0); if (cd->quirks & IGMA_PLANESTART_QUIRK) igmafb_planestart_quirk(sc); if (cd->quirks & IGMA_PFITDISABLE_QUIRK) igmafb_pfitdisable_quirk(sc); } else { /* disable planes */ co->write_reg(cd, PRI_CTRL(pipe), 0 | cd->pri_cntrl); co->write_reg(cd, PRI_LINOFF(pipe), 0); co->write_reg(cd, PRI_STRIDE(pipe), 2560); co->write_reg(cd, PRI_SURF(pipe), 0); co->write_reg(cd, PRI_TILEOFF(pipe), 0); /* pipe size */ co->write_reg(cd, PIPE_SRCSZ(pipe), PIPE_SRCSZ_VAL(720,400)); /* disable pipe */ co->write_reg(cd, PIPE_CONF(pipe), 0); for (i=0; i<10; ++i) { delay(10); if ((co->read_reg(cd, PIPE_CONF(pipe)) & PIPE_CONF_STATE) == 0) break; } /* workaround before enabling VGA */ r = co->read_reg(cd, 0x42000); co->write_reg(cd, 0x42000, (r & 0x1fffffff) | 0xa0000000); r = co->read_reg(cd, 0x42004); co->write_reg(cd, 0x42004, (r & 0xfbffffff) | 0x00000000); /* configure panel fitter */ co->write_reg(cd, PF_WINPOS(pipe), PF_WINPOS_VAL(0, 0)); co->write_reg(cd, PF_WINSZ(pipe), PF_WINSZ_VAL(sc->sc_width, sc->sc_height)); /* enable VGA compatible display */ r = co->read_reg(cd, sc->sc_chip.vga_cntrl); co->write_reg(cd, sc->sc_chip.vga_cntrl, r & ~VGA_CNTRL_DISABLE); /* enable VGA machinery */ b = co->read_vga(cd, 0x01); co->write_vga(cd, 0x01, b & ~0x20); /* restore VGA memory */ memcpy(sc->sc_fbaddr, sc->sc_vga_save, 256*1024); /* enable pipe again */ co->write_reg(cd, PIPE_CONF(pipe), PIPE_CONF_ENABLE | PIPE_CONF_6BPP | PIPE_CONF_DITHER); } } static void igmafb_planestart_quirk(struct igmafb_softc *sc) { const struct igma_chip *cd = &sc->sc_chip; const struct igma_chip_ops *co = cd->ops; int pipe = cd->use_pipe; u_int32_t cntrl, fwbcl; /* disable self refresh */ fwbcl = co->read_reg(cd, FW_BLC_SELF); co->write_reg(cd, FW_BLC_SELF, fwbcl & ~FW_BLC_SELF_EN); cntrl = co->read_reg(cd, CUR_CNTR(pipe)); co->write_reg(cd, CUR_CNTR(pipe), 1<<5 | 0x07); /* "wait for vblank" */ delay(40000); co->write_reg(cd, CUR_CNTR(pipe), cntrl); co->write_reg(cd, CUR_BASE(pipe), co->read_reg(cd, CUR_BASE(pipe))); co->write_reg(cd, FW_BLC_SELF, fwbcl); } static void igmafb_pfitdisable_quirk(struct igmafb_softc *sc) { const struct igma_chip *cd = &sc->sc_chip; const struct igma_chip_ops *co = cd->ops; u_int32_t r; /* disable i965 panel fitter */ r = co->read_reg(cd, PF_CTRL_I965); co->write_reg(cd, PF_CTRL_I965, r & ~PF_ENABLE); } static void igmafb_get_brightness_max(struct igmafb_softc *sc, int *valp) { const struct igma_chip *cd = &sc->sc_chip; const struct igma_chip_ops *co = cd->ops; u_int32_t r, f; r = co->read_reg(cd, cd->backlight_cntrl); f = BACKLIGHT_GET_FREQ(r); if (f == 0) { r = co->read_reg(cd, RAWCLK_FREQ); f = r * 1000000 / (200 * 128); if (f == 0 || f > 32767) f = 125 * 100000 / (200 * 128); } *valp = f; } static void igmafb_get_brightness(struct igmafb_softc *sc, int *valp) { const struct igma_chip *cd = &sc->sc_chip; const struct igma_chip_ops *co = cd->ops; u_int32_t r, v; r = co->read_reg(cd, cd->backlight_cntrl); v = BACKLIGHT_GET_CYCLE(r); *valp = v; } static void igmafb_set_brightness(struct igmafb_softc *sc, int val) { const struct igma_chip *cd = &sc->sc_chip; const struct igma_chip_ops *co = cd->ops; u_int32_t r, f, l; r = co->read_reg(cd, cd->backlight_cntrl); f = BACKLIGHT_GET_FREQ(r); l = BACKLIGHT_GET_LEGACY(r); co->write_reg(cd, cd->backlight_cntrl, BACKLIGHT_VAL(f,l,val)); }
/* * 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 }
static void cg14_setup_wsdisplay(struct cgfourteen_softc *sc, int is_cons) { struct wsemuldisplaydev_attach_args aa; struct rasops_info *ri; long defattr; sc->sc_defaultscreen_descr = (struct wsscreen_descr){ "default", 0, 0, NULL, 8, 16, WSSCREEN_WSCOLORS | WSSCREEN_HILIT, NULL }; sc->sc_screens[0] = &sc->sc_defaultscreen_descr; sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens}; sc->sc_mode = WSDISPLAYIO_MODE_EMUL; vcons_init(&sc->sc_vd, sc, &sc->sc_defaultscreen_descr, &cg14_accessops); sc->sc_vd.init_screen = cg14_init_screen; ri = &sc->sc_console_screen.scr_ri; if (is_cons) { vcons_init_screen(&sc->sc_vd, &sc->sc_console_screen, 1, &defattr); sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; sc->sc_defaultscreen_descr.textops = &ri->ri_ops; sc->sc_defaultscreen_descr.capabilities = ri->ri_caps; sc->sc_defaultscreen_descr.nrows = ri->ri_rows; sc->sc_defaultscreen_descr.ncols = ri->ri_cols; wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0, defattr); } else { /* * since we're not the console we can postpone the rest * until someone actually allocates a screen for us */ } cg14_init_cmap(sc); aa.console = is_cons; aa.scrdata = &sc->sc_screenlist; aa.accessops = &cg14_accessops; aa.accesscookie = &sc->sc_vd; config_found(sc->sc_dev, &aa, wsemuldisplaydevprint); } static void cg14_init_cmap(struct cgfourteen_softc *sc) { int i, j = 0; for (i = 0; i < 256; i++) { sc->sc_cmap.cm_map[i][3] = rasops_cmap[j]; sc->sc_cmap.cm_map[i][2] = rasops_cmap[j + 1]; sc->sc_cmap.cm_map[i][1] = rasops_cmap[j + 2]; j += 3; } cg14_load_hwcmap(sc, 0, 256); } static int cg14_putcmap(struct cgfourteen_softc *sc, struct wsdisplay_cmap *cm) { u_int index = cm->index; u_int count = cm->count; int i, error; u_char rbuf[256], gbuf[256], bbuf[256]; if (cm->index >= 256 || cm->count > 256 || (cm->index + cm->count) > 256) return EINVAL; error = copyin(cm->red, &rbuf[index], count); if (error) return error; error = copyin(cm->green, &gbuf[index], count); if (error) return error; error = copyin(cm->blue, &bbuf[index], count); if (error) return error; for (i = 0; i < count; i++) { sc->sc_cmap.cm_map[index][3] = rbuf[index]; sc->sc_cmap.cm_map[index][2] = gbuf[index]; sc->sc_cmap.cm_map[index][1] = bbuf[index]; index++; } cg14_load_hwcmap(sc, 0, 256); return 0; }