summaryrefslogtreecommitdiff
path: root/sys/arch/sparc/dev/cgeight.c
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2002-08-12 10:44:05 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2002-08-12 10:44:05 +0000
commit15dafe6228319925897f71b6a78bb04ebfb3abc4 (patch)
tree2bfbe764cfc6f9b1e3c6ca9d29d0881a4283149e /sys/arch/sparc/dev/cgeight.c
parenta83486fe3ff711d8b3727f8abae7995141bb7562 (diff)
Convert sparc console code from rcons and pseudo-devices to rasops and wscons.
For most framebuffers it is faster. Other changes include: o 24 bit support in tcx(4) for the S24 framebuffer o accelerated cgsix(4) text console o new cgtwelve(4) driver for the GS framebuffer o improved serial driver code o better keyboard support The following framebuffers have not been tested but should work: cgfour, cgeight and cgfourteen These changes will require XF4 changes, to use Xwsfb instead of Xsun*, to be commited later today. Most of the work by me during the LSM and the week after, with code borrowed from jason@, NetBSD (new serial code), and feedback from mickey@. Work on pnozz(4) done by millert@
Diffstat (limited to 'sys/arch/sparc/dev/cgeight.c')
-rw-r--r--sys/arch/sparc/dev/cgeight.c477
1 files changed, 177 insertions, 300 deletions
diff --git a/sys/arch/sparc/dev/cgeight.c b/sys/arch/sparc/dev/cgeight.c
index 1ced12ab486..344925dfaa9 100644
--- a/sys/arch/sparc/dev/cgeight.c
+++ b/sys/arch/sparc/dev/cgeight.c
@@ -1,7 +1,8 @@
-/* $OpenBSD: cgeight.c,v 1.13 2002/03/14 01:26:42 millert Exp $ */
+/* $OpenBSD: cgeight.c,v 1.14 2002/08/12 10:44:03 miod Exp $ */
/* $NetBSD: cgeight.c,v 1.13 1997/05/24 20:16:04 pk Exp $ */
/*
+ * Copyright (c) 2002 Miodrag Vallat. All rights reserved.
* Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
* Copyright (c) 1995 Theo de Raadt
* Copyright (c) 1992, 1993
@@ -67,55 +68,80 @@
#include <uvm/uvm_extern.h>
-#include <machine/fbio.h>
#include <machine/autoconf.h>
#include <machine/pmap.h>
-#include <machine/fbvar.h>
#include <machine/eeprom.h>
#include <machine/conf.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/wscons/wscons_raster.h>
+#include <dev/rasops/rasops.h>
+#include <machine/fbvar.h>
+
#include <sparc/dev/btreg.h>
#include <sparc/dev/btvar.h>
#include <sparc/dev/pfourreg.h>
/* per-display variables */
struct cgeight_softc {
- struct device sc_dev; /* base device */
- struct fbdevice sc_fb; /* frame buffer device */
- struct rom_reg sc_phys; /* display RAM (phys addr) */
+ struct sunfb sc_sunfb; /* common base part */
+ struct rom_reg sc_phys; /* display RAM (phys addr) */
volatile struct fbcontrol *sc_fbc; /* Brooktree registers */
- int sc_bustype; /* type of bus we live on */
union bt_cmap sc_cmap; /* Brooktree color map */
+ int sc_nscreens;
};
-/* autoconfiguration driver */
-static void cgeightattach(struct device *, struct device *, void *);
-static int cgeightmatch(struct device *, void *, void *);
-#if defined(SUN4)
-static void cgeightunblank(struct device *);
-#endif
+struct wsscreen_descr cgeight_stdscreen = {
+ "std",
+ 0, 0, /* will be filled in */
+ 0,
+ 0, 0,
+ WSSCREEN_REVERSE | WSSCREEN_WSCOLORS
+};
-struct cfattach cgeight_ca = {
- sizeof(struct cgeight_softc), cgeightmatch, cgeightattach
+const struct wsscreen_descr *cgeight_scrlist[] = {
+ &cgeight_stdscreen,
};
-struct cfdriver cgeight_cd = {
- NULL, "cgeight", DV_DULL
+struct wsscreen_list cgeight_screenlist = {
+ sizeof(cgeight_scrlist) /sizeof(struct wsscreen_descr *),
+ cgeight_scrlist
};
-#if defined(SUN4)
-/* frame buffer generic driver */
-static struct fbdriver cgeightfbdriver = {
- cgeightunblank, cgeightopen, cgeightclose, cgeightioctl, cgeightmmap
+int cgeight_ioctl(void *, u_long, caddr_t, int, struct proc *);
+int cgeight_alloc_screen(void *, const struct wsscreen_descr *, void **,
+ int *, int *, long *);
+void cgeight_free_screen(void *, void *);
+int cgeight_show_screen(void *, void *, int, void (*cb)(void *, int, int),
+ void *);
+paddr_t cgeight_mmap(void *, off_t, int);
+int cgeight_is_console(int);
+void cgeight_reset(struct cgeight_softc *);
+void cgeight_burner(void *, u_int, u_int);
+
+struct wsdisplay_accessops cgeight_accessops = {
+ cgeight_ioctl,
+ cgeight_mmap,
+ cgeight_alloc_screen,
+ cgeight_free_screen,
+ cgeight_show_screen,
+ NULL, /* load_font */
+ NULL, /* scrollback */
+ NULL, /* getchar */
+ cgeight_burner,
};
-extern int fbnode;
-extern struct tty *fbconstty;
+void cgeightattach(struct device *, struct device *, void *);
+int cgeightmatch(struct device *, void *, void *);
-static void cgeightloadcmap(struct cgeight_softc *, int, int);
-static int cgeight_get_video(struct cgeight_softc *);
-static void cgeight_set_video(struct cgeight_softc *, int);
-#endif
+struct cfattach cgeight_ca = {
+ sizeof(struct cgeight_softc), cgeightmatch, cgeightattach
+};
+
+struct cfdriver cgeight_cd = {
+ NULL, "cgeight", DV_DULL
+};
/*
* Match a cgeight.
@@ -129,24 +155,15 @@ cgeightmatch(parent, vcf, aux)
struct confargs *ca = aux;
struct romaux *ra = &ca->ca_ra;
- if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
- return (0);
-
/*
* Mask out invalid flags from the user.
*/
cf->cf_flags &= FB_USERMASK;
- /*
- * Only exists on a sun4.
- */
- if (!CPU_ISSUN4)
+ if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
return (0);
- /*
- * Only exists on obio.
- */
- if (ca->ca_bustype != BUS_OBIO)
+ if (!CPU_ISSUN4 || ca->ca_bustype != BUS_OBIO)
return (0);
/*
@@ -155,7 +172,6 @@ cgeightmatch(parent, vcf, aux)
if (probeget(ra->ra_vaddr, 4) == -1)
return (0);
-#if defined(SUN4)
/*
* Check the pfour register.
*/
@@ -163,57 +179,31 @@ cgeightmatch(parent, vcf, aux)
cf->cf_flags |= FB_PFOUR;
return (1);
}
-#endif
return (0);
}
/*
- * Attach a display. We need to notice if it is the console, too.
+ * Attach a display.
*/
void
cgeightattach(parent, self, args)
struct device *parent, *self;
void *args;
{
-#if defined(SUN4)
- register struct cgeight_softc *sc = (struct cgeight_softc *)self;
- register struct confargs *ca = args;
- register int node = 0, ramsize, i;
- register volatile struct bt_regs *bt;
- struct fbdevice *fb = &sc->sc_fb;
- int isconsole;
-
- fb->fb_driver = &cgeightfbdriver;
- fb->fb_device = &sc->sc_dev;
- fb->fb_type.fb_type = FBTYPE_MEMCOLOR;
- fb->fb_flags = sc->sc_dev.dv_cfdata->cf_flags;
+ struct cgeight_softc *sc = (struct cgeight_softc *)self;
+ struct confargs *ca = args;
+ struct wsemuldisplaydev_attach_args waa;
+ int node = 0, i;
+ volatile struct bt_regs *bt;
+ int isconsole = 0;
- /*
- * Only pfour cgfours, thank you...
- */
- if ((ca->ca_bustype != BUS_OBIO) ||
- ((fb->fb_flags & FB_PFOUR) == 0)) {
- printf("%s: ignoring; not a pfour\n", sc->sc_dev.dv_xname);
- return;
- }
+ sc->sc_sunfb.sf_flags = self->dv_cfdata->cf_flags;
/* Map the pfour register. */
- fb->fb_pfour = (volatile u_int32_t *)
+ sc->sc_sunfb.sf_pfour = (volatile u_int32_t *)
mapiodev(ca->ca_ra.ra_reg, 0, sizeof(u_int32_t));
- ramsize = PFOUR_COLOR_OFF_END - PFOUR_COLOR_OFF_OVERLAY;
-
- fb->fb_type.fb_depth = 24;
- fb_setsize(fb, fb->fb_type.fb_depth, 1152, 900, node, ca->ca_bustype);
-
- sc->sc_fb.fb_type.fb_cmsize = 256;
- sc->sc_fb.fb_type.fb_size = ramsize;
- printf(": cgeight/p4, %d x %d", fb->fb_type.fb_width,
- fb->fb_type.fb_height);
-
- isconsole = 0;
-
if (cputyp == CPU_SUN4) {
struct eeprom *eep = (struct eeprom *)eeprom_va;
@@ -222,45 +212,15 @@ cgeightattach(parent, self, args)
* to be found.
*/
if (eep == NULL || eep->eeConsole == EE_CONS_P4OPT)
- isconsole = (fbconstty != NULL);
+ isconsole = 1;
}
-#if 0
- /*
- * We don't do any of the console handling here. Instead,
- * we let the bwtwo driver pick up the overlay plane and
- * use it instead. Rconsole should have better performance
- * with the 1-bit depth.
- * -- Jason R. Thorpe <thorpej@NetBSD.ORG>
- */
-
- /*
- * When the ROM has mapped in a cgfour display, the address
- * maps only the video RAM, so in any case we have to map the
- * registers ourselves. We only need the video RAM if we are
- * going to print characters via rconsole.
- */
-
- if (isconsole) {
- /* XXX this is kind of a waste */
- fb->fb_pixels = mapiodev(ca->ca_ra.ra_reg,
- PFOUR_COLOR_OFF_OVERLAY, ramsize);
- }
-#endif
-
/* Map the Brooktree. */
sc->sc_fbc = (volatile struct fbcontrol *)
mapiodev(ca->ca_ra.ra_reg,
PFOUR_COLOR_OFF_CMAP, sizeof(struct fbcontrol));
sc->sc_phys = ca->ca_ra.ra_reg[0];
- sc->sc_bustype = ca->ca_bustype;
-
-#if 0 /* XXX thorpej ??? */
- /* tell the enable plane to look at the mono image */
- memset(ca->ca_ra.ra_vaddr, 0xff,
- sc->sc_fb.fb_type.fb_width * sc->sc_fb.fb_type.fb_height / 8);
-#endif
/* grab initial (current) color map */
bt = &sc->sc_fbc->fbc_dac;
@@ -268,245 +228,162 @@ cgeightattach(parent, self, args)
for (i = 0; i < 256 * 3 / 4; i++)
sc->sc_cmap.cm_chip[i] = bt->bt_cmap;
+ /* enable video */
+ cgeight_burner(sc, 1, 0);
BT_INIT(bt, 0);
-#if 0 /* see above */
- if (isconsole) {
- printf(" (console)\n");
-#if defined(RASTERCONSOLE) && 0 /* XXX been told it doesn't work well. */
- fbrcons_init(fb);
-#endif
- } else
-#endif /* 0 */
- printf("\n");
+ fb_setsize(&sc->sc_sunfb, 24, 1152, 900, node, ca->ca_bustype);
+ sc->sc_sunfb.sf_ro.ri_hw = sc;
+ sc->sc_sunfb.sf_ro.ri_bits = mapiodev(ca->ca_ra.ra_reg,
+ PFOUR_COLOR_OFF_OVERLAY, round_page(sc->sc_sunfb.sf_fbsize));
+ fbwscons_init(&sc->sc_sunfb, isconsole);
- /*
- * Even though we're not using rconsole, we'd still like
- * to notice if we're the console framebuffer.
- */
- fb_attach(&sc->sc_fb, isconsole);
-#endif
-}
+ cgeight_stdscreen.nrows = sc->sc_sunfb.sf_ro.ri_rows;
+ cgeight_stdscreen.ncols = sc->sc_sunfb.sf_ro.ri_cols;
+ cgeight_stdscreen.textops = &sc->sc_sunfb.sf_ro.ri_ops;
-int
-cgeightopen(dev, flags, mode, p)
- dev_t dev;
- int flags, mode;
- struct proc *p;
-{
- int unit = minor(dev);
+ printf(": cgeight/p4, %dx%d", sc->sc_sunfb.sf_width,
+ sc->sc_sunfb.sf_height);
- if (unit >= cgeight_cd.cd_ndevs || cgeight_cd.cd_devs[unit] == NULL)
- return (ENXIO);
- return (0);
-}
-
-int
-cgeightclose(dev, flags, mode, p)
- dev_t dev;
- int flags, mode;
- struct proc *p;
-{
+ if (isconsole) {
+ fbwscons_console_init(&sc->sc_sunfb, &cgeight_stdscreen, -1,
+ NULL, cgeight_burner);
+ }
- return (0);
+ waa.console = isconsole;
+ waa.scrdata = &cgeight_screenlist;
+ waa.accessops = &cgeight_accessops;
+ waa.accesscookie = sc;
+ config_found(self, &waa, wsemuldisplaydevprint);
}
int
-cgeightioctl(dev, cmd, data, flags, p)
- dev_t dev;
+cgeight_ioctl(v, cmd, data, flags, p)
+ void *v;
u_long cmd;
- register caddr_t data;
+ caddr_t data;
int flags;
struct proc *p;
{
-#if defined(SUN4)
- register struct cgeight_softc *sc = cgeight_cd.cd_devs[minor(dev)];
- register struct fbgattr *fba;
+ struct cgeight_softc *sc = v;
+ struct wsdisplay_cmap *cm;
+ struct wsdisplay_fbinfo *wdf;
int error;
switch (cmd) {
-
- case FBIOGTYPE:
- *(struct fbtype *)data = sc->sc_fb.fb_type;
+ case WSDISPLAYIO_GTYPE:
+ *(u_int *)data = WSDISPLAY_TYPE_UNKNOWN;
break;
-
- case FBIOGATTR:
- 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;
+ case WSDISPLAYIO_GINFO:
+ wdf = (struct wsdisplay_fbinfo *)data;
+ wdf->height = sc->sc_sunfb.sf_height;
+ wdf->width = sc->sc_sunfb.sf_width;
+ wdf->depth = sc->sc_sunfb.sf_depth;
+ wdf->cmsize = 256;
break;
-
- case FBIOGETCMAP:
- return (bt_getcmap((struct fbcmap *)data, &sc->sc_cmap, 256));
-
- case FBIOPUTCMAP:
- /* copy to software map */
-#define p ((struct fbcmap *)data)
- error = bt_putcmap(p, &sc->sc_cmap, 256);
+ case WSDISPLAYIO_GETCMAP:
+ cm = (struct wsdisplay_cmap *)data;
+ error = bt_getcmap(&sc->sc_cmap, cm);
if (error)
return (error);
- /* now blast them into the chip */
- /* XXX should use retrace interrupt */
- cgeightloadcmap(sc, p->index, p->count);
-#undef p
- break;
-
- case FBIOGVIDEO:
- *(int *)data = cgeight_get_video(sc);
break;
-
- case FBIOSVIDEO:
- cgeight_set_video(sc, *(int *)data);
+ case WSDISPLAYIO_PUTCMAP:
+ cm = (struct wsdisplay_cmap *)data;
+ error = bt_putcmap(&sc->sc_cmap, cm);
+ if (error)
+ return (error);
+ bt_loadcmap(&sc->sc_cmap, &sc->sc_fbc->fbc_dac,
+ cm->index, cm->count, 0);
break;
+ case WSDISPLAYIO_SVIDEO:
+ case WSDISPLAYIO_GVIDEO:
+ case WSDISPLAYIO_GCURPOS:
+ case WSDISPLAYIO_SCURPOS:
+ case WSDISPLAYIO_GCURMAX:
+ case WSDISPLAYIO_GCURSOR:
+ case WSDISPLAYIO_SCURSOR:
default:
- return (ENOTTY);
+ return (-1); /* not supported yet */
+
}
-#endif
+
return (0);
}
-/*
- * Return the address that would map the given device at the given
- * offset, allowing for the given protection, or return -1 for error.
- *
- * The cg8 maps it's overlay plane at 0 for 128K, followed by the
- * enable plane for 128K, followed by the colour for as long as it
- * goes. Starting at 8MB, it maps the ramdac for NBPG, then the p4
- * register for NBPG, then the bootrom for 0x40000.
- */
-paddr_t
-cgeightmmap(dev, off, prot)
- dev_t dev;
- off_t off;
- int prot;
+int
+cgeight_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
+ void *v;
+ const struct wsscreen_descr *type;
+ void **cookiep;
+ int *curxp, *curyp;
+ long *attrp;
{
- register struct cgeight_softc *sc = cgeight_cd.cd_devs[minor(dev)];
- int poff;
-
-#define START_ENABLE (128*1024)
-#define START_COLOR ((128*1024) + (128*1024))
-#define COLOR_SIZE (sc->sc_fb.fb_type.fb_width * \
- sc->sc_fb.fb_type.fb_height * 3)
-#define END_COLOR (START_COLOR + COLOR_SIZE)
-#define START_SPECIAL 0x800000
-#define PROMSIZE 0x40000
-#define NOOVERLAY (0x04000000)
-
- if (off & PGOFSET)
- panic("cgeightmap");
-
- if (off < 0)
- return (-1);
- if ((u_int)off >= NOOVERLAY) {
- off -= NOOVERLAY;
+ struct cgeight_softc *sc = v;
- /*
- * X11 maps a huge chunk of the frame buffer; far more than
- * there really is. We compensate by double-mapping the
- * first page for as many other pages as it wants
- */
- while ((u_int)off >= COLOR_SIZE)
- off -= COLOR_SIZE; /* XXX thorpej ??? */
+ if (sc->sc_nscreens > 0)
+ return (ENOMEM);
- poff = off + PFOUR_COLOR_OFF_COLOR;
- } else if ((u_int)off < START_ENABLE) {
- /*
- * in overlay plane
- */
- poff = PFOUR_COLOR_OFF_OVERLAY + off;
- } else if ((u_int)off < START_COLOR) {
- /*
- * in enable plane
- */
- poff = (off - START_ENABLE) + PFOUR_COLOR_OFF_ENABLE;
- } else if ((u_int)off < sc->sc_fb.fb_type.fb_size) {
- /*
- * in colour plane
- */
- poff = (off - START_COLOR) + PFOUR_COLOR_OFF_COLOR;
- } else if ((u_int)off < START_SPECIAL) {
- /*
- * hole
- */
- poff = 0; /* XXX */
- } else if ((u_int)off == START_SPECIAL) {
- /*
- * colour map (Brooktree)
- */
- poff = PFOUR_COLOR_OFF_CMAP;
- } else if ((u_int)off == START_SPECIAL + NBPG) {
- /*
- * p4 register
- */
- poff = 0;
- } else if ((u_int)off > (START_SPECIAL + (NBPG * 2)) &&
- (u_int) off < (START_SPECIAL + (NBPG * 2) + PROMSIZE)) {
- /*
- * rom
- */
- poff = 0x8000 + (off - (START_SPECIAL + (NBPG * 2)));
- } else
- return (-1);
- /*
- * I turned on PMAP_NC here to disable the cache as I was
- * getting horribly broken behaviour with it on.
- */
- return (REG2PHYS(&sc->sc_phys, poff) | PMAP_NC);
+ *cookiep = &sc->sc_sunfb.sf_ro;
+ *curyp = 0;
+ *curxp = 0;
+ sc->sc_sunfb.sf_ro.ri_ops.alloc_attr(&sc->sc_sunfb.sf_ro,
+ 0, 0, 0, attrp);
+ sc->sc_nscreens++;
+ return (0);
}
-#if defined(SUN4)
-/*
- * Undo the effect of an FBIOSVIDEO that turns the video off.
- */
-static void
-cgeightunblank(dev)
- struct device *dev;
+void
+cgeight_free_screen(v, cookie)
+ void *v;
+ void *cookie;
{
+ struct cgeight_softc *sc = v;
- cgeight_set_video((struct cgeight_softc *)dev, 1);
+ sc->sc_nscreens--;
}
-static int
-cgeight_get_video(sc)
- struct cgeight_softc *sc;
+int
+cgeight_show_screen(v, cookie, waitok, cb, cbarg)
+ void *v;
+ void *cookie;
+ int waitok;
+ void (*cb)(void *, int, int);
+ void *cbarg;
{
-
- return (fb_pfour_get_video(&sc->sc_fb));
+ return (0);
}
-static void
-cgeight_set_video(sc, enable)
- struct cgeight_softc *sc;
- int enable;
+/*
+ * Return the address that would map the given device at the given
+ * offset, allowing for the given protection, or return -1 for error.
+ */
+paddr_t
+cgeight_mmap(v, offset, prot)
+ void *v;
+ off_t offset;
+ int prot;
{
+ struct cgeight_softc *sc = v;
+
+ if (offset & PGOFSET)
+ return (-1);
+
+ /* Allow mapping as a dumb framebuffer from offset 0 */
+ if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize) {
+ return (REG2PHYS(&sc->sc_phys, offset +
+ PFOUR_COLOR_OFF_OVERLAY) | PMAP_NC);
+ }
- fb_pfour_set_video(&sc->sc_fb, enable);
+ return (-1); /* not a user-map offset */
}
-/*
- * Load a subset of the current (new) colormap into the Brooktree DAC.
- */
-static void
-cgeightloadcmap(sc, start, ncolors)
- register struct cgeight_softc *sc;
- register int start, ncolors;
+void
+cgeight_burner(v, on, flags)
+ void *v;
+ u_int on, flags;
{
- register volatile struct bt_regs *bt;
- register u_int *ip;
- register int count;
+ struct cgeight_softc *sc = v;
- ip = &sc->sc_cmap.cm_chip[BT_D4M3(start)]; /* start/4 * 3 */
- count = BT_D4M3(start + ncolors - 1) - BT_D4M3(start) + 3;
- bt = &sc->sc_fbc->fbc_dac;
- bt->bt_addr = BT_D4M4(start);
- while (--count >= 0)
- bt->bt_cmap = *ip++;
+ fb_pfour_set_video(&sc->sc_sunfb, on);
}
-#endif