summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2011-12-30 12:47:21 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2011-12-30 12:47:21 +0000
commit9f866067119813243c2e8ecd757d376e74c5d8a6 (patch)
treeec7af41e567cda37a436e90f996c2bfcfd492c7a
parentf5a79a196e245d6be44d5aee982af2703193d6fc (diff)
I had the opportunity to glance at HP-UX's /etc/conf/graf/gr_98705.h, so
after hours of tinkering with my frame buffer debugger, here comes color support for tvrx(4) - by making use of all overlay planes. Access to the regular planes remains a mystery, and seems to require a download of microcode into the board first. Still slightly better...
-rw-r--r--share/man/man4/man4.hp300/dio.46
-rw-r--r--share/man/man4/man4.hp300/intro.46
-rw-r--r--share/man/man4/man4.hp300/tvrx.430
-rw-r--r--sys/arch/hp300/dev/tvrx.c231
4 files changed, 236 insertions, 37 deletions
diff --git a/share/man/man4/man4.hp300/dio.4 b/share/man/man4/man4.hp300/dio.4
index 38e3640fa5b..5eb4e56fa82 100644
--- a/share/man/man4/man4.hp300/dio.4
+++ b/share/man/man4/man4.hp300/dio.4
@@ -1,4 +1,4 @@
-.\" $OpenBSD: dio.4,v 1.11 2011/12/21 23:12:03 miod Exp $
+.\" $OpenBSD: dio.4,v 1.12 2011/12/30 12:47:20 miod Exp $
.\" $NetBSD: dio.4,v 1.2 2002/01/15 01:31:30 wiz Exp $
.\"
.\" Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -28,7 +28,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: December 21 2011 $
+.Dd $Mdocdate: December 30 2011 $
.Dt DIO 4 hp300
.Os
.Sh NAME
@@ -75,7 +75,7 @@ and
frame buffers
.It Xr tvrx 4
HP98705
-TurboVRX
+PersonalVRX
.Dq Tigershark
frame buffer
.El
diff --git a/share/man/man4/man4.hp300/intro.4 b/share/man/man4/man4.hp300/intro.4
index 246d4c9a00c..32181766c4a 100644
--- a/share/man/man4/man4.hp300/intro.4
+++ b/share/man/man4/man4.hp300/intro.4
@@ -1,4 +1,4 @@
-.\" $OpenBSD: intro.4,v 1.31 2011/12/21 23:12:03 miod Exp $
+.\" $OpenBSD: intro.4,v 1.32 2011/12/30 12:47:20 miod Exp $
.\"
.\" Copyright (c) 1990, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" from: @(#)intro.4 8.1 (Berkeley) 6/5/93
.\"
-.Dd $Mdocdate: December 21 2011 $
+.Dd $Mdocdate: December 30 2011 $
.Dt INTRO 4 hp300
.Os
.Sh NAME
@@ -152,7 +152,7 @@ HP Standard Text Interface
.It Xr topcat 4
Topcat, Catseye and Kathmandu frame buffers
.It Xr tvrx 4
-HP98705 TurboVRX
+HP98705 PersonalVRX
.Dq Tigershark
frame buffer
.El
diff --git a/share/man/man4/man4.hp300/tvrx.4 b/share/man/man4/man4.hp300/tvrx.4
index 59c5aea4f36..74fe1d11743 100644
--- a/share/man/man4/man4.hp300/tvrx.4
+++ b/share/man/man4/man4.hp300/tvrx.4
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tvrx.4,v 1.3 2008/03/26 08:11:08 jmc Exp $
+.\" $OpenBSD: tvrx.4,v 1.4 2011/12/30 12:47:20 miod Exp $
.\"
.\" Copyright (c) 2006, Miodrag Vallat
.\"
@@ -23,23 +23,30 @@
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: March 26 2008 $
+.Dd $Mdocdate: December 30 2011 $
.Dt TVRX 4 hp300
.Os
.Sh NAME
.Nm tvrx
-.Nd HP98705 TurboVRX
+.Nd HP98705 PersonalVRX
.Dq TigerShark
frame buffer
.Sh SYNOPSIS
.Cd "tvrx* at dio?"
.Cd "wsdisplay* at tvrx?"
.Sh DESCRIPTION
-The TurboVRX frame buffer is an accelerated, high resolution
+The PersonalVRX frame buffer is an accelerated, high resolution
.Pq 1280x1024
external display, connected to a 98702 DIO-II interface board.
-Models 98705A and 98705C are 8-bit color frame buffers, while model
-98705B is 16-bit color with a 16-bit Z-buffer.
+The external display is composed of one (66570) or two (66570 with 66571 option)
+8-bit color frame buffer boards.
+Other option boards for the PersonalVRX family include the 66572
+.Sq Z-buffer ,
+the
+66573
+.Sq Transform Engine and Scan
+board, and the 66574
+.Sq Colormap .
All models also have four overlay planes.
.Pp
The
@@ -48,10 +55,15 @@ driver provides a frame buffer abstraction to the
.Xr wscons 4
console framework.
.Pp
-Currently, the driver can only use one overlay plane, and will run as an
-unaccelerated monochrome frame buffer.
+Currently, the driver can only use the overlay planes, and will run as an
+unaccelerated 16 color frame buffer.
.Pp
-The TurboVRX cards can be configured using the 5 DIP switches selector on
+2D acceleration is not available until the appropriate microrode has been
+downloaded into the framebuffer control logic; unfortunately, neither
+the microcode nor documentation about the download interface seems to be
+available.
+.Pp
+The PersonalVRX devices can be configured using the 5 DIP switches selector on
the interface board to define the
.Dq select code .
The select code value is computed by adding 133 to the number made from the
diff --git a/sys/arch/hp300/dev/tvrx.c b/sys/arch/hp300/dev/tvrx.c
index 0c65745917c..2772412a437 100644
--- a/sys/arch/hp300/dev/tvrx.c
+++ b/sys/arch/hp300/dev/tvrx.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: tvrx.c,v 1.1 2006/04/14 21:05:43 miod Exp $ */
+/* $OpenBSD: tvrx.c,v 1.2 2011/12/30 12:47:19 miod Exp $ */
/*
- * Copyright (c) 2006, Miodrag Vallat.
+ * Copyright (c) 2006, 2011, Miodrag Vallat.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,9 @@
*/
/*
- * Graphics routines for the TurboVRX frame buffer
+ * Graphics routines for the ``TigerShark'' PersonalVRX frame buffer,
+ * in its non-STI flavour (DIO-II 98702-66501 interface board; the SGC
+ * 98705-66582 board is expected to be supported by the sti(4) driver).
*/
#include <sys/param.h>
@@ -55,11 +57,60 @@
#include <hp300/dev/diofbreg.h>
#include <hp300/dev/diofbvar.h>
+/*
+ * Hardware registers
+ */
+
+#define TVRX_FV_TRIG 0x5003 /* commit mode settings */
+#define TVRX_DISPLAY_ENABLE 0x500f /* enable display */
+#define TVRX_FB_P_ENABLE 0x5017 /* enable primary fb planes */
+#define TVRX_FB_S_ENABLE 0x501b /* enable secondary fb planes */
+#define TVRX_O_P_ENABLE 0x5023 /* enable primary overlay planes */
+#define TVRX_O_S_ENABLE 0x5027 /* enable secondary overlay planes */
+#define TVRX_WBUSY 0x7047 /* window mover busy */
+#define TVRX_ZHERE 0x7053 /* Z buffer available */
+#define TVRX_FB_WEN 0x7093 /* fb planes write enable */
+#define TVRX_WMOVE 0x709f /* trigger window mover */
+#define TVRX_O_WEN 0x70b7 /* overlay planes write enable */
+#define TVRX_DRIVE 0x70bf /* vram access mode */
+#define DRIVE_OVERLAY_ENABLE 0x10 /* drive vram to overlays */
+#define DRIVE_1BPP 0x80 /* force 1bpp packed memory */
+#define DRIVE_PLANE_MASK 0x0f /* overlay planes read mask */
+#define TVRX_REP_RULE 0x70ef /* window mover replacement rule */
+#define TVRX_ROP(rop) ((rop) << 4 | (rop))
+#define TVRX_SRC_X 0x70f2 /* window mover source position */
+#define TVRX_SRC_Y 0x70f6
+#define TVRX_DST_X 0x70fa /* window mover destination position */
+#define TVRX_DST_Y 0x70fe
+#define TVRX_CNT_X 0x7102 /* window mover span */
+#define TVRX_CNT_Y 0x7106
+
+#define TVRX_CMAP_O_P 0x5203 /* primary overlay colormap (16xRGB) */
+#define TVRX_CMAP_O_S 0x5303 /* secondary overlay colormap */
+#define TVRX_CMAP_FB_P_R 0x5403 /* primary fb colormap, 256xR */
+#define TVRX_CMAP_FB_P_G 0x5803 /* primary fb colormap, 256xG */
+#define TVRX_CMAP_FB_P_B 0x5c03 /* primary fb colormap, 256xB */
+#define TVRX_CMAP_FB_S_R 0x6403 /* secondary fb colormap, 256xR */
+#define TVRX_CMAP_FB_S_G 0x6803 /* secondary fb colormap, 256xG */
+#define TVRX_CMAP_FB_S_B 0x6c03 /* secondary fb colormap, 256xB */
+
+#define tvrx_reg(kva,type,offset) \
+ (*(volatile type *)((kva) + (offset)))
+
+/* wait for window mover to become idle */
+#define tvrx_waitbusy(fb) \
+do { \
+ while (tvrx_reg((fb)->regkva, uint8_t, TVRX_WBUSY) & 0x01) \
+ ; \
+} while (0)
+
+
struct tvrx_softc {
- struct device sc_dev;
- struct diofb *sc_fb;
- struct diofb sc_fb_store;
- int sc_scode;
+ struct device sc_dev;
+ struct diofb *sc_fb;
+ struct diofb sc_fb_store;
+
+ int sc_scode;
};
int tvrx_match(struct device *, void *, void *);
@@ -74,8 +125,14 @@ struct cfdriver tvrx_cd = {
};
int tvrx_reset(struct diofb *, int, struct diofbreg *);
+void tvrx_restore(struct diofb *);
+int tvrx_setcmap(struct diofb *, struct wsdisplay_cmap *);
+void tvrx_setcolor(struct diofb *, u_int);
+int tvrx_windowmove(struct diofb *, u_int16_t, u_int16_t, u_int16_t,
+ u_int16_t, u_int16_t, u_int16_t, int16_t, int16_t);
int tvrx_ioctl(void *, u_long, caddr_t, int, struct proc *);
+void tvrx_burner(void *, u_int, u_int);
struct wsdisplay_accessops tvrx_accessops = {
tvrx_ioctl,
@@ -86,7 +143,7 @@ struct wsdisplay_accessops tvrx_accessops = {
NULL, /* load_font */
NULL, /* scrollback */
NULL, /* getchar */
- NULL /* burner */
+ tvrx_burner
};
/*
@@ -138,31 +195,60 @@ int
tvrx_reset(struct diofb *fb, int scode, struct diofbreg *fbr)
{
int rc;
+ u_int i;
if ((rc = diofb_fbinquire(fb, scode, fbr)) != 0)
return (rc);
- /*
- * We rely on the PROM to initialize the frame buffer in the mode
- * we expect it: cleared, overlay plane enabled and accessible
- * at the beginning of the video memory.
- *
- * This is NOT the mode we would end up by simply resetting the
- * board.
- */
+ /* diofb_fbinquire will return 8 (or maybe 16) planes, but we
+ only use the 4 overlay planes */
+ fb->planes = 4;
+ fb->planemask = (1 << 4) - 1;
- fb->ri.ri_depth = 1;
- fb->bmv = diofb_mono_windowmove;
+ fb->bmv = tvrx_windowmove;
+ tvrx_restore(fb);
diofb_fbsetup(fb);
+ for (i = 0; i <= fb->planemask; i++)
+ tvrx_setcolor(fb, i);
return (0);
}
+void
+tvrx_restore(struct diofb *fb)
+{
+ volatile struct diofbreg *fbr = (volatile struct diofbreg *)fb->regkva;
+
+ /*
+ * Resetting the hardware is slow, disables display output, and
+ * does not clear video memory. Give it some time before we setup
+ * ourselves.
+ */
+ fbr->id = GRFHWID;
+ DELAY(100000);
+
+ /* run the overlay planes unpacked... */
+ tvrx_reg(fb->regkva, uint8_t, TVRX_DRIVE) =
+ DRIVE_OVERLAY_ENABLE | fb->planemask;
+ /* ...and enable the four of them */
+ tvrx_reg(fb->regkva, uint8_t, TVRX_O_P_ENABLE) = fb->planemask;
+ tvrx_reg(fb->regkva, uint8_t, TVRX_O_S_ENABLE) = fb->planemask;
+ tvrx_reg(fb->regkva, uint8_t, TVRX_O_WEN) = fb->planemask;
+ /* disable fb planes for safety */
+ tvrx_reg(fb->regkva, uint8_t, TVRX_FB_P_ENABLE) = 0;
+ tvrx_reg(fb->regkva, uint8_t, TVRX_FB_S_ENABLE) = 0;
+
+ tvrx_reg(fb->regkva, uint8_t, TVRX_REP_RULE) = TVRX_ROP(RR_COPY);
+ tvrx_reg(fb->regkva, uint8_t, TVRX_DISPLAY_ENABLE) = 0x01;
+ tvrx_reg(fb->regkva, uint8_t, TVRX_FV_TRIG) = 0x01;
+}
+
int
tvrx_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
{
struct diofb *fb = v;
struct wsdisplay_fbinfo *wdf;
+ u_int i;
switch (cmd) {
case WSDISPLAYIO_GTYPE:
@@ -170,24 +256,34 @@ tvrx_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
break;
case WSDISPLAYIO_SMODE:
fb->mapmode = *(u_int *)data;
+ if (fb->mapmode == WSDISPLAYIO_MODE_EMUL) {
+ tvrx_restore(fb);
+ /* clear display */
+ (*fb->bmv)(fb, 0, 0, 0, 0, fb->fbwidth, fb->fbheight,
+ RR_CLEAR, fb->planemask);
+ /* restore colormap */
+ diofb_resetcmap(fb);
+ for (i = 0; i <= fb->planemask; i++)
+ tvrx_setcolor(fb, i);
+ }
break;
case WSDISPLAYIO_GINFO:
wdf = (void *)data;
wdf->width = fb->ri.ri_width;
wdf->height = fb->ri.ri_height;
wdf->depth = fb->ri.ri_depth;
- wdf->cmsize = 0;
+ wdf->cmsize = 1 << fb->planes;
break;
case WSDISPLAYIO_LINEBYTES:
*(u_int *)data = fb->ri.ri_stride;
break;
case WSDISPLAYIO_GETCMAP:
+ return (diofb_getcmap(fb, (struct wsdisplay_cmap *)data));
case WSDISPLAYIO_PUTCMAP:
- break; /* until color support is implemented */
+ return (tvrx_setcmap(fb, (struct wsdisplay_cmap *)data));
case WSDISPLAYIO_GVIDEO:
case WSDISPLAYIO_SVIDEO:
- /* unsupported */
- return (-1);
+ break;
default:
return (-1);
}
@@ -195,6 +291,97 @@ tvrx_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
return (0);
}
+void
+tvrx_burner(void *v, u_int on, u_int flags)
+{
+ struct diofb *fb = v;
+
+ tvrx_reg(fb->regkva, uint8_t, TVRX_DISPLAY_ENABLE) = on ? 0x01 : 0x00;
+ tvrx_reg(fb->regkva, uint8_t, TVRX_FV_TRIG) = 0x01;
+}
+
+void
+tvrx_setcolor(struct diofb *fb, u_int index)
+{
+ u_int index_scaled = index * 3 * 4;
+
+ tvrx_reg(fb->regkva, uint8_t, TVRX_CMAP_O_P + index_scaled) =
+ tvrx_reg(fb->regkva, uint8_t, TVRX_CMAP_O_S + index_scaled) =
+ fb->cmap.r[index];
+ tvrx_reg(fb->regkva, uint8_t, TVRX_CMAP_O_P + 4 + index_scaled) =
+ tvrx_reg(fb->regkva, uint8_t, TVRX_CMAP_O_S + 4 + index_scaled) =
+ fb->cmap.g[index];
+ tvrx_reg(fb->regkva, uint8_t, TVRX_CMAP_O_P + 2 * 4 + index_scaled) =
+ tvrx_reg(fb->regkva, uint8_t, TVRX_CMAP_O_S + 2 * 4 + index_scaled) =
+ fb->cmap.b[index];
+}
+
+int
+tvrx_setcmap(struct diofb *fb, struct wsdisplay_cmap *cm)
+{
+ u_int8_t r[256], g[256], b[256];
+ u_int index = cm->index, count = cm->count;
+ u_int colcount = 1 << fb->planes;
+ int error;
+
+ if (index >= colcount || count > colcount - index)
+ return (EINVAL);
+
+ if ((error = copyin(cm->red, r, count)) != 0)
+ return (error);
+ if ((error = copyin(cm->green, g, count)) != 0)
+ return (error);
+ if ((error = copyin(cm->blue, b, count)) != 0)
+ return (error);
+
+ bcopy(r, fb->cmap.r + index, count);
+ bcopy(g, fb->cmap.g + index, count);
+ bcopy(b, fb->cmap.b + index, count);
+
+ while (count-- != 0)
+ tvrx_setcolor(fb, index++);
+
+ return (0);
+}
+
+int
+tvrx_windowmove(struct diofb *fb, u_int16_t sx, u_int16_t sy, u_int16_t dx,
+ u_int16_t dy, u_int16_t cx, u_int16_t cy, int16_t rop, int16_t planemask)
+{
+#ifdef TVRX_DEBUG
+ printf("%s: %dx%d %dx%d %dx%d rx %x planemask %x\n",
+ __func__, fb->sx, sy, dx, dy, cx, cy, rop, planemask);
+#endif
+
+ planemask &= fb->planemask;
+
+ tvrx_reg(fb->regkva, uint16_t, TVRX_SRC_Y) = sy;
+ tvrx_reg(fb->regkva, uint16_t, TVRX_SRC_X) = sx;
+ tvrx_reg(fb->regkva, uint16_t, TVRX_DST_Y) = dy;
+ tvrx_reg(fb->regkva, uint16_t, TVRX_DST_X) = dx;
+ tvrx_reg(fb->regkva, uint16_t, TVRX_CNT_Y) = cy;
+ tvrx_reg(fb->regkva, uint16_t, TVRX_CNT_X) = cx;
+
+ tvrx_reg(fb->regkva, uint8_t, TVRX_REP_RULE) = TVRX_ROP(rop);
+ tvrx_reg(fb->regkva, uint8_t, TVRX_O_WEN) = planemask;
+ tvrx_reg(fb->regkva, uint8_t, TVRX_WMOVE) = 1;
+ tvrx_waitbusy(fb);
+
+ if (planemask != fb->planemask) {
+ rop ^= 0x0f;
+ planemask ^= fb->planemask;
+ tvrx_reg(fb->regkva, uint8_t, TVRX_REP_RULE) = TVRX_ROP(rop);
+ tvrx_reg(fb->regkva, uint8_t, TVRX_O_WEN) = planemask;
+ tvrx_reg(fb->regkva, uint8_t, TVRX_WMOVE) = 1;
+ tvrx_waitbusy(fb);
+ }
+
+ tvrx_reg(fb->regkva, uint8_t, TVRX_O_WEN) = fb->planemask;
+ tvrx_reg(fb->regkva, uint8_t, TVRX_REP_RULE) = TVRX_ROP(RR_COPY);
+
+ return 0;
+}
+
/*
* Console support
*/