Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Make ffb take part in the /dev/fbN circus.



details:   https://anonhg.NetBSD.org/src/rev/7c9f66776517
branches:  trunk
changeset: 580698:7c9f66776517
user:      martin <martin%NetBSD.org@localhost>
date:      Wed May 04 14:38:44 2005 +0000

description:
Make ffb take part in the /dev/fbN circus.

diffstat:

 sys/arch/sparc64/dev/ffb.c         |  210 ++++++++++++++++++++++++++++++++----
 sys/arch/sparc64/dev/ffb_mainbus.c |    9 +-
 sys/arch/sparc64/dev/ffbvar.h      |    4 +-
 sys/dev/sun/fbio.h                 |    5 +-
 4 files changed, 192 insertions(+), 36 deletions(-)

diffs (truncated from 379 to 300 lines):

diff -r 2dbbd11acb5b -r 7c9f66776517 sys/arch/sparc64/dev/ffb.c
--- a/sys/arch/sparc64/dev/ffb.c        Wed May 04 10:54:51 2005 +0000
+++ b/sys/arch/sparc64/dev/ffb.c        Wed May 04 14:38:44 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ffb.c,v 1.10 2005/05/04 06:38:06 martin Exp $  */
+/*     $NetBSD: ffb.c,v 1.11 2005/05/04 14:38:44 martin Exp $  */
 /*     $OpenBSD: creator.c,v 1.20 2002/07/30 19:48:15 jason Exp $      */
 
 /*
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffb.c,v 1.10 2005/05/04 06:38:06 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffb.c,v 1.11 2005/05/04 14:38:44 martin Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -45,15 +45,17 @@
 #include <machine/bus.h>
 #include <machine/autoconf.h>
 #include <machine/openfirm.h>
+#include <machine/vmparam.h>
 
 #include <dev/wscons/wsconsio.h>
-#include <dev/wscons/wsdisplayvar.h>
-#include <dev/wscons/wscons_raster.h>
-#include <dev/rasops/rasops.h>
+#include <dev/sun/fbio.h>
+#include <dev/sun/fbvar.h>
 
 #include <sparc64/dev/ffbreg.h>
 #include <sparc64/dev/ffbvar.h>
 
+extern struct cfdriver ffb_cd;
+
 struct wsscreen_descr ffb_stdscreen = {
        "sunffb",
        0, 0,   /* will be filled in -- XXX shouldn't, it's global. */
@@ -90,6 +92,17 @@
 void   ffb_ras_fill(struct ffb_softc *);
 void   ffb_ras_setfg(struct ffb_softc *, int32_t);
 
