From d6049d4b87a15cd3254ec9af8fc50b29056ad912 Mon Sep 17 00:00:00 2001 From: aoyama Date: Wed, 15 Jan 2014 11:13:53 +0000 Subject: [PATCH] Add WSDISPLAYIO_SETGFXMODE ioctl on LUNA's frame buffer. This ioctl changes `pseudo' frame buffer depth, in order to use color wscons and monochrome X server both. Also need to some luna88k-specific initialization in xenocara/driver/xf86-video-wsfb/src/wsfb_driver.c. --- sys/arch/luna88k/dev/lunafb.c | 213 ++++++++++++++++++++++++---------- 1 file changed, 150 insertions(+), 63 deletions(-) diff --git a/sys/arch/luna88k/dev/lunafb.c b/sys/arch/luna88k/dev/lunafb.c index 18b4f290171..a0f594e60e6 100644 --- a/sys/arch/luna88k/dev/lunafb.c +++ b/sys/arch/luna88k/dev/lunafb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lunafb.c,v 1.20 2014/01/03 13:48:25 aoyama Exp $ */ +/* $OpenBSD: lunafb.c,v 1.21 2014/01/15 11:13:53 aoyama Exp $ */ /* $NetBSD: lunafb.c,v 1.7.6.1 2002/08/07 01:48:34 lukem Exp $ */ /*- @@ -159,6 +159,10 @@ int omfb_show_screen(void *, void *, int, void (*) (void *, int, int), void *); int omfb_load_font(void *, void *, struct wsdisplay_font *); int omfb_list_font(void *, struct wsdisplay_font *); +int omfb_set_gfxmode(struct omfb_softc *, struct wsdisplay_gfx_mode *); + +void omfb_set_default_cmap(struct om_hwdevconfig *); +void omfb_clear_framebuffer(struct om_hwdevconfig *); const struct wsdisplay_accessops omfb_accessops = { .ioctl = omfbioctl, @@ -279,6 +283,9 @@ omfbioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) *(u_int *)data = WSDISPLAYIO_DEPTH_1; break; + case WSDISPLAYIO_SETGFXMODE: + return omfb_set_gfxmode(sc, (struct wsdisplay_gfx_mode *)data); + case WSDISPLAYIO_SVIDEO: case WSDISPLAYIO_GVIDEO: break; @@ -404,7 +411,6 @@ omsetcmap(struct omfb_softc *sc, struct wsdisplay_cmap *p) void omfb_getdevconfig(paddr_t paddr, struct om_hwdevconfig *dc) { - int bpp, i; struct rasops_info *ri; union { struct { short h, v; } p; @@ -434,67 +440,15 @@ omfb_getdevconfig(paddr_t paddr, struct om_hwdevconfig *dc) dc->dc_depth_checked = 1; } -#if 1 /* XXX: Xorg mono server works only bpp == 1 for now */ - switch (hwplanebits) { - case 8: - bpp = 8; - break; - default: - case 4: - bpp = 4; - break; - case 1: - bpp = 1; - break; - } -#else - bpp = 1; -#endif dc->dc_wid = 1280; dc->dc_ht = 1024; - dc->dc_depth = bpp; + dc->dc_depth = hwplanebits; dc->dc_rowbytes = 2048 / 8; - dc->dc_cmsize = (bpp == 1) ? 0 : 1 << bpp; + dc->dc_cmsize = (hwplanebits == 1) ? 0 : 1 << hwplanebits; dc->dc_videobase = paddr; - /* WHITE on BLACK */ - if ((hwplanebits == 1) || (hwplanebits == 4)) { - struct bt454 *odac = (struct bt454 *)OMFB_RAMDAC; - - odac->bt_addr = 0; - for (i = 0; i < 16; i++) { - odac->bt_cmap = dc->dc_cmap.r[i] = ansicmap[i].r; - odac->bt_cmap = dc->dc_cmap.g[i] = ansicmap[i].g; - odac->bt_cmap = dc->dc_cmap.b[i] = ansicmap[i].b; - } - } else if (hwplanebits == 8) { - struct bt458 *ndac = (struct bt458 *)OMFB_RAMDAC; - - /* - * Initialize the Bt458. When we write to control registers, - * the address is not incremented automatically. So we specify - * it ourselves for each control register. - */ - ndac->bt_addr = 0x04; - ndac->bt_ctrl = 0xff; /* all planes will be read */ - ndac->bt_addr = 0x05; - ndac->bt_ctrl = 0x00; /* all planes have non-blink */ - ndac->bt_addr = 0x06; - ndac->bt_ctrl = 0x40; /* palette enabled, ovly plane disabled */ - ndac->bt_addr = 0x07; - ndac->bt_ctrl = 0x00; /* no test mode */ - - /* - * Set ANSI 16 colors. We only supports 4bpp console right - * now, repeat 16 colors in 256 colormap. - */ - ndac->bt_addr = 0; - for (i = 0; i < 256; i++) { - ndac->bt_cmap = dc->dc_cmap.r[i] = ansicmap[i % 16].r; - ndac->bt_cmap = dc->dc_cmap.g[i] = ansicmap[i % 16].g; - ndac->bt_cmap = dc->dc_cmap.b[i] = ansicmap[i % 16].b; - } - } + /* set default colormap */ + omfb_set_default_cmap(dc); /* adjust h/v origin on screen */ rfcnt.p.h = 7; @@ -503,11 +457,7 @@ omfb_getdevconfig(paddr_t paddr, struct om_hwdevconfig *dc) *(volatile u_int32_t *)OMFB_RFCNT = rfcnt.u; /* clear the screen */ - *(volatile u_int32_t *)OMFB_PLANEMASK = 0xff; - ((volatile u_int32_t *)OMFB_ROPFUNC)[5] = ~0; /* ROP copy */ - for (i = 0; i < dc->dc_ht * dc->dc_rowbytes / sizeof(u_int32_t); i++) - *((volatile u_int32_t *)dc->dc_videobase + i) = 0; - *(volatile u_int32_t *)OMFB_PLANEMASK = 0x01; + omfb_clear_framebuffer(dc); /* initialize the raster */ ri = &dc->dc_ri; @@ -589,3 +539,140 @@ omfb_list_font(void *v, struct wsdisplay_font *font) return rasops_list_font(ri, font); } + +/* + * Change `pseudo' depth, set the default colormap, and clear frame buffer. + * Note: when called with depth == 0, change to the original hardware depth. + */ +int +omfb_set_gfxmode(struct omfb_softc *sc, struct wsdisplay_gfx_mode *wsd_gfxmode) +{ + /* LUNA's fb is fixed size */ + if ((wsd_gfxmode->width != sc->sc_dc->dc_wid) + || (wsd_gfxmode->height != sc->sc_dc->dc_ht)) + return -1; + + /* if depth == 0, set the original hardware depth */ + if (wsd_gfxmode->depth == 0) + wsd_gfxmode->depth = hwplanebits; + + switch (wsd_gfxmode->depth) { + case 1: + /* all frame buffer support this */ + sc->sc_dc->dc_depth = 1; + sc->sc_dc->dc_cmsize = 0; + break; + case 4: + if ((hwplanebits == 4) || (hwplanebits == 8)) { + sc->sc_dc->dc_depth = 4; + sc->sc_dc->dc_cmsize = 16; + break; + } else + return -1; + case 8: + if (hwplanebits == 8) { + sc->sc_dc->dc_depth = 8; + sc->sc_dc->dc_cmsize = 256; + break; + } else + return -1; + default: + return -1; + } + + omfb_set_default_cmap(sc->sc_dc); + omfb_clear_framebuffer(sc->sc_dc); + + return 0; +} + +/* + * Clear all planes of frame buffer + */ +void +omfb_clear_framebuffer(struct om_hwdevconfig *dc) +{ + int i; + + *(volatile u_int32_t *)OMFB_PLANEMASK = 0xff; /* all planes */ + ((volatile u_int32_t *)OMFB_ROPFUNC)[5] = ~0; /* ROP copy */ + for (i = 0; i < dc->dc_ht * dc->dc_rowbytes / sizeof(u_int32_t); i++) + *((volatile u_int32_t *)dc->dc_videobase + i) = 0; + *(volatile u_int32_t *)OMFB_PLANEMASK = 0x01; /* plane #0 only */ +} + +/* + * set default colormap; white on black for 1bpp, ANSI 16 colors for 4/8 bpp. + */ +void +omfb_set_default_cmap(struct om_hwdevconfig *dc) +{ + int i; + + if ((hwplanebits == 1) || (hwplanebits == 4)) { + struct bt454 *odac = (struct bt454 *)OMFB_RAMDAC; + + odac->bt_addr = 0; + if (dc->dc_depth == 1) { + /* white on black */ + for (i = 0; i < 16; i++) { + u_int8_t val = i % 2 ? 255 : 0; + + odac->bt_cmap = dc->dc_cmap.r[i] = val; + odac->bt_cmap = dc->dc_cmap.g[i] = val; + odac->bt_cmap = dc->dc_cmap.b[i] = val; + } + } else { + for (i = 0; i < 16; i++) { + /* ANSI 16 colors */ + odac->bt_cmap = dc->dc_cmap.r[i] + = ansicmap[i].r; + odac->bt_cmap = dc->dc_cmap.g[i] + = ansicmap[i].g; + odac->bt_cmap = dc->dc_cmap.b[i] + = ansicmap[i].b; + } + } + } else if (hwplanebits == 8) { + struct bt458 *ndac = (struct bt458 *)OMFB_RAMDAC; + + /* + * Initialize the Bt458. When we write to control registers, + * the address is not incremented automatically. So we specify + * it ourselves for each control register. + */ + ndac->bt_addr = 0x04; + ndac->bt_ctrl = 0xff; /* all planes will be read */ + ndac->bt_addr = 0x05; + ndac->bt_ctrl = 0x00; /* all planes have non-blink */ + ndac->bt_addr = 0x06; + ndac->bt_ctrl = 0x40; /* palette enabled, ovly plane disabled */ + ndac->bt_addr = 0x07; + ndac->bt_ctrl = 0x00; /* no test mode */ + + ndac->bt_addr = 0; + if (dc->dc_depth == 1) { + /* white on black */ + for (i = 0; i < 256; i++) { + u_int8_t val = i % 2 ? 255 : 0; + + ndac->bt_cmap = dc->dc_cmap.r[i] = val; + ndac->bt_cmap = dc->dc_cmap.g[i] = val; + ndac->bt_cmap = dc->dc_cmap.b[i] = val; + } + } else { + /* + * Set ANSI 16 colors. We only supports 4bpp console + * right now, repeat 16 colors in 256 colormap. + */ + for (i = 0; i < 256; i++) { + ndac->bt_cmap = dc->dc_cmap.r[i] + = ansicmap[i % 16].r; + ndac->bt_cmap = dc->dc_cmap.g[i] + = ansicmap[i % 16].g; + ndac->bt_cmap = dc->dc_cmap.b[i] + = ansicmap[i % 16].b; + } + } + } +} -- 2.20.1