-/* $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 $ */
/*-
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,
*(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;
void
omfb_getdevconfig(paddr_t paddr, struct om_hwdevconfig *dc)
{
- int bpp, i;
struct rasops_info *ri;
union {
struct { short h, v; } p;
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;
*(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;
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;
+ }
+ }
+ }
+}