summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2006-07-24 20:35:09 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2006-07-24 20:35:09 +0000
commitd4567ce267be20d900513e1d0fd2f179dc7bd3b8 (patch)
tree15fb0c7805e7c816f8fd8aef698a561b52988abb /sys
parentb8b1809bfab62d1f228d3281549039c26171d76a (diff)
Add a wsdisplay driver for the frame buffer found on VS4000/60 and VLC
systems, based on Blaz Antonic's work and adjusted to fit modern wscons requirements; currently running as a dumb frame buffer, acceleration code going in soon.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/vax/conf/GENERIC16
-rw-r--r--sys/arch/vax/conf/files.vax18
-rw-r--r--sys/arch/vax/vax/conf.c21
-rw-r--r--sys/arch/vax/vsa/lcg.c655
-rw-r--r--sys/arch/vax/vsa/lcgreg.h191
5 files changed, 883 insertions, 18 deletions
diff --git a/sys/arch/vax/conf/GENERIC b/sys/arch/vax/conf/GENERIC
index 0d4c9c45f9e..989174509b5 100644
--- a/sys/arch/vax/conf/GENERIC
+++ b/sys/arch/vax/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.41 2006/07/20 19:15:34 miod Exp $
+# $OpenBSD: GENERIC,v 1.42 2006/07/24 20:35:06 miod Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -68,8 +68,9 @@ ncr0 at vsbus0 csr 0x200c0080 # VS2000/3100 SCSI-ctlr
ncr1 at vsbus0 csr 0x200c0180 # VS2000/3100 SCSI-ctlr
asc0 at vsbus0 csr 0x200c0080 # VS4000/60 (or VLC) SCSI-ctlr
asc0 at vsbus0 csr 0x26000080 # VS4000/90 4000/10X MV3100/9X SCSI
-smg0 at vsbus0 csr 0x200f0000 # Small monochrome display ctlr.
-#clr0 at vsbus0 csr 0x30000000 # 4- or 8-bitplans color graphics
+smg0 at vsbus0 csr 0x200f0000 # VS3100 on-board mono frame buffer
+#gpx0 at vsbus0 csr 0x3c000000 # VS3100 GPX display option
+lcg0 at vsbus0 csr 0x20100000 # VS4000/60 (or VLC) frame buffer
#hd* at hdc0 drive? # RD5x disks
#ry* at hdc0 drive? # RX floppies
@@ -142,11 +143,12 @@ ses* at scsibus?
uk* at scsibus?
# Workstation console
-wsdisplay0 at smg?
+wsdisplay* at smg?
+#wsdisplay* at gpx?
+wsdisplay* at lcg?
-#wsdisplay0 at clr0
-#wsdisplay0 at qd0
-#wsdisplay0 at qv0
+#wsdisplay* at qd0
+#wsdisplay* at qv0
lkkbd0 at dz0 line 0
wskbd* at lkkbd?
diff --git a/sys/arch/vax/conf/files.vax b/sys/arch/vax/conf/files.vax
index 68e5a365e26..18a3f143282 100644
--- a/sys/arch/vax/conf/files.vax
+++ b/sys/arch/vax/conf/files.vax
@@ -1,4 +1,4 @@
-# $OpenBSD: files.vax,v 1.36 2006/07/23 19:17:21 miod Exp $
+# $OpenBSD: files.vax,v 1.37 2006/07/24 20:35:06 miod Exp $
# $NetBSD: files.vax,v 1.60 1999/08/27 20:04:32 ragge Exp $
#
# new style config file for vax architecture
@@ -157,11 +157,21 @@ file arch/vax/vsa/ncr.c ncr needs-flag
attach le at vsbus with le_vsbus
file arch/vax/vsa/if_le_vsbus.c le_vsbus
-# Monochrome framebuffer on VS3100.
+# Monochrome (on-board) framebuffer on VS3100
device smg: wsemuldisplaydev, rasops1
attach smg at vsbus
file arch/vax/vsa/smg.c smg needs-flag
+# GPX framebuffer on VS3100
+device gpx: wsemuldisplaydev, rasops8
+attach gpx at vsbus
+file arch/vax/vsa/gpx.c gpx needs-flag
+
+# LCG framebuffer on KA46/KA48
+device lcg: wsemuldisplaydev, rasops8
+attach lcg at vsbus
+file arch/vax/vsa/lcg.c lcg needs-flag
+
device lkkbd: wskbddev
attach lkkbd at dz with dzkbd
file arch/vax/dec/dzkbd.c dzkbd needs-flag
@@ -170,10 +180,6 @@ device lkms: wsmousedev
attach lkms at dz with dzms
file arch/vax/dec/dzms.c dzms needs-flag
-#device lkc: qfont
-#attach lkc at dz
-#file arch/vax/vsa/lkc.c lkc needs-flag
-
# These devices aren't tested (or even compiled!)
# They are just included here to make some files happy ;)
#
diff --git a/sys/arch/vax/vax/conf.c b/sys/arch/vax/vax/conf.c
index 28b2e4ef747..7615d7b928e 100644
--- a/sys/arch/vax/vax/conf.c
+++ b/sys/arch/vax/vax/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.43 2004/02/10 01:31:21 millert Exp $ */
+/* $OpenBSD: conf.c,v 1.44 2006/07/24 20:35:08 miod Exp $ */
/* $NetBSD: conf.c,v 1.44 1999/10/27 16:38:54 ragge Exp $ */
/*-
@@ -144,24 +144,31 @@ int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]);
#include "wskbd.h"
#include "smg.h"
-#if NSMG > 0
+#include "lcg.h"
+#if NLCG > 0 || NSMG > 0
#if NWSKBD > 0
+#define lcgcngetc wskbd_cngetc
#define smgcngetc wskbd_cngetc
#else
static int
-smgcngetc(dev_t dev)
+dummycngetc(dev_t dev)
{
return 0;
}
+#define lcgcngetc dummycngetc
+#define smgcngetc dummycngetc
#endif /* NWSKBD > 0 */
-#endif /* NSMG > 0 */
+#endif /* NLCG > 0 || NSMG > 0 */
+#define lcgcnputc wsdisplay_cnputc
#define smgcnputc wsdisplay_cnputc
+#define lcgcnpollc nullcnpollc
#define smgcnpollc nullcnpollc
cons_decl(gen);
cons_decl(dz);
cons_decl(qd);
+cons_decl(lcg);
cons_decl(smg);
#include "qv.h"
#include "qd.h"
@@ -185,6 +192,9 @@ struct consdev constab[]={
cons_init(qd),
#endif
#endif
+#if NLCG
+ cons_init(lcg),
+#endif
#if NSMG
cons_init(smg),
#endif
@@ -566,7 +576,8 @@ getmajor(void *ptr)
for (i = 0; i < nchrdev; i++)
if (cdevsw[i].d_open == ptr)
return i;
- panic("getmajor");
+
+ return (-1);
}
dev_t
diff --git a/sys/arch/vax/vsa/lcg.c b/sys/arch/vax/vsa/lcg.c
new file mode 100644
index 00000000000..12b2e28f3b3
--- /dev/null
+++ b/sys/arch/vax/vsa/lcg.c
@@ -0,0 +1,655 @@
+/* $OpenBSD: lcg.c,v 1.1 2006/07/24 20:35:08 miod Exp $ */
+/*
+ * Copyright (c) 2006 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice, this permission notice, and the disclaimer below
+ * appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Copyright (c) 2003, 2004 Blaz Antonic
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the abovementioned copyrights
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+
+#include <machine/vsbus.h>
+#include <machine/scb.h>
+#include <machine/sid.h>
+#include <machine/cpu.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wscons_callbacks.h>
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/rasops/rasops.h>
+
+#include <vax/vsa/lcgreg.h>
+
+#define LCG_REG_ADDR 0x20100000 /* registers */
+#define LCG_REG_SIZE 0x4000
+#define LCG_CONFIG_ADDR 0x200f0010 /* configuration register */
+#define LCG_LUT_ADDR 0x21800800 /* colormap */
+#define LCG_LUT_OFFSET 0x0800
+#define LCG_LUT_SIZE 0x0800
+#define LCG_FB_ADDR 0x21801000 /* frame buffer */
+
+int lcg_match(struct device *, void *, void *);
+void lcg_attach(struct device *, struct device *, void *);
+
+struct lcg_screen {
+ struct rasops_info ss_ri;
+ u_int32_t ss_cfg;
+ u_int ss_width, ss_height, ss_depth;
+ u_int ss_fbsize; /* visible part only */
+ caddr_t ss_addr; /* frame buffer address */
+ vaddr_t ss_reg;
+ volatile u_int8_t *ss_lut;
+};
+
+/* for console */
+struct lcg_screen lcg_consscr;
+
+struct lcg_softc {
+ struct device sc_dev;
+ struct lcg_screen *sc_scr;
+ int sc_nscreens;
+};
+
+struct cfattach lcg_ca = {
+ sizeof(struct lcg_softc), lcg_match, lcg_attach,
+};
+
+struct cfdriver lcg_cd = {
+ NULL, "lcg", DV_DULL
+};
+
+struct wsscreen_descr lcg_stdscreen = {
+ "std",
+};
+
+const struct wsscreen_descr *_lcg_scrlist[] = {
+ &lcg_stdscreen,
+};
+
+const struct wsscreen_list lcg_screenlist = {
+ sizeof(_lcg_scrlist) / sizeof(struct wsscreen_descr *),
+ _lcg_scrlist,
+};
+
+int lcg_ioctl(void *, u_long, caddr_t, int, struct proc *);
+paddr_t lcg_mmap(void *, off_t, int);
+int lcg_alloc_screen(void *, const struct wsscreen_descr *,
+ void **, int *, int *, long *);
+void lcg_free_screen(void *, void *);
+int lcg_show_screen(void *, void *, int,
+ void (*) (void *, int, int), void *);
+void lcg_burner(void *, u_int, u_int);
+
+const struct wsdisplay_accessops lcg_accessops = {
+ lcg_ioctl,
+ lcg_mmap,
+ lcg_alloc_screen,
+ lcg_free_screen,
+ lcg_show_screen,
+ NULL, /* load_font */
+ NULL, /* scrollback */
+ NULL, /* getchar */
+ lcg_burner
+};
+
+int lcg_alloc_attr(void *, int, int, int, long *);
+u_int lcg_probe_screen(u_int32_t, u_int *, u_int *);
+void lcg_resetcmap(struct lcg_screen *);
+void lcg_set_lut_entry(volatile u_int8_t *, const u_char *, u_int, u_int);
+int lcg_setup_screen(struct lcg_screen *);
+
+#define lcg_read_reg(ss, regno) \
+ *(volatile u_int32_t *)((ss)->ss_reg + (regno))
+#define lcg_write_reg(ss, regno, val) \
+ *(volatile u_int32_t *)((ss)->ss_reg + (regno)) = (val)
+
+int
+lcg_match(struct device *parent, void *vcf, void *aux)
+{
+ struct vsbus_softc *sc = (void *)parent;
+ struct vsbus_attach_args *va = aux;
+ vaddr_t cfgreg;
+ int depth;
+ volatile u_int8_t *ch;
+
+ switch (vax_boardtype) {
+ default:
+ return (0);
+
+ case VAX_BTYP_46:
+ case VAX_BTYP_48:
+ if (va->va_paddr != LCG_REG_ADDR)
+ return (0);
+
+ break;
+ }
+
+ /*
+ * Check for a recognized configuration.
+ */
+ cfgreg = vax_map_physmem(LCG_CONFIG_ADDR, 1);
+ depth = lcg_probe_screen(*(volatile u_int32_t *)cfgreg, NULL, NULL);
+ vax_unmap_physmem(cfgreg, 1);
+ if (depth == 0)
+ return (0);
+
+ /*
+ * Check for video memory.
+ * We can not use badaddr() on these models.
+ */
+ ch = (volatile u_int8_t *)va->va_addr;
+ *ch = 0x01;
+ if ((*ch & 0x01) == 0)
+ return (0);
+ *ch = 0x00;
+ if ((*ch & 0x01) != 0)
+ return (0);
+
+ sc->sc_mask = 0x04; /* XXX - should be generated */
+ scb_fake(0x120, 0x15);
+ return (20);
+}
+
+void
+lcg_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct lcg_softc *sc = (struct lcg_softc *)self;
+ struct lcg_screen *ss;
+ struct wsemuldisplaydev_attach_args aa;
+ vaddr_t tmp;
+ int console;
+
+ console = (vax_confdata & 0x100) == 0;
+ if (console) {
+ ss = &lcg_consscr;
+ sc->sc_nscreens = 1;
+ } else {
+ ss = malloc(sizeof(struct lcg_screen), M_DEVBUF, M_NOWAIT);
+ if (ss == NULL) {
+ printf(": can not allocate memory\n");
+ return;
+ }
+ bzero(ss, sizeof(struct lcg_screen));
+
+ tmp = vax_map_physmem(LCG_CONFIG_ADDR, 1);
+ if (tmp == NULL) {
+ printf(": can not map configuration register\n");
+ goto fail1;
+ }
+ ss->ss_cfg = *(volatile u_int32_t *)tmp;
+ vax_unmap_physmem(tmp, 1);
+
+ ss->ss_depth = lcg_probe_screen(ss->ss_cfg,
+ &ss->ss_width, &ss->ss_height);
+ ss->ss_fbsize =
+ roundup(ss->ss_width * ss->ss_height, VAX_NBPG);
+
+ ss->ss_addr = (caddr_t)vax_map_physmem(LCG_FB_ADDR,
+ ss->ss_fbsize / VAX_NBPG);
+ if (ss->ss_addr == NULL) {
+ printf(": can not map frame buffer\n");
+ goto fail1;
+ }
+
+ ss->ss_reg = vax_map_physmem(LCG_REG_ADDR,
+ LCG_REG_SIZE / VAX_NBPG);
+ if (ss->ss_reg == 0L) {
+ printf(": can not map registers\n");
+ goto fail2;
+ }
+
+ ss->ss_lut = (u_int8_t *)vax_map_physmem(LCG_LUT_ADDR,
+ LCG_LUT_SIZE / VAX_NBPG);
+ if (ss->ss_lut == NULL) {
+ printf(": can not map color LUT\n");
+ goto fail3;
+ }
+
+ if (lcg_setup_screen(ss) != 0) {
+ printf(": initialization failed\n");
+ goto fail4;
+ }
+ }
+ sc->sc_scr = ss;
+
+ printf(": %dx%dx%d frame buffer\n",
+ ss->ss_width, ss->ss_height, ss->ss_depth);
+
+ aa.console = console;
+ aa.scrdata = &lcg_screenlist;
+ aa.accessops = &lcg_accessops;
+ aa.accesscookie = sc;
+
+ config_found(self, &aa, wsemuldisplaydevprint);
+ return;
+
+fail4:
+ vax_unmap_physmem((vaddr_t)ss->ss_lut, LCG_LUT_SIZE / VAX_NBPG);
+fail3:
+ vax_unmap_physmem(ss->ss_reg, LCG_REG_SIZE / VAX_NBPG);
+fail2:
+ vax_unmap_physmem((vaddr_t)ss->ss_addr, ss->ss_fbsize / VAX_NBPG);
+fail1:
+ free(ss, M_DEVBUF);
+}
+
+/*
+ * Determine if we have a recognized frame buffer, its resolution and
+ * color depth.
+ */
+u_int
+lcg_probe_screen(u_int32_t cfg, u_int *width, u_int *height)
+{
+ u_int w, h, d = 8;
+
+ switch (vax_boardtype) {
+ case VAX_BTYP_46:
+ switch (cfg & 0xf0) {
+ case 0x20:
+ case 0x60:
+ w = 1024; h = 864;
+ break;
+ case 0x40:
+ w = 1024; h = 768;
+ break;
+ case 0x80:
+ d = 4;
+ /* FALLTHROUGH */
+ case 0x90:
+ case 0xb0:
+ w = 1280; h = 1024;
+ break;
+ default:
+ return (0);
+ }
+ break;
+ case VAX_BTYP_48:
+ switch (cfg & 0x07) {
+ case 0x05:
+ w = 1280; h = 1024;
+ break;
+ case 0x06:
+ if (vax_confdata & 0x80) {
+ w = 1024; h = 768;
+ } else {
+ w = 640; h = 480;
+ }
+ break;
+ case 0x07:
+ if (vax_confdata & 0x80) {
+ w = 1024; h = 864;
+ } else {
+ w = 1024; h = 768;
+ }
+ break;
+ default:
+ return (0);
+ }
+ break;
+ }
+
+ if (width != NULL)
+ *width = w;
+ if (height != NULL)
+ *height = h;
+
+ return (d);
+}
+
+/*
+ * Initialize anything necessary for an emulating wsdisplay to work (i.e.
+ * pick a font, initialize a rasops structure, setup the accessops callbacks.)
+ */
+int
+lcg_setup_screen(struct lcg_screen *ss)
+{
+ struct rasops_info *ri = &ss->ss_ri;
+
+ bzero(ri, sizeof(*ri));
+ /*
+ * Since the frame buffer memory is byte addressed, even in low-bpp
+ * mode, initialize a 8bpp rasops engine. We will report a shorter
+ * colormap if necessary, which will allow X to do TRT.
+ */
+ ri->ri_depth = 8;
+ ri->ri_width = ss->ss_width;
+ ri->ri_height = ss->ss_height;
+ ri->ri_stride = ss->ss_width;
+ ri->ri_flg = RI_CLEAR | RI_CENTER;
+ ri->ri_bits = (void *)ss->ss_addr;
+ ri->ri_hw = ss;
+
+ /*
+ * We can let rasops select our font here, as we do not need to
+ * use a font with a different bit order than rasops' defaults,
+ * unlike smg.
+ */
+
+ /*
+ * Ask for an unholy big display, rasops will trim this to more
+ * reasonable values.
+ */
+ if (rasops_init(ri, 160, 160) != 0)
+ return (-1);
+
+ lcg_resetcmap(ss);
+ if (ss->ss_depth < 8) {
+ ri->ri_ops.alloc_attr = lcg_alloc_attr;
+ ri->ri_caps &= ~WSSCREEN_HILIT;
+ }
+
+ lcg_stdscreen.ncols = ri->ri_cols;
+ lcg_stdscreen.nrows = ri->ri_rows;
+ lcg_stdscreen.textops = &ri->ri_ops;
+ lcg_stdscreen.fontwidth = ri->ri_font->fontwidth;
+ lcg_stdscreen.fontheight = ri->ri_font->fontheight;
+ lcg_stdscreen.capabilities = ri->ri_caps;
+
+ return (0);
+}
+
+int
+lcg_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ struct lcg_softc *sc = v;
+ struct lcg_screen *ss = sc->sc_scr;
+ struct wsdisplay_fbinfo *wdf;
+
+ switch (cmd) {
+ case WSDISPLAYIO_GTYPE:
+ *(u_int *)data = WSDISPLAY_TYPE_LCG;
+ break;
+
+ case WSDISPLAYIO_GINFO:
+ wdf = (struct wsdisplay_fbinfo *)data;
+ wdf->height = ss->ss_height;
+ wdf->width = ss->ss_width;
+ wdf->depth = 8;
+ wdf->cmsize = 1 << ss->ss_depth;
+ break;
+
+ case WSDISPLAYIO_LINEBYTES:
+ *(u_int *)data = ss->ss_ri.ri_stride;
+ break;
+
+ case WSDISPLAYIO_GETCMAP:
+ case WSDISPLAYIO_PUTCMAP:
+ break; /* XXX TBD */
+
+ case WSDISPLAYIO_GVIDEO:
+ case WSDISPLAYIO_SVIDEO:
+ break;
+
+ default:
+ return (-1);
+ }
+
+ return (0);
+}
+
+paddr_t
+lcg_mmap(void *v, off_t offset, int prot)
+{
+ struct lcg_softc *sc = v;
+ struct lcg_screen *ss = sc->sc_scr;
+
+ if (offset >= ss->ss_fbsize || offset < 0)
+ return (-1);
+
+ return (LCG_FB_ADDR + offset) >> PGSHIFT;
+}
+
+int
+lcg_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
+ int *curxp, int *curyp, long *defattrp)
+{
+ struct lcg_softc *sc = v;
+ struct lcg_screen *ss = sc->sc_scr;
+ struct rasops_info *ri = &ss->ss_ri;
+
+ if (sc->sc_nscreens > 0)
+ return (ENOMEM);
+
+ *cookiep = ri;
+ *curxp = *curyp = 0;
+ ri->ri_ops.alloc_attr(ri, 0, 0, 0, defattrp);
+ sc->sc_nscreens++;
+
+ return (0);
+}
+
+void
+lcg_free_screen(void *v, void *cookie)
+{
+ struct lcg_softc *sc = v;
+
+ sc->sc_nscreens--;
+}
+
+int
+lcg_show_screen(void *v, void *cookie, int waitok,
+ void (*cb)(void *, int, int), void *cbarg)
+{
+ return (0);
+}
+
+void
+lcg_burner(void *v, u_int on, u_int flags)
+{
+ struct lcg_softc *sc = v;
+ struct lcg_screen *ss = sc->sc_scr;
+ u_int32_t vidcfg;
+
+ vidcfg = lcg_read_reg(ss, LCG_REG_VIDEO_CONFIG);
+ if (on)
+ vidcfg |= 1 << 1;
+ else
+ vidcfg &= ~(1 << 1);
+ lcg_write_reg(ss, LCG_REG_VIDEO_CONFIG, vidcfg);
+}
+
+/*
+ * Attribute allocator for 4bpp frame buffers.
+ * In such modes, highlighting is not available.
+ */
+int
+lcg_alloc_attr(void *cookie, int fg, int bg, int flg, long *attr)
+{
+ extern int rasops_alloc_cattr(void *, int, int, int, long *);
+
+ if ((flg & (WSATTR_BLINK | WSATTR_HILIT)) != 0)
+ return (EINVAL);
+
+ return (rasops_alloc_cattr(cookie, fg, bg, flg, attr));
+}
+
+/*
+ * Fill the given colormap (LUT) entry.
+ */
+void
+lcg_set_lut_entry(volatile u_int8_t *lutptr, const u_char *cmap, u_int idx,
+ u_int shift)
+{
+ lutptr++;
+ *lutptr++ = idx;
+ *lutptr++ = 1;
+ *lutptr++ = (*cmap++) >> shift;
+ *lutptr++ = 1;
+ *lutptr++ = (*cmap++) >> shift;
+ *lutptr++ = 1;
+ *lutptr++ = (*cmap++) >> shift;
+}
+
+void
+lcg_resetcmap(struct lcg_screen *ss)
+{
+ const u_char *color;
+ u_int i;
+ volatile u_int8_t *lutptr;
+ u_int32_t vidcfg;
+
+ vidcfg = lcg_read_reg(ss, LCG_REG_VIDEO_CONFIG);
+ color = rasops_cmap;
+ lutptr = ss->ss_lut;
+ if (ss->ss_depth == 8) {
+ for (i = 0; i < 256; i++) {
+ lcg_set_lut_entry(lutptr, color, i, 0);
+ lutptr += 8;
+ color += 3;
+ }
+ } else {
+ for (i = 0; i < 8; i++) {
+ lcg_set_lut_entry(lutptr, color, i, 4);
+ lutptr += 8;
+ color += 3;
+ }
+ color = rasops_cmap + 0xf8 * 3;
+ for (i = 0xf8; i < 0x100; i++) {
+ lcg_set_lut_entry(lutptr, color, i & 0x0f, 4);
+ lutptr += 8;
+ color += 3;
+ }
+ }
+ vidcfg &= ~((1 << 5) | (3 << 8) | (1 << 11));
+ if (ss->ss_width == 1280) /* XXX is this right? */
+ vidcfg |= (0 << 5) | (2 << 8) | (0 << 11);
+ else
+ vidcfg |= (1 << 5) | (1 << 8) | (1 << 11);
+ lcg_write_reg(ss, LCG_REG_VIDEO_CONFIG, vidcfg);
+ lcg_write_reg(ss, LCG_REG_LUT_CONSOLE_SEL, 1);
+ lcg_write_reg(ss, LCG_REG_LUT_COLOR_BASE_W, LCG_LUT_OFFSET);
+ DELAY(1000); /* XXX should wait on a status bit */
+ lcg_write_reg(ss, LCG_REG_LUT_CONSOLE_SEL, 0);
+}
+
+#include <dev/cons.h>
+cons_decl(lcg);
+
+#include "dzkbd.h"
+
+#include <vax/qbus/dzreg.h>
+#include <vax/qbus/dzvar.h>
+#include <vax/dec/dzkbdvar.h>
+
+
+/*
+ * Called very early to setup the glass tty as console.
+ * Because it's called before the VM system is initialized, virtual memory
+ * for the framebuffer can be stolen directly without disturbing anything.
+ */
+void
+lcgcnprobe(cndev)
+ struct consdev *cndev;
+{
+ struct lcg_screen *ss = &lcg_consscr;
+ extern vaddr_t virtual_avail;
+ extern int getmajor(void *); /* conf.c */
+ vaddr_t tmp;
+
+ switch (vax_boardtype) {
+ case VAX_BTYP_46:
+ case VAX_BTYP_48:
+ if ((vax_confdata & 0x100) != 0)
+ break; /* doesn't use graphics console */
+
+ tmp = virtual_avail;
+ ioaccess(tmp, LCG_CONFIG_ADDR, 1);
+ ss->ss_cfg = *(volatile u_int32_t *)tmp;
+
+ ss->ss_depth = lcg_probe_screen(ss->ss_cfg,
+ &ss->ss_width, &ss->ss_height);
+ if (ss->ss_depth == 0)
+ break; /* unsupported configuration */
+
+ ss->ss_fbsize =
+ roundup(ss->ss_width * ss->ss_height, VAX_NBPG);
+
+ ss->ss_addr = (caddr_t)virtual_avail;
+ virtual_avail += ss->ss_fbsize;
+ ioaccess((vaddr_t)ss->ss_addr, LCG_FB_ADDR,
+ ss->ss_fbsize / VAX_NBPG);
+
+ ss->ss_reg = virtual_avail;
+ virtual_avail += LCG_REG_SIZE;
+ ioaccess(ss->ss_reg, LCG_REG_ADDR,
+ LCG_REG_SIZE / VAX_NBPG);
+
+ ss->ss_lut = (u_int8_t *)virtual_avail;
+ virtual_avail += LCG_LUT_SIZE;
+ ioaccess((vaddr_t)ss->ss_lut, LCG_LUT_ADDR,
+ LCG_LUT_SIZE / VAX_NBPG);
+
+ cndev->cn_pri = CN_INTERNAL;
+ cndev->cn_dev = makedev(getmajor(wsdisplayopen), 0);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void
+lcgcninit(struct consdev *cndev)
+{
+ struct lcg_screen *ss = &lcg_consscr;
+ long defattr;
+ struct rasops_info *ri;
+ extern void lkccninit(struct consdev *);
+ extern int lkccngetc(dev_t);
+ extern int dz_vsbus_lk201_cnattach(int);
+
+ /* mappings have been done in lcgcnprobe() */
+ if (lcg_setup_screen(ss) != 0)
+ return;
+
+ ri = &ss->ss_ri;
+ ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr);
+ wsdisplay_cnattach(&lcg_stdscreen, ri, 0, 0, defattr);
+
+#if NDZKBD > 0
+ dzkbd_cnattach(0); /* Connect keyboard and screen together */
+#endif
+}
diff --git a/sys/arch/vax/vsa/lcgreg.h b/sys/arch/vax/vsa/lcgreg.h
new file mode 100644
index 00000000000..2ba55951aee
--- /dev/null
+++ b/sys/arch/vax/vsa/lcgreg.h
@@ -0,0 +1,191 @@
+/* $OpenBSD: lcgreg.h,v 1.1 2006/07/24 20:35:08 miod Exp $ */
+/* $NetBSD: lcgreg.h,v 1.4 2005/12/11 12:19:34 christos Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas of 3am Software Foundry.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * The registers of the LCG used in the VS4000/60 and VS4000/VLC.
+ * All relative to 0x20100000
+ */
+
+/* Memory Control, Flow Control, Configuration Registers
+ */
+#define LCG_REG_MEM_CONFIG 0x001800
+#define LCG_REG_MEM_STATUS 0x001804
+#define LCG_REG_MEM_CURRENT_STATE 0x001808
+#define LCG_REG_MEM_ERROR 0x00180c
+#define LCG_REG_SLOW_CONTROL_STATUS 0x001810
+
+/* Video Control Registers
+ */
+#define LCG_REG_VIDEO_CONFIG 0x001e00
+#define LCG_REG_VIDEO_HTIMING 0x001e10
+#define LCG_REG_VIDEO_VTIMING 0x001e14
+#define LCG_REG_VIDEO_TIMING 0x001e18
+#define LCG_REG_VIDEO_X 0x000e30
+#define LCG_REG_VIDEO_Y 0x000e30
+#define LCG_REG_VIDEO_REFRESH_BASE 0x000e34
+#define LCG_REG_VIDEO_REFRESH_SHIFT 0x000e40
+#define LCG_REG_VIDEO_LUT_LOAD_COUNT 0x000e40
+#define LCG_REG_CURSOR_SCANLINE_LW0 0x000e50
+#define LCG_REG_CURSOR_SCANLINE_LW1 0x000e54
+#define LCG_REG_CURSOR_SCANLINE_LW2 0x000e58
+#define LCG_REG_CURSOR_SCANLINE_LW3 0x000e5c
+#define LCG_REG_CURSOR_BASE 0x000e80
+#define LCG_REG_CURSOR_XY 0x000e84
+#define LCG_REG_CURSOR_X 0x000e84
+#define LCG_REG_CURSOR_Y 0x000e84
+#define LCG_REG_LUT_CONSOLE_SEL 0x000ee0
+#define LCG_REG_LUT_COLOR_BASE_W 0x0006e4
+#define LCG_REG_LUT_COLOR_BASE_R 0x0006e4
+#define LCG_REG_LUT_CONTROL_BASE 0x000ee8
+#define LCG_REG_VIDEO_COUNTER_TEST 0x000f00
+#define LCG_REG_MEM_REFRESH_BASE 0x000f04
+
+/* Graphics Control and VM Registers
+ */
+#define LCG_REG_LCG_GO 0x000c80
+#define LCG_REG_NEXT_ADDRESS 0x001334
+#define LCG_REG_PA_SPTE_PTE 0x001338
+#define LCG_REG_TB_INVALIDATE_SINGLE 0x001a00
+#define LCG_REG_TB_INVALIDATE_ALL 0x001a08
+#define LCG_REG_TB_INVALIDATE_STATUS 0x001a10
+#define LCG_REG_TB_STATUS 0x001c00
+#define LCG_REG_TB_VPN_COUNT 0x001c04
+#define LCG_REG_TB_DEST_VPN 0x001c14
+#define LCG_REG_TB_SOURCE_VPN 0x001c18
+#define LCG_REG_TB_STENCIL_VPN 0x001c1c
+#define LCG_REG_TB_DEST_DATA_PFN_R 0x001c24
+#define LCG_REG_TB_DEST_DATA_PFN_W 0x001c24
+#define LCG_REG_TB_SOURCE_DATA_PFN_R 0x001c28
+#define LCG_REG_TB_SOURCE_DATA_PFN_W 0x001c28
+#define LCG_REG_TB_STENCIL_DATA_PFN_R 0x001c2c
+#define LCG_REG_TB_STENCIL_DATA_PFN_W 0x001c2c
+#define LCG_REG_TB_DEST_PRE_PFN_R 0x001c34
+#define LCG_REG_TB_DEST_PRE_PFN_W 0x001c34
+#define LCG_REG_TB_SOURCE_PTE_PFN_R 0x001c38
+#define LCG_REG_TB_SOURCE_PTE_PFN_W 0x001c38
+#define LCG_REG_TB_STENCIL_PTE_PFN_R 0x001c3c
+#define LCG_REG_TB_STENCIL_PTE_PFN_W 0x001c3c
+#define LCG_REG_GRAPHICS_CONFIG 0x001c90
+#define LCG_REG_GRAPHICS_INT_STATUS 0x001c94
+#define LCG_REG_GRAPHICS_INT_SET_ENABLE 0x001c98
+#define LCG_REG_GRAPHICS_INT_CLR_ENABLE 0x001c9c
+#define LCG_REG_GRAPHICS_SUB_STATUS 0x001ca0
+#define LCG_REG_GRAPHICS_CONTROL 0x001ca4
+#define LCG_REG_BREAKPT_ADDRESS 0x001cb0
+#define LCG_REG_BREAKPT_VIRTUAL 0x001cb0
+#define LCG_REG_WRITE_PROTECT_LOW_HIGH 0x001cc0
+#define LCG_REG_WRITE_PROTECT_LOW 0x001cc0
+#define LCG_REG_WRITE_PROTECT_HIGH 0x001cc0
+#define LCG_REG_MAX_VIRTUAL_ADDRESS 0x002350
+#define LCG_REG_PA_SPTE_POBR 0x002354
+
+/* Clip List / Command FIFO Registers
+ */
+#define LCG_REG_CLIP_LIST_OFFSET 0x0004e4
+#define LCG_REG_CLIP_LIST_BASE 0x0004e4
+#define LCG_REG_CLIP_LIST 0x0004e4
+#define LCG_REG_FIFO_MASKS 0x000570
+#define LCG_REG_FIFO_HEAD_OFFSET 0x000574
+#define LCG_REG_FIFO_BASE 0x000574
+#define LCG_REG_FIFO_HEAD 0x000574
+#define LCG_REG_FIFO_TAIL_OFFSET 0x000578
+#define LCG_REG_FIFO_BASE2 0x000578
+#define LCG_REG_FIFO_TAIL 0x000578
+#define LCG_REG_CLIP_LIST_SAVE_OFFSET 0x000ce4
+#define LCG_REG_FIFO_RESIDUE_LW0 0x000d04
+#define LCG_REG_FIFO_RESIDUE_LW1 0x000d08
+#define LCG_REG_FIFO_RESIDUE_LW2 0x000d0c
+#define LCG_REG_FIFO_LENGTH 0x000d70
+#define LCG_REG_FIFO_SAVE_HEAD_OFFSET 0x000d74
+#define LCG_REG_FIFO_WINDOW_BASE 0x080000
+#define LCG_REG_FIFO_WINDOW_END 0x100000
+
+/* Graphics Data Buffer and Pixel SLU Registers
+ */
+#define LCG_REG_LOGICAL_FUNCTION 0x000220
+#define LCG_REG_PLANE_MASK 0x000234
+#define LCG_REG_SOURCE_PLANE_INDEX 0x00026c
+#define LCG_REG_FOREGROUND_PIXEL 0x0002c0
+#define LCG_REG_BACKGROUND_PIXEL 0x0004c0
+#define LCG_REG_GDB_LW0 0x000d80
+#define LCG_REG_GDB_LW1 0x000d84
+#define LCG_REG_GDB_LW2 0x000d88
+#define LCG_REG_GDB_LW3 0x000d8c
+#define LCG_REG_GDB_LW4 0x000d90
+#define LCG_REG_GDB_LW5 0x000d94
+#define LCG_REG_GDB_LW6 0x000d98
+#define LCG_REG_GDB_LW7 0x000d9c
+#define LCG_REG_SLU_STATE 0x000da0
+
+/* Address Generator Registers
+ */
+#define LCG_REG_CLIP_MIN_Y 0x000244
+#define LCG_REG_CLIP_MIN_MAX_X 0x000248
+#define LCG_REG_CLIP_MIN_X 0x000248
+#define LCG_REG_CLIP_MAX_X 0x000248
+#define LCG_REG_CLIP_MAX_Y 0x00024c
+#define LCG_REG_DEST_X_BIAS 0x000250
+#define LCG_REG_DEST_Y_ORIGIN 0x000254
+#define LCG_REG_DEST_Y_STEP 0x000258
+#define LCG_REG_SOURCE_X_BIAS 0x000260
+#define LCG_REG_SOURCE_Y_BASE 0x000264
+#define LCG_REG_SOURCE_Y_STEP_WIDTH 0x000268
+#define LCG_REG_SOURCE_Y_STEP 0x000268
+#define LCG_REG_SOURCE_WIDTH 0x000268
+#define LCG_REG_STENCIL_X_BIAS 0x000270
+#define LCG_REG_STENCIL_Y_BASE 0x000274
+#define LCG_REG_STENCIL_Y_STEP 0x000278
+#define LCG_REG_DEST_Y_BASE 0x000284
+#define LCG_REG_DEST_X 0x000290
+#define LCG_REG_DEST_WIDTH_HEIGHT 0x000294
+#define LCG_REG_DEST_WIDTH 0x000294
+#define LCG_REG_DEST_HEIGHT 0x000294
+#define LCG_REG_AG_STATUS2 0x000320
+#define LCG_REG_AG_CURRENT_STATE 0x000320
+#define LCG_REG_CURRENT_OPCODE 0x000320
+#define LCG_REG_OP_ACTION_CODE 0x000320
+#define LCG_REG_AG_STATUS 0x000324
+#define LCG_REG_NEXT_X 0x000330
+#define LCG_REG_CLIP_X_DIFF 0x000330
+#define LCG_REG_SOURCE_X_BIAS0 0x000460
+#define LCG_REG_SOURCE_WIDTH0 0x000468
+#define LCG_REG_DEST_X0 0x000490
+#define LCG_REG_DEST_WIDTH0 0x000494
+#define LCG_REG_TILE_ROTATION 0x000660
+#define LCG_REG_TILE_WIDTH 0x000668