diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2006-07-24 20:35:09 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2006-07-24 20:35:09 +0000 |
commit | d4567ce267be20d900513e1d0fd2f179dc7bd3b8 (patch) | |
tree | 15fb0c7805e7c816f8fd8aef698a561b52988abb /sys | |
parent | b8b1809bfab62d1f228d3281549039c26171d76a (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/GENERIC | 16 | ||||
-rw-r--r-- | sys/arch/vax/conf/files.vax | 18 | ||||
-rw-r--r-- | sys/arch/vax/vax/conf.c | 21 | ||||
-rw-r--r-- | sys/arch/vax/vsa/lcg.c | 655 | ||||
-rw-r--r-- | sys/arch/vax/vsa/lcgreg.h | 191 |
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 |