diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2011-12-30 12:47:21 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2011-12-30 12:47:21 +0000 |
commit | 9f866067119813243c2e8ecd757d376e74c5d8a6 (patch) | |
tree | ec7af41e567cda37a436e90f996c2bfcfd492c7a | |
parent | f5a79a196e245d6be44d5aee982af2703193d6fc (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.4 | 6 | ||||
-rw-r--r-- | share/man/man4/man4.hp300/intro.4 | 6 | ||||
-rw-r--r-- | share/man/man4/man4.hp300/tvrx.4 | 30 | ||||
-rw-r--r-- | sys/arch/hp300/dev/tvrx.c | 231 |
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 */ |