Module Name:    src
Committed By:   tsutsui
Date:           Fri Jul 25 16:40:13 UTC 2014

Modified Files:
        src/sys/arch/luna68k/dev: lunafb.c

Log Message:
Implement WSDISPLAYIO_SMODE ioctl for proper mmap and colormap handling.

- allow mmap framebuffer memories only in WSDISPLAYIO_DUMBFB
- initialize palette for ANSI text colors on back to WSDISPLAYIO_MODE_EMUL

Tested on LUNA with 4bpp framebuffer.


To generate a diff of this commit:
cvs rdiff -u -r1.34 -r1.35 src/sys/arch/luna68k/dev/lunafb.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/luna68k/dev/lunafb.c
diff -u src/sys/arch/luna68k/dev/lunafb.c:1.34 src/sys/arch/luna68k/dev/lunafb.c:1.35
--- src/sys/arch/luna68k/dev/lunafb.c:1.34	Thu Jul 24 14:09:09 2014
+++ src/sys/arch/luna68k/dev/lunafb.c	Fri Jul 25 16:40:12 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: lunafb.c,v 1.34 2014/07/24 14:09:09 tsutsui Exp $ */
+/* $NetBSD: lunafb.c,v 1.35 2014/07/25 16:40:12 tsutsui Exp $ */
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: lunafb.c,v 1.34 2014/07/24 14:09:09 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lunafb.c,v 1.35 2014/07/25 16:40:12 tsutsui Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -127,12 +127,14 @@ struct omfb_softc {
 	device_t sc_dev;		/* base device */
 	struct om_hwdevconfig *sc_dc;	/* device configuration */
 	int sc_nscreens;
+	int sc_mode;
 };
 
 static int  omgetcmap(struct omfb_softc *, struct wsdisplay_cmap *);
 static int  omsetcmap(struct omfb_softc *, struct wsdisplay_cmap *);
 
 static struct om_hwdevconfig omfb_console_dc;
+static void omfb_resetcmap(struct om_hwdevconfig *);
 static void omfb_getdevconfig(paddr_t, struct om_hwdevconfig *);
 
 static struct wsscreen_descr omfb_stdscreen = {
@@ -213,6 +215,7 @@ omfbattach(device_t parent, device_t sel
 	aprint_normal(": %d x %d, %dbpp\n", sc->sc_dc->dc_wid, sc->sc_dc->dc_ht,
 	    sc->sc_dc->dc_depth);
 
+	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
 	waa.console = omfb_console;
 	waa.scrdata = &omfb_screenlist;
 	waa.accessops = &omfb_accessops;
@@ -240,6 +243,7 @@ omfbioctl(void *v, void *vs, u_long cmd,
 {
 	struct omfb_softc *sc = v;
 	struct om_hwdevconfig *dc = sc->sc_dc;
+	int new_mode;
 
 	switch (cmd) {
 	case WSDISPLAYIO_GTYPE:
@@ -265,6 +269,15 @@ omfbioctl(void *v, void *vs, u_long cmd,
 	case WSDISPLAYIO_PUTCMAP:
 		return omsetcmap(sc, (struct wsdisplay_cmap *)data);
 
+	case WSDISPLAYIO_SMODE:
+		new_mode = *(int *)data;
+		if (new_mode != sc->sc_mode) {
+			sc->sc_mode = new_mode;
+			if (new_mode == WSDISPLAYIO_MODE_EMUL)
+				omfb_resetcmap(dc);
+		}
+		return 0;
+
 	case WSDISPLAYIO_SVIDEO:
 	case WSDISPLAYIO_GVIDEO:
 	case WSDISPLAYIO_GCURPOS:
@@ -288,13 +301,21 @@ omfbmmap(void *v, void *vs, off_t offset
 	struct om_hwdevconfig *dc = sc->sc_dc;
 	paddr_t cookie = -1;
 
-#if 0	/* XXX: quick workaround to make X.Org mono server work */
-	if (offset >= 0 && offset < OMFB_SIZE)
-		cookie = m68k_btop(m68k_trunc_page(dc->dc_videobase) + offset);
-#else
-	if (offset >= 0 && offset < dc->dc_rowbytes * dc->dc_ht * dc->dc_depth)
-		cookie = m68k_btop(m68k_trunc_page(OMFB_FB_RADDR) + offset);
+	switch (sc->sc_mode) {
+#if 0
+	case WSDISPLAYIO_MODE_MAPPED:
+		if (offset >= 0 && offset < OMFB_SIZE)
+			cookie = m68k_btop(m68k_trunc_page(dc->dc_videobase) +
+			    offset);
+		break;
 #endif
+	case WSDISPLAYIO_MODE_DUMBFB:
+		if (offset >= 0 &&
+		    offset < dc->dc_rowbytes * dc->dc_ht * dc->dc_depth)
+			cookie = m68k_btop(m68k_trunc_page(OMFB_FB_RADDR) +
+			    offset);
+		break;
+	}
 
 	return cookie;
 }
@@ -364,35 +385,10 @@ omsetcmap(struct omfb_softc *sc, struct 
 }
 
 static void
-omfb_getdevconfig(paddr_t paddr, struct om_hwdevconfig *dc)
+omfb_resetcmap(struct om_hwdevconfig *dc)
 {
-	int bpp, i;
-	struct rasops_info *ri;
-	union {
-		struct { short h, v; } p;
-		uint32_t u;
-	} rfcnt;
-
-	switch (hwplanemask) {
-	case 0xff:
-		bpp = 8;	/* XXX check monochrome bit in DIPSW */
-		break;
-	default:
-	case 0x0f:
-		bpp = 4;	/* XXX check monochrome bit in DIPSW */
-		break;
-	case 1:
-		bpp = 1;
-		break;
-	}
-	dc->dc_wid = 1280;
-	dc->dc_ht = 1024;
-	dc->dc_depth = bpp;
-	dc->dc_rowbytes = 2048 / 8;
-	dc->dc_cmsize = (bpp == 1) ? 0 : 1 << bpp;
-	dc->dc_videobase = paddr;
+	int i;
 
-	/* WHITE on BLACK */
 	if (hwplanemask == 0x01) {
 		struct bt454 *odac = (struct bt454 *)OMFB_RAMDAC;
 
@@ -451,6 +447,38 @@ omfb_getdevconfig(paddr_t paddr, struct 
 			ndac->bt_cmap = dc->dc_cmap.b[i] = ansicmap[i % 16].b;
 		}
 	}
+}
+
+static void
+omfb_getdevconfig(paddr_t paddr, struct om_hwdevconfig *dc)
+{
+	int bpp, i;
+	struct rasops_info *ri;
+	union {
+		struct { short h, v; } p;
+		uint32_t u;
+	} rfcnt;
+
+	switch (hwplanemask) {
+	case 0xff:
+		bpp = 8;	/* XXX check monochrome bit in DIPSW */
+		break;
+	default:
+	case 0x0f:
+		bpp = 4;	/* XXX check monochrome bit in DIPSW */
+		break;
+	case 1:
+		bpp = 1;
+		break;
+	}
+	dc->dc_wid = 1280;
+	dc->dc_ht = 1024;
+	dc->dc_depth = bpp;
+	dc->dc_rowbytes = 2048 / 8;
+	dc->dc_cmsize = (bpp == 1) ? 0 : 1 << bpp;
+	dc->dc_videobase = paddr;
+
+	omfb_resetcmap(dc);
 
 	/* adjust h/v origin on screen */
 	rfcnt.p.h = 7;

Reply via email to