summaryrefslogtreecommitdiff
path: root/sys/dev/sbus/cgthree.c
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>2002-01-04 08:22:14 +0000
committerJason Wright <jason@cvs.openbsd.org>2002-01-04 08:22:14 +0000
commit80c51b3f573153f5c32b1bba1e002af3c13d9e43 (patch)
tree7d02a9b9e50614f90fc7ff724fb62b7315e727be /sys/dev/sbus/cgthree.c
parent6df9b8722aaf6d6411d1357bc7699f54357d1668 (diff)
Add support for get/put colormap (mostly borrowed from sparc)
[XXX the bt458 stuff should be shared and will be later].
Diffstat (limited to 'sys/dev/sbus/cgthree.c')
-rw-r--r--sys/dev/sbus/cgthree.c153
1 files changed, 145 insertions, 8 deletions
diff --git a/sys/dev/sbus/cgthree.c b/sys/dev/sbus/cgthree.c
index d0f2087d046..518914c298b 100644
--- a/sys/dev/sbus/cgthree.c
+++ b/sys/dev/sbus/cgthree.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cgthree.c,v 1.3 2002/01/04 05:42:30 jason Exp $ */
+/* $OpenBSD: cgthree.c,v 1.4 2002/01/04 08:22:13 jason Exp $ */
/*
* Copyright (c) 2001 Jason L. Wright (jason@thought.net)
@@ -55,6 +55,31 @@
#define CGTHREE_VID_OFFSET 0x800000
#define CGTHREE_VID_SIZE (1024 * 1024)
+union bt_cmap {
+ u_int8_t cm_map[256][3]; /* 256 r/b/g entries */
+ u_int32_t cm_chip[256 * 3 / 4]; /* the way the chip is loaded */
+};
+
+#define BT_ADDR 0x00 /* map address register */
+#define BT_CMAP 0x04 /* colormap data register */
+#define BT_CTRL 0x08 /* control register */
+#define BT_OMAP 0x0c /* overlay (cursor) map register */
+
+#define BT_WRITE(sc, reg, val) \
+ bus_space_write_4((sc)->sc_bustag, (sc)->sc_ctrl_regs, (reg), (val))
+#define BT_READ(sc, reg) \
+ bus_space_read_4((sc)->sc_bustag, (sc)->sc_ctrl_regs, (reg))
+
+#define BT_INIT(sc) do { \
+ BT_WRITE((sc), BT_ADDR, 0x06); /* command reg */ \
+ BT_WRITE((sc), BT_CTRL, 0x73); /* overlay plane */ \
+ BT_WRITE((sc), BT_ADDR, 0x04); /* read mask */ \
+ BT_WRITE((sc), BT_CTRL, 0xff); /* color planes */ \
+} while (0)
+
+#define BT_D4M3(x) ((((x) >> 2) << 1) + ((x) >> 2)) /* (x / 4) * 3 */
+#define BT_D4M4(x) ((x) & ~3) /* (x / 4) * 4 */
+
struct cgthree_softc {
struct device sc_dev;
struct sbusdev sc_sd;
@@ -67,6 +92,7 @@ struct cgthree_softc {
int sc_width, sc_height, sc_depth, sc_linebytes;
struct rcons sc_rcons;
struct raster sc_raster;
+ union bt_cmap sc_cmap;
};
struct wsdisplay_emulops cgthree_emulops = {
@@ -105,6 +131,11 @@ int cgthree_show_screen __P((void *, void *, int,
void (*cb) __P((void *, int, int)), void *));
paddr_t cgthree_mmap __P((void *, off_t, int));
int cgthree_is_console __P((int));
+void cgthree_loadcmap __P((struct cgthree_softc *, u_int, u_int));
+int cg3_bt_putcmap __P((union bt_cmap *, struct wsdisplay_cmap *));
+int cg3_bt_getcmap __P((union bt_cmap *, struct wsdisplay_cmap *));
+void cgthree_setcolor __P((struct cgthree_softc *, u_int,
+ u_int8_t, u_int8_t, u_int8_t));
static int a2int __P((char *, int));
@@ -147,7 +178,7 @@ cgthreeattach(parent, self, aux)
struct cgthree_softc *sc = (struct cgthree_softc *)self;
struct sbus_attach_args *sa = aux;
struct wsemuldisplaydev_attach_args waa;
- int console;
+ int console, i;
long defattr;
sc->sc_bustag = sa->sa_bustag;
@@ -160,7 +191,7 @@ cgthreeattach(parent, self, aux)
}
/*
- * Map just BT, FHC, THC, and video RAM.
+ * Map just CTRL and video RAM.
*/
if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
sa->sa_reg[0].sbr_offset + CGTHREE_CTRL_OFFSET,
@@ -198,6 +229,11 @@ cgthreeattach(parent, self, aux)
sbus_establish(&sc->sc_sd, &sc->sc_dev);
+ BT_WRITE(sc, BT_ADDR, 0);
+ for (i = 0; i < 256 * 3 / 4; i++)
+ sc->sc_cmap.cm_chip[i] = BT_READ(sc, BT_CMAP);
+ BT_INIT(sc);
+
sc->sc_rcons.rc_sp = &sc->sc_raster;
sc->sc_raster.width = sc->sc_width;
sc->sc_raster.height = sc->sc_height;
@@ -227,9 +263,20 @@ cgthreeattach(parent, self, aux)
printf("\n");
- if (console)
+ if (console) {
+ cgthree_setcolor(sc, WSCOL_BLACK, 0, 0, 0);
+ cgthree_setcolor(sc, 255, 255, 255, 255);
+ cgthree_setcolor(sc, WSCOL_RED, 255, 0, 0);
+ cgthree_setcolor(sc, WSCOL_GREEN, 0, 255, 0);
+ cgthree_setcolor(sc, WSCOL_BROWN, 154, 85, 46);
+ cgthree_setcolor(sc, WSCOL_BLUE, 0, 0, 255);
+ cgthree_setcolor(sc, WSCOL_MAGENTA, 255, 255, 0);
+ cgthree_setcolor(sc, WSCOL_CYAN, 0, 255, 255);
+ cgthree_setcolor(sc, WSCOL_WHITE, 255, 255, 255);
+
wsdisplay_cnattach(&cgthree_stdscreen, &sc->sc_rcons,
*sc->sc_rcons.rc_ccolp, *sc->sc_rcons.rc_crowp, defattr);
+ }
waa.console = console;
waa.scrdata = &cgthree_screenlist;
@@ -255,6 +302,8 @@ cgthree_ioctl(v, cmd, data, flags, p)
{
struct cgthree_softc *sc = v;
struct wsdisplay_fbinfo *wdf;
+ struct wsdisplay_cmap *cm;
+ int error;
switch (cmd) {
case WSDISPLAYIO_GTYPE:
@@ -271,12 +320,20 @@ cgthree_ioctl(v, cmd, data, flags, p)
*(u_int *)data = sc->sc_linebytes;
break;
-#if 0
case WSDISPLAYIO_GETCMAP:
- return vgafb_getcmap(vc, (struct wsdisplay_cmap *)data);
+ cm = (struct wsdisplay_cmap *)data;
+ error = cg3_bt_getcmap(&sc->sc_cmap, cm);
+ if (error)
+ return (error);
+ break;
+
case WSDISPLAYIO_PUTCMAP:
- return vgafb_putcmap(vc, (struct wsdisplay_cmap *)data);
-#endif
+ cm = (struct wsdisplay_cmap *)data;
+ error = cg3_bt_putcmap(&sc->sc_cmap, cm);
+ if (error)
+ return (error);
+ cgthree_loadcmap(sc, cm->index, cm->count);
+ break;
case WSDISPLAYIO_SVIDEO:
case WSDISPLAYIO_GVIDEO:
@@ -388,3 +445,83 @@ cgthree_is_console(node)
return (fbnode == node);
}
+
+void
+cgthree_setcolor(sc, index, r, g, b)
+ struct cgthree_softc *sc;
+ u_int index;
+ u_int8_t r, g, b;
+{
+ union bt_cmap *bcm = &sc->sc_cmap;
+
+ bcm->cm_map[index][0] = r;
+ bcm->cm_map[index][1] = g;
+ bcm->cm_map[index][2] = b;
+ cgthree_loadcmap(sc, index, 1);
+}
+
+void
+cgthree_loadcmap(sc, start, ncolors)
+ struct cgthree_softc *sc;
+ u_int start, ncolors;
+{
+ u_int cstart;
+ int count;
+
+ cstart = BT_D4M3(start);
+ count = BT_D4M3(start + ncolors - 1) - BT_D4M3(start) + 3;
+ BT_WRITE(sc, BT_ADDR, BT_D4M4(start));
+ while (--count >= 0) {
+ BT_WRITE(sc, BT_CMAP, sc->sc_cmap.cm_chip[cstart]);
+ cstart++;
+ }
+}
+
+int
+cg3_bt_getcmap(bcm, rcm)
+ union bt_cmap *bcm;
+ struct wsdisplay_cmap *rcm;
+{
+ u_int index = rcm->index, count = rcm->count, i;
+ int error;
+
+ if (index >= 256 || index + count > 256)
+ return (EINVAL);
+ for (i = 0; i < count; i++) {
+ if ((error = copyout(&bcm->cm_map[index + i][0],
+ &rcm->red[i], 1)) != 0)
+ return (error);
+ if ((error = copyout(&bcm->cm_map[index + i][1],
+ &rcm->green[i], 1)) != 0)
+ return (error);
+ if ((error = copyout(&bcm->cm_map[index + i][2],
+ &rcm->blue[i], 1)) != 0)
+ return (error);
+ }
+ return (0);
+}
+
+int
+cg3_bt_putcmap(bcm, rcm)
+ union bt_cmap *bcm;
+ struct wsdisplay_cmap *rcm;
+{
+ u_int index = rcm->index, count = rcm->count, i;
+ int error;
+
+ if (index >= 256 || rcm->count > 256 ||
+ (rcm->index + rcm->count) > 256)
+ return (EINVAL);
+ for (i = 0; i < count; i++) {
+ if ((error = copyin(&rcm->red[i],
+ &bcm->cm_map[index + i][0], 1)) != 0)
+ return (error);
+ if ((error = copyin(&rcm->green[i],
+ &bcm->cm_map[index + i][1], 1)) != 0)
+ return (error);
+ if ((error = copyin(&rcm->blue[i],
+ &bcm->cm_map[index + i][2], 1)) != 0)
+ return (error);
+ }
+ return (0);
+}