Module Name: src Committed By: macallan Date: Sun May 12 11:48:05 UTC 2024
Modified Files: src/sys/arch/sparc/dev: cgfourteen.c Log Message: support 16bit / RGB565 colour To generate a diff of this commit: cvs rdiff -u -r1.97 -r1.98 src/sys/arch/sparc/dev/cgfourteen.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/sparc/dev/cgfourteen.c diff -u src/sys/arch/sparc/dev/cgfourteen.c:1.97 src/sys/arch/sparc/dev/cgfourteen.c:1.98 --- src/sys/arch/sparc/dev/cgfourteen.c:1.97 Wed Apr 24 11:49:58 2024 +++ src/sys/arch/sparc/dev/cgfourteen.c Sun May 12 11:48:05 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: cgfourteen.c,v 1.97 2024/04/24 11:49:58 macallan Exp $ */ +/* $NetBSD: cgfourteen.c,v 1.98 2024/05/12 11:48:05 macallan Exp $ */ /* * Copyright (c) 1996 @@ -385,6 +385,7 @@ cgfourteenattach(device_t parent, device /* Attach to /dev/fb */ fb_attach(&sc->sc_fb, isconsole); + } /* @@ -493,6 +494,7 @@ cgfourteenioctl(dev_t dev, u_long cmd, v return EINVAL; cg14_set_depth(sc, depth); + cg14_init_cmap(sc); } break; default: @@ -608,7 +610,8 @@ cgfourteenpoll(dev_t dev, int events, st static void cg14_init(struct cgfourteen_softc *sc) { - cg14_set_depth(sc, 32); + cg14_set_depth(sc, 32); + cg14_init_cmap(sc); } static void @@ -616,6 +619,7 @@ static void cg14_reset(struct cgfourteen_softc *sc) { cg14_set_depth(sc, 8); + cg14_init_cmap(sc); } /* Enable/disable video display; power down monitor if DPMS-capable */ @@ -736,7 +740,9 @@ cg14_setup_wsdisplay(struct cgfourteen_s WSSCREEN_RESIZE, NULL }; + cg14_set_depth(sc, 8); + sc->sc_screens[0] = &sc->sc_defaultscreen_descr; sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens}; sc->sc_mode = WSDISPLAYIO_MODE_EMUL; @@ -753,45 +759,50 @@ cg14_setup_wsdisplay(struct cgfourteen_s sc->sc_gc.gc_rectfill = cg14_rectfill_a; sc->sc_gc.gc_rop = 0xc; - vcons_init_screen(&sc->sc_vd, &sc->sc_console_screen, 1, - &defattr); + vcons_init_screen(&sc->sc_vd, &sc->sc_console_screen, 1, + &defattr); + + /* clear the screen with the default background colour */ + if (sc->sc_sx != NULL) { + cg14_rectfill(sc, 0, 0, ri->ri_width, ri->ri_height, + ri->ri_devcmap[(defattr >> 16) & 0xf]); + } else { + memset(sc->sc_fb.fb_pixels, + ri->ri_devcmap[(defattr >> 16) & 0xf], + ri->ri_stride * ri->ri_height); + } + 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; + glyphcache_init_align(&sc->sc_gc, sc->sc_fb.fb_type.fb_height + 5, + (sc->sc_vramsize / sc->sc_fb.fb_type.fb_width) - + sc->sc_fb.fb_type.fb_height - 5, + sc->sc_fb.fb_type.fb_width, + ri->ri_font->fontwidth, + ri->ri_font->fontheight, + defattr, 4); - /* clear the screen with the default background colour */ - if (sc->sc_sx != NULL) { - cg14_rectfill(sc, 0, 0, ri->ri_width, ri->ri_height, - ri->ri_devcmap[(defattr >> 16) & 0xf]); - } else { - memset(sc->sc_fb.fb_pixels, - ri->ri_devcmap[(defattr >> 16) & 0xf], - ri->ri_stride * ri->ri_height); - } - 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; - glyphcache_init_align(&sc->sc_gc, sc->sc_fb.fb_type.fb_height + 5, - (sc->sc_vramsize / sc->sc_fb.fb_type.fb_width) - - sc->sc_fb.fb_type.fb_height - 5, - sc->sc_fb.fb_type.fb_width, - ri->ri_font->fontwidth, - ri->ri_font->fontheight, - defattr, 4); if (is_cons) { wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0, defattr); vcons_replay_msgbuf(&sc->sc_console_screen); } - 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, CFARGS_NONE); + + /* + * do this here since any output through firmware calls will mess + * with XLUT settings + */ + cg14_init_cmap(sc); } static void @@ -799,18 +810,74 @@ cg14_init_cmap(struct cgfourteen_softc * { struct rasops_info *ri = &sc->sc_console_screen.scr_ri; int i, j = 0; + uint32_t r, g, b, c; uint8_t cmap[768]; - rasops_get_cmap(ri, cmap, sizeof(cmap)); - - for (i = 0; i < 256; i++) { - - sc->sc_cmap.cm_map[i][3] = cmap[j]; - sc->sc_cmap.cm_map[i][2] = cmap[j + 1]; - sc->sc_cmap.cm_map[i][1] = cmap[j + 2]; - j += 3; + if (sc->sc_depth == 16) { + /* construct an R5G6B5 palette in CLUT1/2 */ + for (i = 0; i < 0x100; i++) { + /* upper byte first */ + r = (i & 0xf8); /* red component */ + r |= r >> 5; /* fill lower bits so 0xf8 */ + c = 0x40000000 | r; /* becomes 0xff */ + g = i & 0x7; /* upper 3 bits of green */ + g |= g << 3; + c |= ((g << 10) & 0xf000); /* make it 4 */ + sc->sc_clut1->clut_lut[i] = c; + /* lower byte */ + g = i & 0xe0; /* lower half of green */ + g |= g >> 3; + c = 0x40000000 | ((g << 4) & 0x0f00); + b = i & 0x1f; /* and blue */ + b = (b << 3) | (b >> 2); + c |= (b << 16); + sc->sc_clut2->clut_lut[i] = c; + } + + /* + * because we alpha blend our components everything is half + * intensity, fix that with the gamma LUT + */ + + sc->sc_dac->dac_mode &= ~6; /* 8bit mode, for simlicity */ + for (i = 0; i < 128; i++) { + sc->sc_dac->dac_addr = i; + sc->sc_dac->dac_gammalut = i << 1; + sc->sc_dac->dac_gammalut = i << 1; + sc->sc_dac->dac_gammalut = i << 1; + } + + /* finally fill the XLUT */ + for (i = 0; i < 256; i++) + sc->sc_xlut->xlut_lut[i] = + CG14_LEFT_CLUT2 | CG14_LEFT_B | + CG14_RIGHT_CLUT1 | CG14_RIGHT_X; + } else { + /* in 8 or 24bit put a linear ramp in the gamma LUT */ + sc->sc_dac->dac_mode &= ~6; /* 8bit mode, for simlicity */ + for (i = 0; i < 256; i++) { + sc->sc_dac->dac_addr = i; + sc->sc_dac->dac_gammalut = i; + sc->sc_dac->dac_gammalut = i; + sc->sc_dac->dac_gammalut = i; + } + + /* and zero the XLUT */ + for (i = 0; i < 256; i++) + sc->sc_xlut->xlut_lut[i] = 0; + + if (sc->sc_depth == 8) { + rasops_get_cmap(ri, cmap, sizeof(cmap)); + + for (i = 0; i < 256; i++) { + sc->sc_cmap.cm_map[i][3] = cmap[j]; + sc->sc_cmap.cm_map[i][2] = cmap[j + 1]; + sc->sc_cmap.cm_map[i][1] = cmap[j + 2]; + j += 3; + } + cg14_load_hwcmap(sc, 0, 256); + } } - cg14_load_hwcmap(sc, 0, 256); } static int @@ -932,6 +999,7 @@ cg14_ioctl(void *v, void *vs, u_long cmd } else { cg14_set_depth(sc, 32); + cg14_init_cmap(sc); } } } @@ -1002,10 +1070,10 @@ cg14_init_screen(void *cookie, struct vc struct cgfourteen_softc *sc = cookie; struct rasops_info *ri = &scr->scr_ri; - ri->ri_depth = 8; + ri->ri_depth = sc->sc_depth; ri->ri_width = sc->sc_fb.fb_type.fb_width; ri->ri_height = sc->sc_fb.fb_type.fb_height; - ri->ri_stride = ri->ri_width; + ri->ri_stride = ri->ri_width * (sc->sc_depth >> 3); ri->ri_flg = RI_CENTER | RI_FULLCLEAR; ri->ri_bits = (char *)sc->sc_fb.fb_pixels; @@ -1038,7 +1106,7 @@ cg14_init_screen(void *cookie, struct vc ri->ri_hw = scr; #if NSX > 0 - if (sc->sc_sx != NULL) { + if ((sc->sc_sx != NULL) && (sc->sc_depth == 8)) { ri->ri_ops.copyrows = cg14_copyrows; ri->ri_ops.copycols = cg14_copycols; ri->ri_ops.eraserows = cg14_eraserows; @@ -1055,7 +1123,6 @@ cg14_init_screen(void *cookie, struct vc static void cg14_set_depth(struct cgfourteen_softc *sc, int depth) { - int i; /* init mask */ if (sc->sc_sx != NULL) { @@ -1090,9 +1157,6 @@ cg14_set_depth(struct cgfourteen_softc * device_xname(sc->sc_dev), depth); return; } - /* everything is CLUT1 */ - for (i = 0; i < CG14_CLUT_SIZE; i++) - sc->sc_xlut->xlut_lut[i] = 0; }