diff options
-rw-r--r-- | sbin/wsconsctl/util.c | 5 | ||||
-rw-r--r-- | sys/arch/vax/conf/GENERIC | 6 | ||||
-rw-r--r-- | sys/arch/vax/conf/files.vax | 7 | ||||
-rw-r--r-- | sys/arch/vax/vax/conf.c | 17 | ||||
-rw-r--r-- | sys/arch/vax/vsa/lcspx.c | 457 | ||||
-rw-r--r-- | sys/dev/wscons/wsconsio.h | 3 |
6 files changed, 485 insertions, 10 deletions
diff --git a/sbin/wsconsctl/util.c b/sbin/wsconsctl/util.c index 86cfa18383e..5b34108a298 100644 --- a/sbin/wsconsctl/util.c +++ b/sbin/wsconsctl/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.33 2006/04/14 21:05:43 miod Exp $ */ +/* $OpenBSD: util.c,v 1.34 2006/07/24 22:19:52 miod Exp $ */ /* $NetBSD: util.c,v 1.8 2000/03/14 08:11:53 sato Exp $ */ /*- @@ -142,7 +142,8 @@ static const struct nameint dpytype_tab[] = { { WSDISPLAY_TYPE_PXALCD, "pxalcd" }, { WSDISPLAY_TYPE_MAC68K, "mac68k" }, { WSDISPLAY_TYPE_SUNLEO, "sunleo" }, - { WSDISPLAY_TYPE_TVRX, "tvrx" } + { WSDISPLAY_TYPE_TVRX, "tvrx" }, + { WSDISPLAY_TYPE_LCSPX, "dec-lcspx" } }; static const struct nameint kbdenc_tab[] = { diff --git a/sys/arch/vax/conf/GENERIC b/sys/arch/vax/conf/GENERIC index 989174509b5..6d2df195558 100644 --- a/sys/arch/vax/conf/GENERIC +++ b/sys/arch/vax/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.42 2006/07/24 20:35:06 miod Exp $ +# $OpenBSD: GENERIC,v 1.43 2006/07/24 22:19:54 miod Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -71,6 +71,7 @@ asc0 at vsbus0 csr 0x26000080 # VS4000/90 4000/10X MV3100/9X SCSI 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 +lcspx0 at vsbus0 csr 0x39302000 # VS4000/90 frame buffer #hd* at hdc0 drive? # RD5x disks #ry* at hdc0 drive? # RX floppies @@ -143,9 +144,10 @@ ses* at scsibus? uk* at scsibus? # Workstation console -wsdisplay* at smg? #wsdisplay* at gpx? wsdisplay* at lcg? +wsdisplay* at lcspx? +wsdisplay* at smg? #wsdisplay* at qd0 #wsdisplay* at qv0 diff --git a/sys/arch/vax/conf/files.vax b/sys/arch/vax/conf/files.vax index 18a3f143282..3eebda21fb4 100644 --- a/sys/arch/vax/conf/files.vax +++ b/sys/arch/vax/conf/files.vax @@ -1,4 +1,4 @@ -# $OpenBSD: files.vax,v 1.37 2006/07/24 20:35:06 miod Exp $ +# $OpenBSD: files.vax,v 1.38 2006/07/24 22:19:54 miod Exp $ # $NetBSD: files.vax,v 1.60 1999/08/27 20:04:32 ragge Exp $ # # new style config file for vax architecture @@ -172,6 +172,11 @@ device lcg: wsemuldisplaydev, rasops8 attach lcg at vsbus file arch/vax/vsa/lcg.c lcg needs-flag +# LCSPX framebuffer on KA49 +device lcspx: wsemuldisplaydev, rasops8 +attach lcspx at vsbus +file arch/vax/vsa/lcspx.c lcspx needs-flag + device lkkbd: wskbddev attach lkkbd at dz with dzkbd file arch/vax/dec/dzkbd.c dzkbd needs-flag diff --git a/sys/arch/vax/vax/conf.c b/sys/arch/vax/vax/conf.c index 7615d7b928e..07f82f0eca8 100644 --- a/sys/arch/vax/vax/conf.c +++ b/sys/arch/vax/vax/conf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.c,v 1.44 2006/07/24 20:35:08 miod Exp $ */ +/* $OpenBSD: conf.c,v 1.45 2006/07/24 22:19:54 miod Exp $ */ /* $NetBSD: conf.c,v 1.44 1999/10/27 16:38:54 ragge Exp $ */ /*- @@ -143,11 +143,13 @@ int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]); #include <dev/cons.h> #include "wskbd.h" -#include "smg.h" #include "lcg.h" -#if NLCG > 0 || NSMG > 0 +#include "lcspx.h" +#include "smg.h" +#if NLCG > 0 || NLCSPX > 0 || NSMG > 0 #if NWSKBD > 0 #define lcgcngetc wskbd_cngetc +#define lcspxcngetc wskbd_cngetc #define smgcngetc wskbd_cngetc #else static int @@ -156,19 +158,23 @@ dummycngetc(dev_t dev) return 0; } #define lcgcngetc dummycngetc +#define lcspxcngetc dummycngetc #define smgcngetc dummycngetc #endif /* NWSKBD > 0 */ -#endif /* NLCG > 0 || NSMG > 0 */ +#endif /* NLCG > 0 || NLCSPX > 0 || NSMG > 0 */ #define lcgcnputc wsdisplay_cnputc +#define lcspxcnputc wsdisplay_cnputc #define smgcnputc wsdisplay_cnputc #define lcgcnpollc nullcnpollc +#define lcspxcnpollc nullcnpollc #define smgcnpollc nullcnpollc cons_decl(gen); cons_decl(dz); cons_decl(qd); cons_decl(lcg); +cons_decl(lcspx); cons_decl(smg); #include "qv.h" #include "qd.h" @@ -195,6 +201,9 @@ struct consdev constab[]={ #if NLCG cons_init(lcg), #endif +#if NLCSPX + cons_init(lcspx), +#endif #if NSMG cons_init(smg), #endif diff --git a/sys/arch/vax/vsa/lcspx.c b/sys/arch/vax/vsa/lcspx.c new file mode 100644 index 00000000000..be61cebe19f --- /dev/null +++ b/sys/arch/vax/vsa/lcspx.c @@ -0,0 +1,457 @@ +/* $OpenBSD: lcspx.c,v 1.1 2006/07/24 22:19:54 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) 2004 Blaz Antonic + * All rights reserved. + * + * This software contains code written by Michael L. Hitch. + * + * 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 <dev/ic/bt463reg.h> /* actually it's a 459 here... */ + +#define LCSPX_REG_ADDR 0x39302000 /* registers */ +#define LCSPX_REG1_ADDR 0x39b00000 /* more registers */ +#define LCSPX_RAMDAC_ADDR 0x39b10000 /* RAMDAC */ +#define LCSPX_RAMDAC_INTERLEAVE 0x00004000 +#define LCSPX_FB_ADDR 0x38000000 /* frame buffer */ + +#define LCSPX_WIDTH 1280 +#define LCSPX_HEIGHT 1024 +#define LCSPX_FBSIZE (LCSPX_WIDTH * LCSPX_HEIGHT) + +int lcspx_match(struct device *, void *, void *); +void lcspx_attach(struct device *, struct device *, void *); + +struct lcspx_screen { + struct rasops_info ss_ri; + caddr_t ss_addr; /* frame buffer address */ + volatile u_int8_t *ss_ramdac[4]; +}; + +/* for console */ +struct lcspx_screen lcspx_consscr; + +struct lcspx_softc { + struct device sc_dev; + struct lcspx_screen *sc_scr; + int sc_nscreens; +}; + +struct cfattach lcspx_ca = { + sizeof(struct lcspx_softc), lcspx_match, lcspx_attach, +}; + +struct cfdriver lcspx_cd = { + NULL, "lcspx", DV_DULL +}; + +struct wsscreen_descr lcspx_stdscreen = { + "std", +}; + +const struct wsscreen_descr *_lcspx_scrlist[] = { + &lcspx_stdscreen, +}; + +const struct wsscreen_list lcspx_screenlist = { + sizeof(_lcspx_scrlist) / sizeof(struct wsscreen_descr *), + _lcspx_scrlist, +}; + +int lcspx_ioctl(void *, u_long, caddr_t, int, struct proc *); +paddr_t lcspx_mmap(void *, off_t, int); +int lcspx_alloc_screen(void *, const struct wsscreen_descr *, + void **, int *, int *, long *); +void lcspx_free_screen(void *, void *); +int lcspx_show_screen(void *, void *, int, + void (*) (void *, int, int), void *); + +const struct wsdisplay_accessops lcspx_accessops = { + lcspx_ioctl, + lcspx_mmap, + lcspx_alloc_screen, + lcspx_free_screen, + lcspx_show_screen, + NULL, /* load_font */ + NULL, /* scrollback */ + NULL, /* getchar */ + NULL /* burner */ +}; + +void lcspx_resetcmap(struct lcspx_screen *); +int lcspx_setup_screen(struct lcspx_screen *); + +int +lcspx_match(struct device *parent, void *vcf, void *aux) +{ + struct vsbus_softc *sc = (void *)parent; + struct vsbus_attach_args *va = aux; + volatile u_int8_t *ch; + int rc; + + switch (vax_boardtype) { + default: + return (0); + + case VAX_BTYP_49: + if (va->va_paddr != LCSPX_REG_ADDR) + return (0); + + break; + } + + /* + * Check for video memory. + * We can not use badaddr() on these models. + */ + ch = (volatile u_int8_t *)vax_map_physmem(LCSPX_FB_ADDR, 1); + rc = 1; + *ch = 0x01; + if ((*ch & 0x01) == 0) + rc = 0; + *ch = 0x00; + if ((*ch & 0x01) != 0) + rc = 0; + vax_unmap_physmem((vaddr_t)ch, 1); + + sc->sc_mask = 0x04; /* XXX - should be generated */ + scb_fake(0x120, 0x15); + return (20); +} + +void +lcspx_attach(struct device *parent, struct device *self, void *aux) +{ + struct lcspx_softc *sc = (struct lcspx_softc *)self; + struct lcspx_screen *ss; + struct wsemuldisplaydev_attach_args aa; + int i, console; + + console = (vax_confdata & 8) == 0; + if (console) { + ss = &lcspx_consscr; + sc->sc_nscreens = 1; + } else { + ss = malloc(sizeof(struct lcspx_screen), M_DEVBUF, M_NOWAIT); + if (ss == NULL) { + printf(": can not allocate memory\n"); + return; + } + bzero(ss, sizeof(struct lcspx_screen)); + + ss->ss_addr = (caddr_t)vax_map_physmem(LCSPX_FB_ADDR, + LCSPX_FBSIZE / VAX_NBPG); + if (ss->ss_addr == NULL) { + printf(": can not map frame buffer\n"); + goto fail1; + } + + for (i = 0; i < 4; i++) { + ss->ss_ramdac[i] = (volatile u_int8_t *)vax_map_physmem( + LCSPX_RAMDAC_ADDR + i * LCSPX_RAMDAC_INTERLEAVE, 1); + if (ss->ss_ramdac[i] == NULL) { + printf(": can not map RAMDAC registers\n"); + goto fail2; + } + } + + if (lcspx_setup_screen(ss) != 0) { + printf(": initialization failed\n"); + goto fail2; + } + } + sc->sc_scr = ss; + + printf(": 1280x1024x8 frame buffer\n"); + + aa.console = console; + aa.scrdata = &lcspx_screenlist; + aa.accessops = &lcspx_accessops; + aa.accesscookie = sc; + + config_found(self, &aa, wsemuldisplaydevprint); + return; + +fail2: + for (i = 0; i < 4; i++) + if (ss->ss_ramdac[i] != NULL) + vax_unmap_physmem((vaddr_t)ss->ss_ramdac[i], 1); + vax_unmap_physmem((vaddr_t)ss->ss_addr, LCSPX_FBSIZE / VAX_NBPG); +fail1: + free(ss, M_DEVBUF); +} + +/* + * Initialize anything necessary for an emulating wsdisplay to work (i.e. + * pick a font, initialize a rasops structure, setup the accessops callbacks.) + */ +int +lcspx_setup_screen(struct lcspx_screen *ss) +{ + struct rasops_info *ri = &ss->ss_ri; + + bzero(ri, sizeof(*ri)); + ri->ri_depth = 8; + ri->ri_width = LCSPX_WIDTH; + ri->ri_height = LCSPX_HEIGHT; + ri->ri_stride = LCSPX_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); + + lcspx_resetcmap(ss); + + lcspx_stdscreen.ncols = ri->ri_cols; + lcspx_stdscreen.nrows = ri->ri_rows; + lcspx_stdscreen.textops = &ri->ri_ops; + lcspx_stdscreen.fontwidth = ri->ri_font->fontwidth; + lcspx_stdscreen.fontheight = ri->ri_font->fontheight; + lcspx_stdscreen.capabilities = ri->ri_caps; + + return (0); +} + +int +lcspx_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) +{ + struct lcspx_softc *sc = v; + struct lcspx_screen *ss = sc->sc_scr; + struct wsdisplay_fbinfo *wdf; + + switch (cmd) { + case WSDISPLAYIO_GTYPE: + *(u_int *)data = WSDISPLAY_TYPE_LCSPX; + break; + + case WSDISPLAYIO_GINFO: + wdf = (struct wsdisplay_fbinfo *)data; + wdf->height = LCSPX_HEIGHT; + wdf->width = LCSPX_WIDTH; + wdf->depth = 8; + wdf->cmsize = 256; + 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 +lcspx_mmap(void *v, off_t offset, int prot) +{ + if (offset >= LCSPX_FBSIZE || offset < 0) + return (-1); + + return (LCSPX_FB_ADDR + offset) >> PGSHIFT; +} + +int +lcspx_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep, + int *curxp, int *curyp, long *defattrp) +{ + struct lcspx_softc *sc = v; + struct lcspx_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 +lcspx_free_screen(void *v, void *cookie) +{ + struct lcspx_softc *sc = v; + + sc->sc_nscreens--; +} + +int +lcspx_show_screen(void *v, void *cookie, int waitok, + void (*cb)(void *, int, int), void *cbarg) +{ + return (0); +} + +void +lcspx_resetcmap(struct lcspx_screen *ss) +{ + const u_char *color; + u_int i; + + color = rasops_cmap; + for (i = 0; i < 256; i++) { + /* + * Reprogram the index every iteration, because the RAMDAC + * may not be in autoincrement mode. XXX fix this + */ + *(ss->ss_ramdac[BT463_REG_ADDR_LOW]) = i & 0xff; + *(ss->ss_ramdac[BT463_REG_ADDR_HIGH]) = i >> 8; + + *(ss->ss_ramdac[BT463_REG_CMAP_DATA]) = *color++; + *(ss->ss_ramdac[BT463_REG_CMAP_DATA]) = *color++; + *(ss->ss_ramdac[BT463_REG_CMAP_DATA]) = *color++; + } +} + +#include <dev/cons.h> +cons_decl(lcspx); + +#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 +lcspxcnprobe(cndev) + struct consdev *cndev; +{ + struct lcspx_screen *ss = &lcspx_consscr; + extern vaddr_t virtual_avail; + extern int getmajor(void *); /* conf.c */ + int i; + + switch (vax_boardtype) { + case VAX_BTYP_49: + if ((vax_confdata & 8) != 0) + break; /* doesn't use graphics console */ + + ss->ss_addr = (caddr_t)virtual_avail; + virtual_avail += LCSPX_FBSIZE; + ioaccess((vaddr_t)ss->ss_addr, LCSPX_FB_ADDR, + LCSPX_FBSIZE / VAX_NBPG); + + for (i = 0; i < 4; i++) { + ss->ss_ramdac[i] = (volatile u_int8_t *)virtual_avail; + virtual_avail += VAX_NBPG; + ioaccess((vaddr_t)ss->ss_ramdac[i], + LCSPX_RAMDAC_ADDR + i * LCSPX_RAMDAC_INTERLEAVE, 1); + } + + cndev->cn_pri = CN_INTERNAL; + cndev->cn_dev = makedev(getmajor(wsdisplayopen), 0); + break; + + default: + break; + } +} + +void +lcspxcninit(struct consdev *cndev) +{ + struct lcspx_screen *ss = &lcspx_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 lcspxcnprobe() */ + if (lcspx_setup_screen(ss) != 0) + return; + + ri = &ss->ss_ri; + ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr); + wsdisplay_cnattach(&lcspx_stdscreen, ri, 0, 0, defattr); + +#if NDZKBD > 0 + dzkbd_cnattach(0); /* Connect keyboard and screen together */ +#endif +} diff --git a/sys/dev/wscons/wsconsio.h b/sys/dev/wscons/wsconsio.h index 7a957f9e731..16ef32f7a6b 100644 --- a/sys/dev/wscons/wsconsio.h +++ b/sys/dev/wscons/wsconsio.h @@ -1,4 +1,4 @@ -/* $OpenBSD: wsconsio.h,v 1.40 2006/04/16 20:45:00 miod Exp $ */ +/* $OpenBSD: wsconsio.h,v 1.41 2006/07/24 22:19:54 miod Exp $ */ /* $NetBSD: wsconsio.h,v 1.74 2005/04/28 07:15:44 martin Exp $ */ /* @@ -290,6 +290,7 @@ struct wsmouse_calibcoords { #define WSDISPLAY_TYPE_SUNLEO 50 /* Sun ZX/Leo */ #define WSDISPLAY_TYPE_TVRX 51 /* HP TurboVRX */ #define WSDISPLAY_TYPE_CFXGA 52 /* CF VoyagerVGA */ +#define WSDISPLAY_TYPE_LCSPX 53 /* DEC LCSPX (VS4000) */ /* Basic display information. Not applicable to all display types. */ struct wsdisplay_fbinfo { |