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;
}