diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2012-04-17 15:36:56 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2012-04-17 15:36:56 +0000 |
commit | 55b040815206d7dce82f59a01096792b5b766e98 (patch) | |
tree | 28ddc1a5387e22267d7b3af73a1ee3aa53d4440c | |
parent | 91ed4a46917ab93a8b6a3c3a667d9e6607c144de (diff) |
Driver for the ``Entry'' LG1 frame buffer found on low-range Indigo systems
only. Ported from NetBSD, not tested due to lack of hardware, hopefully it
will be working as intended (fingers crossed)
-rw-r--r-- | sys/arch/sgi/conf/GENERIC-IP22 | 10 | ||||
-rw-r--r-- | sys/arch/sgi/conf/RAMDISK-IP22 | 28 | ||||
-rw-r--r-- | sys/arch/sgi/gio/files.gio | 6 | ||||
-rw-r--r-- | sys/arch/sgi/gio/light.c | 652 | ||||
-rw-r--r-- | sys/arch/sgi/gio/lightreg.h | 87 | ||||
-rw-r--r-- | sys/arch/sgi/gio/lightvar.h | 29 |
6 files changed, 795 insertions, 17 deletions
diff --git a/sys/arch/sgi/conf/GENERIC-IP22 b/sys/arch/sgi/conf/GENERIC-IP22 index 5b59abe8ef5..ac9503fc7fb 100644 --- a/sys/arch/sgi/conf/GENERIC-IP22 +++ b/sys/arch/sgi/conf/GENERIC-IP22 @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC-IP22,v 1.7 2012/04/17 15:22:59 miod Exp $ +# $OpenBSD: GENERIC-IP22,v 1.8 2012/04/17 15:36:52 miod Exp $ # # THIS KERNEL IS FOR INDIGO (IP20), INDY (IP22) AND INDIGO2 (IP24) SYSTEMS ONLY. # @@ -70,8 +70,8 @@ zstty* at zs0 # Serial ports #wsmouse* at zsms? mux 0 pckbd* at pckbc? -pms* at pckbc? wskbd* at pckbd? mux 1 +pms* at pckbc? wsmouse* at pms? mux 0 newport* at gio? # Indy Newport and Indigo2 XL graphics @@ -80,8 +80,8 @@ wsdisplay* at newport? #grtwo* at gio? disable # Express (GR2) graphics #wsdisplay* at grtwo? -#light* at gio? # Light/Starter/Entry (LG1/LG2) graphics -#wsdisplay* at light? +light* at gio? # Light/Starter/Entry (LG1/LG2) graphics +wsdisplay* at light? #audio* at haltwo? @@ -96,4 +96,4 @@ uk* at scsibus? pseudo-device crypto 1 #pseudo-device hotplug 1 # devices hot plugging -#pseudo-device wsmux 2 # Mouse and keyboard multiplexor +pseudo-device wsmux 2 # Mouse and keyboard multiplexor diff --git a/sys/arch/sgi/conf/RAMDISK-IP22 b/sys/arch/sgi/conf/RAMDISK-IP22 index 2e221475856..6db3c73b0b5 100644 --- a/sys/arch/sgi/conf/RAMDISK-IP22 +++ b/sys/arch/sgi/conf/RAMDISK-IP22 @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISK-IP22,v 1.4 2012/04/15 20:18:16 miod Exp $ +# $OpenBSD: RAMDISK-IP22,v 1.5 2012/04/17 15:36:52 miod Exp $ # # THIS KERNEL IS FOR INDIGO (IP20), INDY (IP22) AND INDIGO2 (IP24) SYSTEMS ONLY. @@ -40,7 +40,7 @@ option TGT_INDIGO2 # Indigo2 (IP22/IP26/IP28) option TGT_INDY # Indy (IP24) option ARCBIOS # mandatory option CPU_R4000 # R4000/R4400 support (IP20/IP22/IP24) -#option CPU_R4600 # R4600 support (IP22/IP24) +option CPU_R4600 # R4600 support (IP22/IP24) option CPU_R5000 # R5000 support (IP24) # Specify storage configuration using ramdisk @@ -66,19 +66,29 @@ dpclock0 at hpc0 # IP20 dsclock0 at hpc0 # IP22/24 sq* at hpc? # On-board Ethernet or E++ adapter wdsc* at hpc? # On-board SCSI or GIO32 SCSI adapter -#pckbc* at hpc? # Indy/Indigo2 keyboard and mouse +pckbc* at hpc? # Indy/Indigo2 keyboard and mouse -zs* at hpc? -zstty* at zs? # Serial ports +zs0 at hpc0 +#zs1 at hpc0 +zstty* at zs0 # Serial ports +#zskbd* at zs1 channel 0 +#wskbd* at zskbd? mux 1 +#zsms* at zs1 channel 1 +#wsmouse* at zsms? mux 0 -#newport* at gio? # Indy Newport graphics -#wsdisplay* at newport? +pckbd* at pckbc? +wskbd* at pckbd? mux 1 +#pms* at pckbc? +#wsmouse* at pms? mux 0 + +newport* at gio? # Indy Newport graphics +wsdisplay* at newport? #grtwo* at gio? # Express (GR2) graphics #wsdisplay* at grtwo? -#light* at gio? # Light/Starter/Entry (LG1/LG2) graphics -#wsdisplay* at light? +light* at gio? # Light/Starter/Entry (LG1/LG2) graphics +wsdisplay* at light? scsibus* at scsi? sd* at scsibus? diff --git a/sys/arch/sgi/gio/files.gio b/sys/arch/sgi/gio/files.gio index fe393862625..f8131536844 100644 --- a/sys/arch/sgi/gio/files.gio +++ b/sys/arch/sgi/gio/files.gio @@ -1,4 +1,4 @@ -# $OpenBSD: files.gio,v 1.1 2012/03/28 20:44:23 miod Exp $ +# $OpenBSD: files.gio,v 1.2 2012/04/17 15:36:55 miod Exp $ # $NetBSD: files.gio,v 1.11 2009/02/12 06:33:57 rumble Exp $ device gio {[slot = -1], [addr = -1]} @@ -16,12 +16,12 @@ attach newport at gio file arch/sgi/gio/newport.c newport needs-flag # GR2 graphics -device grtwo: wsemuldisplaydev +device grtwo: wsemuldisplaydev, rasops8 attach grtwo at gio file arch/sgi/gio/grtwo.c grtwo needs-flag # LG1/LG2 graphics -device light: wsemuldisplaydev +device light: wsemuldisplaydev, rasops8 attach light at gio file arch/sgi/gio/light.c light needs-flag diff --git a/sys/arch/sgi/gio/light.c b/sys/arch/sgi/gio/light.c new file mode 100644 index 00000000000..05240d604cb --- /dev/null +++ b/sys/arch/sgi/gio/light.c @@ -0,0 +1,652 @@ +/* $OpenBSD: light.c,v 1.1 2012/04/17 15:36:55 miod Exp $ */ +/* $NetBSD: light.c,v 1.5 2007/03/04 06:00:39 christos Exp $ */ + +/* + * Copyright (c) 2012 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 and this permission notice 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) 2006 Stephen M. Rumble + * Copyright (c) 2003 Ilpo Ruotsalainen + * 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. 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. + * + * <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>> + */ + +/* + * SGI "Light" graphics, a.k.a. "Entry", "Starter", "LG1", and "LG2". + * + * 1024x768 8bpp at 60Hz. + * + * This driver supports the boards found in Indigo R3k and R4k machines. + * There is a Crimson variant, but the register offsets differ significantly. + * + * Light's REX chip is the precursor of the REX3 found in "newport", hence + * much similarity exists. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> +#include <sys/malloc.h> + +#include <machine/autoconf.h> +#include <mips64/archtype.h> + +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wsdisplayvar.h> +#include <dev/rasops/rasops.h> + +#include <sgi/dev/gl.h> +#include <sgi/gio/giovar.h> +#include <sgi/gio/lightvar.h> +#include <sgi/gio/lightreg.h> + +struct light_softc { + struct device sc_dev; + + struct light_devconfig *sc_dc; + + int sc_nscreens; + struct wsscreen_list sc_wsl; + const struct wsscreen_descr *sc_scrlist[1]; +}; + +struct light_devconfig { + struct rasops_info dc_ri; + long dc_defattr; + + uint32_t dc_addr; + bus_space_tag_t dc_st; + bus_space_handle_t dc_sh; + + int dc_boardrev; + + struct light_softc *dc_sc; + struct wsscreen_descr dc_wsd; +}; + +/* always 1024x768x8 */ +#define LIGHT_XRES 1024 +#define LIGHT_YRES 768 +#define LIGHT_DEPTH 8 + +int light_match(struct device *, void *, void *); +void light_attach(struct device *, struct device *, void *); + +struct cfdriver light_cd = { + NULL, "light", DV_DULL +}; + +const struct cfattach light_ca = { + sizeof(struct light_softc), light_match, light_attach +}; + +/* wsdisplay_accessops */ +int light_ioctl(void *, u_long, caddr_t, int, struct proc *); +paddr_t light_mmap(void *, off_t, int); +int light_alloc_screen(void *, const struct wsscreen_descr *, void **, + int *, int *, long *); +void light_free_screen(void *, void *); +int light_show_screen(void *, void *, int, void (*)(void *, int, int), + void *); + +struct wsdisplay_accessops light_accessops = { + .ioctl = light_ioctl, + .mmap = light_mmap, + .alloc_screen = light_alloc_screen, + .free_screen = light_free_screen, + .show_screen = light_show_screen, +}; + +int light_do_cursor(struct rasops_info *); +int light_putchar(void *, int, int, u_int, long); +int light_copycols(void *, int, int, int, int); +int light_erasecols(void *, int, int, int, long); +int light_copyrows(void *, int, int, int); +int light_eraserows(void *, int, int, long); + +static __inline__ +uint32_t rex_read(struct light_devconfig *, uint32_t, uint32_t); +static __inline__ +void rex_write(struct light_devconfig *, uint32_t, uint32_t, uint32_t); +static __inline__ +uint8_t rex_vc1_read(struct light_devconfig *); +static __inline__ +void rex_vc1_write(struct light_devconfig *, uint8_t); +static __inline__ +void rex_wait(struct light_devconfig *); +static __inline__ +int rex_revision(struct light_devconfig *); +void rex_copy_rect(struct light_devconfig *, int, int, int, int, int, int, + int); +void rex_fill_rect(struct light_devconfig *, int, int, int, int, int); + +void light_attach_common(struct light_devconfig *, struct gio_attach_args *); +void light_init_screen(struct light_devconfig *); + +static struct light_devconfig light_console_dc; +static int light_is_console = 0; + +#define LIGHT_IS_LG1(_rev) ((_rev) < 2) /* else LG2 */ + +/******************************************************************************* + * REX routines and helper functions + ******************************************************************************/ + +static __inline__ +uint32_t +rex_read(struct light_devconfig *dc, uint32_t rset, uint32_t r) +{ + return (bus_space_read_4(dc->dc_st, dc->dc_sh, rset + r)); +} + +static __inline__ +void +rex_write(struct light_devconfig *dc, uint32_t rset, uint32_t r, uint32_t v) +{ + bus_space_write_4(dc->dc_st, dc->dc_sh, rset + r, v); +} + +static __inline__ +uint8_t +rex_vc1_read(struct light_devconfig *dc) +{ + rex_write(dc, REX_PAGE1_GO, REX_P1REG_CFGSEL, REX_CFGSEL_VC1_SYSCTL); + rex_read(dc, REX_PAGE1_GO, REX_P1REG_VC1_ADDRDATA); + return (rex_read(dc, REX_PAGE1_SET, REX_P1REG_VC1_ADDRDATA)); +} + +static __inline__ +void +rex_vc1_write(struct light_devconfig *dc, uint8_t val) +{ + rex_write(dc, REX_PAGE1_GO, REX_P1REG_CFGSEL, REX_CFGSEL_VC1_SYSCTL); + rex_write(dc, REX_PAGE1_SET, REX_P1REG_VC1_ADDRDATA, val); + rex_write(dc, REX_PAGE1_GO, REX_P1REG_VC1_ADDRDATA, val); +} + +static __inline__ +void +rex_wait(struct light_devconfig *dc) +{ + while (rex_read(dc, REX_PAGE1_SET,REX_P1REG_CFGMODE) & REX_CFGMODE_BUSY) + continue; +} + +static __inline__ +int +rex_revision(struct light_devconfig *dc) +{ + rex_write(dc, REX_PAGE1_SET, REX_P1REG_CFGSEL, REX_CFGSEL_VC1_LADDR); + rex_read(dc, REX_PAGE1_GO, REX_P1REG_WCLOCKREV); + return (rex_read(dc, REX_PAGE1_SET, REX_P1REG_WCLOCKREV) & 0x7); +} + +void +rex_copy_rect(struct light_devconfig *dc, int from_x, int from_y, int to_x, + int to_y, int width, int height, int rop) +{ + int dx, dy, ystarti, yendi; + + dx = from_x - to_x; + dy = from_y - to_y; + + /* adjust for y. NB: STOPONX, STOPONY are inclusive */ + if (to_y > from_y) { + ystarti = to_y + height - 1; + yendi = to_y; + } else { + ystarti = to_y; + yendi = to_y + height - 1; + } + + rex_wait(dc); + + rex_write(dc, REX_PAGE0_SET, REX_P0REG_XSTARTI, to_x); + rex_write(dc, REX_PAGE0_SET, REX_P0REG_XENDI, to_x + width); + rex_write(dc, REX_PAGE0_SET, REX_P0REG_YSTARTI, ystarti); + rex_write(dc, REX_PAGE0_SET, REX_P0REG_YENDI, yendi); + rex_write(dc, REX_PAGE0_SET, REX_P0REG_COMMAND, REX_OP_DRAW | + REX_OP_FLG_LOGICSRC | REX_OP_FLG_QUADMODE | + REX_OP_FLG_BLOCK | REX_OP_FLG_STOPONX | REX_OP_FLG_STOPONY | + (rop << REX_LOGICOP_SHIFT)); + rex_write(dc, REX_PAGE0_GO, REX_P0REG_XYMOVE, + ((dx << 16) & 0xffff0000) | (dy & 0x0000ffff)); +} + +void +rex_fill_rect(struct light_devconfig *dc, int from_x, int from_y, int to_x, + int to_y, int bg) +{ + struct rasops_info *ri = &dc->dc_ri; + + rex_wait(dc); + + rex_write(dc, REX_PAGE0_SET, REX_P0REG_YSTARTI, from_y); + rex_write(dc, REX_PAGE0_SET, REX_P0REG_YENDI, to_y); + rex_write(dc, REX_PAGE0_SET, REX_P0REG_XSTARTI, from_x); + rex_write(dc, REX_PAGE0_SET, REX_P0REG_XENDI, to_x); + rex_write(dc, REX_PAGE0_SET, REX_P0REG_COLORREDI, + ri->ri_devcmap[bg] & 0xff); + rex_write(dc, REX_PAGE0_SET, REX_P0REG_COMMAND, REX_OP_DRAW | + REX_OP_FLG_QUADMODE | REX_OP_FLG_BLOCK | + REX_OP_FLG_STOPONX | REX_OP_FLG_STOPONY | + (OPENGL_LOGIC_OP_COPY << REX_LOGICOP_SHIFT)); + rex_read(dc, REX_PAGE0_GO, REX_P0REG_COMMAND); +} + +/******************************************************************************* + * match/attach functions + ******************************************************************************/ + +int +light_match(struct device *parent, void *vcf, void *aux) +{ + struct gio_attach_args *ga = aux; + uint32_t reg; + + /* not looking for a frame buffer */ + if (ga->ga_slot != -1) + return (0); + + if (ga->ga_addr != LIGHT_ADDR_0 && ga->ga_addr != LIGHT_ADDR_1) + return (0); + + if (guarded_read_4(ga->ga_ioh + REX_PAGE1_SET + REX_P1REG_XYOFFSET, + ®) != 0) + return (0); + + if (reg != 0x08000800) + return (0); + + return (1); +} + +void +light_attach(struct device *parent, struct device *self, void *aux) +{ + struct light_softc *sc = (struct light_softc *)self; + struct gio_attach_args *ga = aux; + struct light_devconfig *dc; + struct wsemuldisplaydev_attach_args waa; + + if (light_is_console && ga->ga_addr == light_console_dc.dc_addr) { + waa.console = 1; + dc = &light_console_dc; + sc->sc_nscreens = 1; + } else { + waa.console = 0; + dc = malloc(sizeof(struct light_devconfig), M_DEVBUF, + M_WAITOK | M_ZERO); + light_attach_common(dc, ga); + light_init_screen(dc); + } + sc->sc_dc = dc; + dc->dc_sc = sc; + + if (ga->ga_descr != NULL && *ga->ga_descr != '\0') + printf(": %s", ga->ga_descr); + else + printf(": LG%dMC\n", + LIGHT_IS_LG1(sc->sc_dc->dc_boardrev) ? 1 : 2); + printf(", revision %d\n", dc->dc_boardrev); + printf("%s: %dx%d %d-bit frame buffer\n", + self->dv_xname, LIGHT_XRES, LIGHT_YRES, LIGHT_DEPTH); + + sc->sc_scrlist[0] = &dc->dc_wsd; + sc->sc_wsl.nscreens = 1; + sc->sc_wsl.screens = sc->sc_scrlist; + + waa.scrdata = &sc->sc_wsl; + waa.accessops = &light_accessops; + waa.accesscookie = dc; + waa.defaultscreens = 0; + + config_found(self, &waa, wsemuldisplaydevprint); +} + +int +light_cnprobe(struct gio_attach_args *ga) +{ + return light_match(NULL, NULL, ga); +} + +int +light_cnattach(struct gio_attach_args *ga) +{ + struct rasops_info *ri = &light_console_dc.dc_ri; + long defattr; + + light_attach_common(&light_console_dc, ga); + light_init_screen(&light_console_dc); + + ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr); + wsdisplay_cnattach(&light_console_dc.dc_wsd, ri, 0, 0, defattr); + light_is_console = 1; + + return 0; +} + +void +light_attach_common(struct light_devconfig *dc, struct gio_attach_args *ga) +{ + dc->dc_addr = ga->ga_addr; + dc->dc_st = ga->ga_iot; + dc->dc_sh = ga->ga_ioh; + + dc->dc_boardrev = rex_revision(dc); + + rex_vc1_write(dc, rex_vc1_read(dc) & ~(VC1_SYSCTL_CURSOR | + VC1_SYSCTL_CURSOR_ON)); +} + +void +light_init_screen(struct light_devconfig *dc) +{ + struct rasops_info *ri = &dc->dc_ri; + + memset(ri, 0, sizeof(struct rasops_info)); + ri->ri_hw = dc; + ri->ri_flg = RI_CENTER | RI_FULLCLEAR; + ri->ri_flg |= RI_FORCEMONO; /* XXX until colormap support... */ + /* for the proper operation of rasops computations, pretend 8bpp */ + ri->ri_depth = 8; + ri->ri_stride = LIGHT_XRES; + ri->ri_width = LIGHT_XRES; + ri->ri_height = LIGHT_YRES; + + rasops_init(ri, 160, 160); + + ri->ri_do_cursor = light_do_cursor; + ri->ri_ops.copyrows = light_copyrows; + ri->ri_ops.eraserows = light_eraserows; + ri->ri_ops.copycols = light_copycols; + ri->ri_ops.erasecols = light_erasecols; + ri->ri_ops.putchar = light_putchar; + + strlcpy(dc->dc_wsd.name, "std", sizeof(dc->dc_wsd.name)); + dc->dc_wsd.ncols = ri->ri_cols; + dc->dc_wsd.nrows = ri->ri_rows; + dc->dc_wsd.textops = &ri->ri_ops; + dc->dc_wsd.fontwidth = ri->ri_font->fontwidth; + dc->dc_wsd.fontheight = ri->ri_font->fontheight; + dc->dc_wsd.capabilities = ri->ri_caps; + + rex_fill_rect(dc, 0, 0, LIGHT_XRES - 1, LIGHT_YRES - 1, WSCOL_BLACK); +} + +/******************************************************************************* + * wsdisplay_emulops + ******************************************************************************/ + +int +light_do_cursor(struct rasops_info *ri) +{ + struct light_devconfig *dc = ri->ri_hw; + int x, y, w, h; + + w = ri->ri_font->fontwidth; + h = ri->ri_font->fontheight; + x = ri->ri_ccol * w + ri->ri_xorigin; + y = ri->ri_crow * h + ri->ri_yorigin; + + rex_copy_rect(dc, x, y, x, y, w, h, OPENGL_LOGIC_OP_COPY_INVERTED); + + return 0; +} + +int +light_putchar(void *c, int row, int col, u_int ch, long attr) +{ + struct rasops_info *ri = c; + struct light_devconfig *dc = ri->ri_hw; + struct wsdisplay_font *font = ri->ri_font; + uint8_t *bitmap; + uint32_t pattern; + int x = col * font->fontwidth + ri->ri_xorigin; + int y = row * font->fontheight + ri->ri_yorigin; + int i; + int bg, fg, ul; + + ri->ri_ops.unpack_attr(ri, attr, &fg, &bg, &ul); + + if ((ch == ' ' || ch == 0) && ul == 0) { + rex_fill_rect(dc, x, y, x + font->fontwidth - 1, + y + font->fontheight - 1, bg); + return 0; + } + + rex_wait(dc); + + rex_write(dc, REX_PAGE0_SET, REX_P0REG_YSTARTI, y); + rex_write(dc, REX_PAGE0_SET, REX_P0REG_YENDI, y + font->fontheight - 1); + rex_write(dc, REX_PAGE0_SET, REX_P0REG_XSTARTI, x); + rex_write(dc, REX_PAGE0_SET, REX_P0REG_XENDI, x + font->fontwidth - 1); + rex_write(dc, REX_PAGE0_SET, REX_P0REG_COLORREDI, + ri->ri_devcmap[fg] & 0xff); + rex_write(dc, REX_PAGE0_SET, REX_P0REG_COLORBACK, + ri->ri_devcmap[bg] & 0xff); + rex_write(dc, REX_PAGE0_GO, REX_P0REG_COMMAND, REX_OP_NOP); + + rex_wait(dc); + + rex_write(dc, REX_PAGE0_SET, REX_P0REG_COMMAND, REX_OP_DRAW | + REX_OP_FLG_ENZPATTERN | REX_OP_FLG_QUADMODE | + REX_OP_FLG_XYCONTINUE | REX_OP_FLG_STOPONX | REX_OP_FLG_BLOCK | + REX_OP_FLG_LENGTH32 | REX_OP_FLG_ZOPAQUE | + (OPENGL_LOGIC_OP_COPY << REX_LOGICOP_SHIFT)); + + bitmap = (uint8_t *)font->data + + (ch - font->firstchar) * ri->ri_fontscale; + if (font->fontwidth <= 8) { + for (i = font->fontheight; i != 0; i--) { + if (ul && i == 1) + pattern = 0xff000000; + else + pattern = *bitmap << 24; + rex_write(dc, REX_PAGE0_GO, REX_P0REG_ZPATTERN, + pattern); + bitmap += font->stride; + } + } else { + for (i = font->fontheight; i != 0; i--) { + if (ul && i == 1) + pattern = 0xffff0000; + else + pattern = *(uint16_t *)bitmap << 16; + rex_write(dc, REX_PAGE0_GO, REX_P0REG_ZPATTERN, + pattern); + bitmap += font->stride; + } + } + + return 0; +} + +/* copy set of columns within the same line */ +int +light_copycols(void *c, int row, int srccol, int dstcol, int ncols) +{ + struct rasops_info *ri = c; + struct light_devconfig *dc = ri->ri_hw; + struct wsdisplay_font *font = ri->ri_font; + int from_x, to_x, y, width, height; + + from_x = ri->ri_xorigin + srccol * font->fontwidth; + to_x = ri->ri_xorigin + dstcol * font->fontwidth; + y = ri->ri_yorigin + row * font->fontheight; + width = ncols * font->fontwidth; + height = font->fontheight; + + rex_copy_rect(dc, from_x, y, to_x, y, width, height, + OPENGL_LOGIC_OP_COPY); + + return 0; +} + +/* erase a set of columns in the same line */ +int +light_erasecols(void *c, int row, int startcol, int ncols, long attr) +{ + struct rasops_info *ri = c; + struct light_devconfig *dc = ri->ri_hw; + struct wsdisplay_font *font = ri->ri_font; + int from_x, from_y, to_x, to_y; + int bg, fg; + + ri->ri_ops.unpack_attr(ri, attr, &fg, &bg, NULL); + + from_x = ri->ri_xorigin + startcol * font->fontwidth; + from_y = ri->ri_yorigin + row * font->fontheight; + to_x = from_x + (ncols * font->fontwidth) - 1; + to_y = from_y + font->fontheight - 1; + + rex_fill_rect(dc, from_x, from_y, to_x, to_y, bg); + + return 0; +} + +/* copy a set of complete rows */ +int +light_copyrows(void *c, int srcrow, int dstrow, int nrows) +{ + struct rasops_info *ri = c; + struct light_devconfig *dc = ri->ri_hw; + struct wsdisplay_font *font = ri->ri_font; + int x, from_y, to_y, width, height; + + x = ri->ri_xorigin; + from_y = ri->ri_yorigin + srcrow * font->fontheight; + to_y = ri->ri_yorigin + dstrow * font->fontheight; + width = ri->ri_emuwidth; + height = nrows * font->fontheight; + + rex_copy_rect(dc, x, from_y, x, to_y, width, height, + OPENGL_LOGIC_OP_COPY); + + return 0; +} + +/* erase a set of complete rows */ +int +light_eraserows(void *c, int row, int nrows, long attr) +{ + struct rasops_info *ri = c; + struct light_devconfig *dc = ri->ri_hw; + struct wsdisplay_font *font = ri->ri_font; + int bg, fg; + + ri->ri_ops.unpack_attr(ri, attr, &fg, &bg, NULL); + + if (nrows == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR)) { + rex_fill_rect(dc, 0, 0, LIGHT_XRES - 1, LIGHT_YRES - 1, bg); + return 0; + } + + rex_fill_rect(dc, ri->ri_xorigin, + ri->ri_yorigin + row * font->fontheight - 1, + ri->ri_xorigin + ri->ri_emuwidth - 1, + ri->ri_yorigin + (row + nrows) * font->fontheight - 1, bg); + + return 0; +} + +/******************************************************************************* + * wsdisplay_accessops + ******************************************************************************/ + +int +light_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) +{ + struct wsdisplay_fbinfo *fb; + + switch (cmd) { + case WSDISPLAYIO_GTYPE: + *(u_int *)data = WSDISPLAY_TYPE_LIGHT; + break; + case WSDISPLAYIO_GINFO: + fb = (struct wsdisplay_fbinfo *)data; + fb->width = LIGHT_XRES; + fb->height = LIGHT_YRES; + fb->depth = LIGHT_DEPTH; + fb->cmsize = 1 << LIGHT_DEPTH; + break; + default: + return -1; + } + + return 0; +} + +paddr_t +light_mmap(void *v, off_t off, int prot) +{ + return -1; +} + +int +light_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep, + int *curxp, int *curyp, long *attrp) +{ + struct light_devconfig *dc = v; + struct rasops_info *ri = &dc->dc_ri; + struct light_softc *sc = dc->dc_sc; + + if (sc->sc_nscreens > 0) + return ENOMEM; + + sc->sc_nscreens++; + + *cookiep = ri; + *curxp = *curyp = 0; + ri->ri_ops.alloc_attr(ri, 0, 0, 0, &dc->dc_defattr); + *attrp = dc->dc_defattr; + + return 0; +} + +void +light_free_screen(void *v, void *cookie) +{ +} + +int +light_show_screen(void *v, void *cookie, int waitok, + void (*cb)(void *, int, int), void *cbarg) +{ + return 0; +} diff --git a/sys/arch/sgi/gio/lightreg.h b/sys/arch/sgi/gio/lightreg.h new file mode 100644 index 00000000000..d6926717a1e --- /dev/null +++ b/sys/arch/sgi/gio/lightreg.h @@ -0,0 +1,87 @@ +/* $OpenBSD: lightreg.h,v 1.1 2012/04/17 15:36:55 miod Exp $ */ +/* $NetBSD: lightreg.h,v 1.3 2006/12/29 00:31:48 rumble Exp $ */ + +/* + * Copyright (c) 2006 Stephen M. Rumble + * 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. 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. + */ + +#define LIGHT_ADDR_0 0x1f3f0000 +#define LIGHT_ADDR_1 0x1f3f8000 /* dual head */ +#define LIGHT_SIZE 0x00008000 + +#define REX_PAGE0_SET 0x00000000 /* REX registers */ +#define REX_PAGE0_GO 0x00000800 +#define REX_PAGE1_SET 0x00004790 /* configuration registers */ +#define REX_PAGE1_GO 0x00004F90 + +/* REX register offsets (from REX_PAGE0_{SET,GO}) */ +#define REX_P0REG_COMMAND 0x00000000 +#define REX_P0REG_XSTARTI 0x0000000C +#define REX_P0REG_YSTARTI 0x0000001C +#define REX_P0REG_XYMOVE 0x00000034 +#define REX_P0REG_COLORREDI 0x00000038 +#define REX_P0REG_COLORGREENI 0x00000040 +#define REX_P0REG_COLORBLUEI 0x00000048 +#define REX_P0REG_COLORBACK 0x0000005C +#define REX_P0REG_ZPATTERN 0x00000060 +#define REX_P0REG_XENDI 0x00000084 +#define REX_P0REG_YENDI 0x00000088 + +/* configuration register offsets (from REX_PAGE1_{SET,GO}) */ +#define REX_P1REG_WCLOCKREV 0x00000054 /* nsclock / revision */ +#define REX_P1REG_CFGSEL 0x0000005c /* function selector */ +#define REX_P1REG_VC1_ADDRDATA 0x00000060 /* vc1 r/w addr and data 8bit */ +#define REX_P1REG_CFGMODE 0x00000068 /* REX system config */ +#define REX_P1REG_XYOFFSET 0x0000006c /* x, y start of screen */ + +/* REX opcodes */ +#define REX_OP_NOP 0x00000000 +#define REX_OP_DRAW 0x00000001 + +/* REX command flags */ +#define REX_OP_FLG_BLOCK 0x00000008 +#define REX_OP_FLG_LENGTH32 0x00000010 +#define REX_OP_FLG_QUADMODE 0x00000020 +#define REX_OP_FLG_XYCONTINUE 0x00000080 +#define REX_OP_FLG_STOPONX 0x00000100 +#define REX_OP_FLG_STOPONY 0x00000200 +#define REX_OP_FLG_ENZPATTERN 0x00000400 +#define REX_OP_FLG_LOGICSRC 0x00080000 +#define REX_OP_FLG_ZOPAQUE 0x00800000 +#define REX_OP_FLG_ZCONTINUE 0x01000000 + +/* REX logicops */ +#define REX_LOGICOP_SHIFT 28 + +/* configmode bits */ +#define REX_CFGMODE_BUSY 0x00000001 + +/* configsel bits */ +#define REX_CFGSEL_VC1_LADDR 0x00000004 /* low address bits */ +#define REX_CFGSEL_VC1_HADDR 0x00000005 /* high address bits */ +#define REX_CFGSEL_VC1_SYSCTL 0x00000006 + +/* vc1 sysctl bits (byte) */ +#define VC1_SYSCTL_VIDEO_ON 0x04 +#define VC1_SYSCTL_CURSOR 0x10 +#define VC1_SYSCTL_CURSOR_ON 0x20 diff --git a/sys/arch/sgi/gio/lightvar.h b/sys/arch/sgi/gio/lightvar.h new file mode 100644 index 00000000000..fefd59ca7db --- /dev/null +++ b/sys/arch/sgi/gio/lightvar.h @@ -0,0 +1,29 @@ +/* $OpenBSD: lightvar.h,v 1.1 2012/04/17 15:36:55 miod Exp $ */ +/* $NetBSD: lightvar.h,v 1.2 2011/07/01 18:53:46 dyoung Exp $ */ + +/* + * Copyright (c) 2006 Stephen M. Rumble + * 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. 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. + */ + +int light_cnattach(struct gio_attach_args *); +int light_cnprobe(struct gio_attach_args *); |