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