+/* frame buffer generic driver */   
+static void ffbfb_unblank(struct device*);
+dev_type_open(ffbfb_open);
+dev_type_close(ffbfb_close);
+dev_type_ioctl(ffbfb_ioctl);
+dev_type_mmap(ffbfb_mmap);
+static struct fbdriver ffb_fbdriver = {
+        ffbfb_unblank, ffbfb_open, ffbfb_close, ffbfb_ioctl, nopoll,
+       ffbfb_mmap, nokqfilter
+};
+
 struct wsdisplay_accessops ffb_accessops = {
        ffb_ioctl,
        ffb_mmap,
@@ -133,15 +146,15 @@
        sc->sc_height = prom_getpropint(sc->sc_node, "height", 0);
        sc->sc_width = prom_getpropint(sc->sc_node, "width", 0);
 
-       sc->sc_rasops.ri_depth = 32;
-       sc->sc_rasops.ri_stride = sc->sc_linebytes;
-       sc->sc_rasops.ri_flg = RI_CENTER;
-       sc->sc_rasops.ri_bits = (void *)bus_space_vaddr(sc->sc_bt,
+       sc->sc_fb.fb_rinfo.ri_depth = 32;
+       sc->sc_fb.fb_rinfo.ri_stride = sc->sc_linebytes;
+       sc->sc_fb.fb_rinfo.ri_flg = RI_CENTER;
+       sc->sc_fb.fb_rinfo.ri_bits = (void *)bus_space_vaddr(sc->sc_bt,
            sc->sc_pixel_h);
 
-       sc->sc_rasops.ri_width = sc->sc_width;
-       sc->sc_rasops.ri_height = sc->sc_height;
-       sc->sc_rasops.ri_hw = sc;
+       sc->sc_fb.fb_rinfo.ri_width = sc->sc_width;
+       sc->sc_fb.fb_rinfo.ri_height = sc->sc_height;
+       sc->sc_fb.fb_rinfo.ri_hw = sc;
 
        maxcol = (prom_getoption("screen-#columns", buf, sizeof buf) == 0)
                ? strtoul(buf, NULL, 10)
@@ -151,19 +164,19 @@
                ? strtoul(buf, NULL, 10)
                : 34;
 
-       rasops_init(&sc->sc_rasops, maxrow, maxcol);
+       rasops_init(&sc->sc_fb.fb_rinfo, maxrow, maxcol);
 
        if ((sc->sc_dv.dv_cfdata->cf_flags & FFB_CFFLAG_NOACCEL) == 0) {
-               sc->sc_rasops.ri_hw = sc;
-               sc->sc_rasops.ri_ops.eraserows = ffb_ras_eraserows;
-               sc->sc_rasops.ri_ops.erasecols = ffb_ras_erasecols;
-               sc->sc_rasops.ri_ops.copyrows = ffb_ras_copyrows;
+               sc->sc_fb.fb_rinfo.ri_hw = sc;
+               sc->sc_fb.fb_rinfo.ri_ops.eraserows = ffb_ras_eraserows;
+               sc->sc_fb.fb_rinfo.ri_ops.erasecols = ffb_ras_erasecols;
+               sc->sc_fb.fb_rinfo.ri_ops.copyrows = ffb_ras_copyrows;
                ffb_ras_init(sc);
        }
 
-       ffb_stdscreen.nrows = sc->sc_rasops.ri_rows;
-       ffb_stdscreen.ncols = sc->sc_rasops.ri_cols;
-       ffb_stdscreen.textops = &sc->sc_rasops.ri_ops;
+       ffb_stdscreen.nrows = sc->sc_fb.fb_rinfo.ri_rows;
+       ffb_stdscreen.ncols = sc->sc_fb.fb_rinfo.ri_cols;
+       ffb_stdscreen.textops = &sc->sc_fb.fb_rinfo.ri_ops;
 
        /* collect DAC version, as Elite3D cursor enable bit is reversed */
        DAC_WRITE(sc, FFB_DAC_TYPE, FFB_DAC_GVERS);
@@ -175,6 +188,13 @@
 
        ffb_blank(sc, WSDISPLAYIO_SVIDEO, &blank);
 
+       sc->sc_fb.fb_driver = &ffb_fbdriver;
+       sc->sc_fb.fb_type.fb_cmsize = 0;
+       sc->sc_fb.fb_type.fb_size = maxrow * sc->sc_linebytes;
+       sc->sc_fb.fb_type.fb_type = FBTYPE_CREATOR;
+       sc->sc_fb.fb_device = &sc->sc_dv;
+       fb_attach(&sc->sc_fb, sc->sc_console);
+
        if (sc->sc_console) {
                int *ccolp, *crowp;
                long defattr;
@@ -182,15 +202,15 @@
                if (romgetcursoraddr(&crowp, &ccolp))
                        ccolp = crowp = NULL;
                if (ccolp != NULL)
-                       sc->sc_rasops.ri_ccol = *ccolp;
+                       sc->sc_fb.fb_rinfo.ri_ccol = *ccolp;
                if (crowp != NULL)
-                       sc->sc_rasops.ri_crow = *crowp;
+                       sc->sc_fb.fb_rinfo.ri_crow = *crowp;
 
-               sc->sc_rasops.ri_ops.allocattr(&sc->sc_rasops,
+               sc->sc_fb.fb_rinfo.ri_ops.allocattr(&sc->sc_fb.fb_rinfo,
                    0, 0, 0, &defattr);
 
-               wsdisplay_cnattach(&ffb_stdscreen, &sc->sc_rasops,
-                   sc->sc_rasops.ri_ccol, sc->sc_rasops.ri_crow, defattr);
+               wsdisplay_cnattach(&ffb_stdscreen, &sc->sc_fb.fb_rinfo,
+                   sc->sc_fb.fb_rinfo.ri_ccol, sc->sc_fb.fb_rinfo.ri_crow, defattr);
        }
 
        waa.console = sc->sc_console;
@@ -214,6 +234,48 @@
 #endif
 
        switch (cmd) {
+       case FBIOGTYPE:
+               *(struct fbtype *)data = sc->sc_fb.fb_type;
+               break;
+       case FBIOGATTR:
+#define fba ((struct fbgattr *)data)
+               fba->real_type = sc->sc_fb.fb_type.fb_type;
+               fba->owner = 0;         /* XXX ??? */
+               fba->fbtype = sc->sc_fb.fb_type;
+               fba->sattr.flags = 0;
+               fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type;
+               fba->sattr.dev_specific[0] = -1;
+               fba->emu_types[0] = sc->sc_fb.fb_type.fb_type;
+               fba->emu_types[1] = -1;
+#undef fba
+               break; 
+
+       case FBIOGETCMAP:
+       case FBIOPUTCMAP:
+               return EIO;
+
+       case FBIOGVIDEO:
+       case FBIOSVIDEO:
+               return ffb_blank(sc, cmd == FBIOGVIDEO?
+                   WSDISPLAYIO_GVIDEO : WSDISPLAYIO_SVIDEO,
+                   (u_int *)data);
+               break;
+       case FBIOGCURSOR:
+               printf("%s: FBIOGCURSOR not implemented\n", sc->sc_dv.dv_xname);
+               return EIO;
+       case FBIOSCURSOR:
+               printf("%s: FBIOSCURSOR not implemented\n", sc->sc_dv.dv_xname);
+               return EIO;
+       case FBIOGCURPOS:
+               printf("%s: FBIOGCURPOS not implemented\n", sc->sc_dv.dv_xname);
+               return EIO;
+       case FBIOSCURPOS:
+               printf("%s: FBIOSCURPOS not implemented\n", sc->sc_dv.dv_xname);
+               return EIO;
+       case FBIOGCURMAX:
+               printf("%s: FBIOGCURMAX not implemented\n", sc->sc_dv.dv_xname);
+               return EIO;
+
        case WSDISPLAYIO_GTYPE:
                *(u_int *)data = WSDISPLAY_TYPE_SUNFFB;
                break;
@@ -264,11 +326,11 @@
        if (sc->sc_nscreens > 0)
                return (ENOMEM);
 
-       *cookiep = &sc->sc_rasops;
+       *cookiep = &sc->sc_fb.fb_rinfo;
        *curyp = 0;
        *curxp = 0;
 
-       sc->sc_rasops.ri_ops.allocattr(&sc->sc_rasops, 0, 0, 0, attrp);
+       sc->sc_fb.fb_rinfo.ri_ops.allocattr(&sc->sc_fb.fb_rinfo, 0, 0, 0, attrp);
 
        sc->sc_nscreens++;
        return (0);
@@ -524,3 +586,97 @@
        FBC_WRITE(sc, FFB_FBC_FG, fg);
        ffb_ras_wait(sc);
 }
+
+/* frame buffer generic driver support functions */   
+static void
+ffbfb_unblank(struct device *dev)
+{
+       /* u_int on = 1; */
+
+       if (dev && dev->dv_xname)
+               printf("%s: ffbfb_unblank\n", dev->dv_xname);
+       else
+               printf("ffbfb_unblank(%p)n", dev);
+       /* ffb_blank((struct ffb_softc*)dev, WSDISPLAYIO_SVIDEO, &on); */
+}
+
+int
+ffbfb_open(dev_t dev, int flags, int mode, struct proc *p)
+{
+       int unit = minor(dev);
+
+       if (unit >= ffb_cd.cd_ndevs || ffb_cd.cd_devs[unit] == NULL)
+               return ENXIO;
+
+       return 0;
+}
+
+int
+ffbfb_close(dev_t dev, int flags, int mode, struct proc *p)
+{
+       return 0;
+}
+
+int
+ffbfb_ioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+       struct ffb_softc *sc = ffb_cd.cd_devs[minor(dev)];
+
+       return ffb_ioctl(sc, cmd, data, flags, p);
+}
+
+paddr_t
+ffbfb_mmap(dev_t dev, off_t off, int prot)
+{
+       struct ffb_softc *sc = ffb_cd.cd_devs[minor(dev)];
+       int i, reg;
+       off_t o;
+
+       /*
+        * off is a magic cookie (see xfree86/drivers/sunffb/ffb.h),
+        * which we map to an index into the "reg" property, and use
+        * our copy of the firmware data as arguments for the real
+        * mapping.
+        */
+       static struct { unsigned long voff; int reg; } map[] = {
+               { 0x00000000, FFB_REG_SFB8R },
+               { 0x00400000, FFB_REG_SFB8G },
+               { 0x00800000, FFB_REG_SFB8B },
+               { 0x00c00000, FFB_REG_SFB8X },
+               { 0x01000000, FFB_REG_SFB32 },
+               { 0x02000000, FFB_REG_SFB64  },
+               { 0x04000000, FFB_REG_FBC },
+               { 0x04004000, FFB_REG_DFB8R },
+               { 0x04404000, FFB_REG_DFB8G },
+               { 0x04804000, FFB_REG_DFB8B },
+               { 0x04c04000, FFB_REG_DFB8X },
+               { 0x05004000, FFB_REG_DFB24 },
+               { 0x06004000, FFB_REG_DFB32 },
+               { 0x07004000, FFB_REG_DFB422A },
+               { 0x0bc06000, FFB_REG_DAC },
+               { 0x0bc08000, FFB_REG_PROM },
+       };
+
+       /* special value "FFB_EXP_VOFF" - not backed by any "reg" entry */
+       if (off == 0x0bc18000)
+               return bus_space_mmap(sc->sc_bt, sc->sc_addrs[FFB_REG_PROM],
+                   0x00200000, prot, BUS_SPACE_MAP_LINEAR);
+
+#define NELEMS(arr) (sizeof(arr)/sizeof((arr)[0]))
+
+       /* the map is ordered by voff */
+       for (i = 0; i < NELEMS(map); i++) {
+               if (map[i].voff > off)
+                       break;          /* beyound */
+               reg = map[i].reg;
+               if (map[i].voff + sc->sc_sizes[reg] < off)
+                       continue;       /* not there yet */
+               if (off > map[i].voff + sc->sc_sizes[reg])
+                       break;          /* out of range */
+               o = off - map[i].voff;
+               return bus_space_mmap(sc->sc_bt, sc->sc_addrs[reg], o, prot,
+                   BUS_SPACE_MAP_LINEAR);



Home | Main Index | Thread Index | Old Index