Module Name:    src
Committed By:   rkujawa
Date:           Sun Jul 29 20:31:53 UTC 2012

Modified Files:
        src/sys/dev/pci: tdvfb.c tdvfbvar.h

Log Message:
Add wsdisplay ioctls and support for mmap'ing of linear frame buffer.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/pci/tdvfb.c
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/pci/tdvfbvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/tdvfb.c
diff -u src/sys/dev/pci/tdvfb.c:1.3 src/sys/dev/pci/tdvfb.c:1.4
--- src/sys/dev/pci/tdvfb.c:1.3	Fri Jul 20 21:31:28 2012
+++ src/sys/dev/pci/tdvfb.c	Sun Jul 29 20:31:53 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: tdvfb.c,v 1.3 2012/07/20 21:31:28 rkujawa Exp $	*/
+/*	$NetBSD: tdvfb.c,v 1.4 2012/07/29 20:31:53 rkujawa Exp $	*/
 
 /*
  * Copyright (c) 2012 The NetBSD Foundation, Inc.   
@@ -38,10 +38,18 @@
  *
  * This driver currently only support boards with ICS GENDAC (which seems to
  * be most popular, however at least two different DACs were used with CVG).
+ *
+ * TODO (in no particular order):
+ * - Finally fix 16-bit depth handling on big-endian machines.
+ * - Expose card to userspace through /dev/3dfx compatible device file
+ *   (for Glide).
+ * - Allow mmap'ing of registers through wscons access op.
+ * - Complete wscons emul ops acceleration support.
+ * - Add support for others DACs (need hardware).
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tdvfb.c,v 1.3 2012/07/20 21:31:28 rkujawa Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tdvfb.c,v 1.4 2012/07/29 20:31:53 rkujawa Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -58,6 +66,7 @@ __KERNEL_RCSID(0, "$NetBSD: tdvfb.c,v 1.
 #include <dev/pci/tdvfbvar.h>
 
 #include <dev/videomode/videomode.h>
+#include <dev/pci/wsdisplay_pci.h>
 
 #include "opt_wsemul.h"
 #include "opt_tdvfb.h"
@@ -93,6 +102,9 @@ static void	tdvfb_gendac_set_cvg_timing(
 static void	tdvfb_gendac_set_vid_timing(struct tdvfb_softc *sc, 
 		    struct tdvfb_dac_timing *timing);
 
+static paddr_t	tdvfb_mmap(void *v, void *vs, off_t offset, int prot);
+static int	tdvfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
+		    struct lwp *l);
 static void	tdvfb_init_screen(void *cookie, struct vcons_screen *scr, 
 		    int existing, long *defattr);
 static void	tdvfb_init_palette(struct tdvfb_softc *sc);
@@ -109,6 +121,17 @@ static void	tdvfb_copyrows(void *cookie,
 CFATTACH_DECL_NEW(tdvfb, sizeof(struct tdvfb_softc),
     tdvfb_match, tdvfb_attach, NULL, NULL);
 
+struct wsdisplay_accessops tdvfb_accessops = {
+	tdvfb_ioctl,
+	tdvfb_mmap,
+	NULL,	/* alloc_screen */
+	NULL,	/* free_screen */
+	NULL,	/* show_screen */
+	NULL, 	/* load_font */
+	NULL,	/* pollc */
+	NULL	/* scroll */
+};
+
 static int
 tdvfb_match(device_t parent, cfdata_t match, void *aux)
 {
@@ -172,7 +195,7 @@ tdvfb_attach(device_t parent, device_t s
 	}
 
 	aprint_normal_dev(sc->sc_dev, "registers at 0x%08x, fb at 0x%08x\n", 
-	    sc->sc_cvg_pa, sc->sc_cvg_pa + TDV_OFF_FB);
+	    (uint32_t) sc->sc_cvg_pa, (uint32_t) sc->sc_cvg_pa + TDV_OFF_FB);
 
 	/* Do the low level setup. */
 	if (!tdvfb_init(sc)) {
@@ -186,13 +209,23 @@ tdvfb_attach(device_t parent, device_t s
 	 */
 	sc->sc_memsize = tdvfb_mem_size(sc);
 
+	aprint_normal_dev(sc->sc_dev, "%d MB framebuffer memory present\n", 
+	    sc->sc_memsize / 1024 / 1024);
+
 	/* Select video mode, 800x600 32bpp 60Hz by default... */
 	sc->sc_width = 800;
 	sc->sc_height = 600;
+#if BYTE_ORDER == BIG_ENDIAN
 	sc->sc_bpp = 32;	/* XXX: 16 would allow blitter use. */
+#else
+	sc->sc_bpp = 16;
+#endif 
 	sc->sc_linebytes = 1024 * (sc->sc_bpp / 8);
 	sc->sc_videomode = pick_mode_by_ref(sc->sc_width, sc->sc_height, 60);
 
+	aprint_normal_dev(sc->sc_dev, "setting %dx%d %d bpp resolution\n",
+	    sc->sc_width, sc->sc_height, sc->sc_bpp);
+
 	tdvfb_videomode_set(sc);
 
 	sc->sc_defaultscreen_descr = (struct wsscreen_descr){
@@ -208,7 +241,7 @@ tdvfb_attach(device_t parent, device_t s
 	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
 	
 	vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr,
-	    &sc->sc_accessops);
+	    &tdvfb_accessops);
 	sc->vd.init_screen = tdvfb_init_screen;
 
 	ri = &sc->sc_console_screen.scr_ri;
@@ -238,7 +271,7 @@ tdvfb_attach(device_t parent, device_t s
 
 	ws_aa.console = console;
 	ws_aa.scrdata = &sc->sc_screenlist;
-	ws_aa.accessops = &sc->sc_accessops;
+	ws_aa.accessops = &tdvfb_accessops;
 	ws_aa.accesscookie = &sc->vd;
 	
 	config_found(sc->sc_dev, &ws_aa, wsemuldisplaydevprint);
@@ -889,3 +922,77 @@ tdvfb_eraserows(void *cookie, int row, i
 	}
 }
 
+static int
+tdvfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
+{
+	struct vcons_data *vd;
+	struct tdvfb_softc *sc;
+	struct wsdisplay_fbinfo *wsfbi;
+	struct vcons_screen *ms;
+
+	vd = v;
+	sc = vd->cookie;
+	ms = vd->active;
+
+	switch (cmd) {
+	case WSDISPLAYIO_GTYPE:
+		*(u_int *)data = WSDISPLAY_TYPE_PCIMISC;
+		return 0;
+
+	case PCI_IOC_CFGREAD:
+	case PCI_IOC_CFGWRITE:
+		return pci_devioctl(sc->sc_pc, sc->sc_pcitag,
+		    cmd, data, flag, l);
+
+	case WSDISPLAYIO_GET_BUSID:
+		return wsdisplayio_busid_pci(sc->sc_dev, sc->sc_pc,
+		    sc->sc_pcitag, data);
+
+	case WSDISPLAYIO_GINFO:
+		if (ms == NULL)
+			return ENODEV;
+
+		wsfbi = (void*) data;
+		wsfbi->height = ms->scr_ri.ri_height;
+		wsfbi->width = ms->scr_ri.ri_width;
+		wsfbi->depth = ms->scr_ri.ri_depth;	
+		wsfbi->cmsize = 256;
+		return 0;
+
+	case WSDISPLAYIO_LINEBYTES:
+		*(u_int*)data = sc->sc_linebytes;
+		return 0;
+	
+	case WSDISPLAYIO_SMODE: 
+		{
+			int new_mode = *(int*)data;
+			if (new_mode != sc->sc_mode) {
+				sc->sc_mode = new_mode;
+				if(new_mode == WSDISPLAYIO_MODE_EMUL) 
+					vcons_redraw_screen(ms);
+			}		
+			return 0;
+		}
+	}	
+	return EPASSTHROUGH;	
+}
+
+static paddr_t
+tdvfb_mmap(void *v, void *vs, off_t offset, int prot)
+{
+	struct vcons_data *vd;
+	struct tdvfb_softc *sc;
+	paddr_t pa;
+
+	vd = v;
+	sc = vd->cookie;
+
+	if (offset < sc->sc_memsize) {
+		pa = bus_space_mmap(sc->sc_cvgt, sc->sc_fbh + offset, 0, prot,
+		    BUS_SPACE_MAP_LINEAR);
+		return pa;
+	}
+
+	return -1;
+}
+

Index: src/sys/dev/pci/tdvfbvar.h
diff -u src/sys/dev/pci/tdvfbvar.h:1.2 src/sys/dev/pci/tdvfbvar.h:1.3
--- src/sys/dev/pci/tdvfbvar.h:1.2	Fri Jul 20 12:03:32 2012
+++ src/sys/dev/pci/tdvfbvar.h	Sun Jul 29 20:31:53 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: tdvfbvar.h,v 1.2 2012/07/20 12:03:32 rkujawa Exp $	*/
+/*	$NetBSD: tdvfbvar.h,v 1.3 2012/07/29 20:31:53 rkujawa Exp $	*/
 
 /*
  * Copyright (c) 2012 The NetBSD Foundation, Inc. 
@@ -77,7 +77,6 @@ struct tdvfb_softc {
 	struct wsscreen_descr sc_defaultscreen_descr;
 	const struct wsscreen_descr *sc_screens[1];
 	struct wsscreen_list sc_screenlist;
-	struct wsdisplay_accessops sc_accessops;
 
 	u_char sc_cmap_red[256];
 	u_char sc_cmap_green[256];

Reply via email to