summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2012-04-16 22:31:37 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2012-04-16 22:31:37 +0000
commit430cf5bf4a8b78e23d7e53663ac657c509eb3374 (patch)
tree6d9924fb7409c821669f521df08fd56c2e238722
parentf09813013655ad3b727993a1b3629a0dd4d92a62 (diff)
Drivers for the Indy and Indigo 2 PS/2 keyboard ports, and the ``Newport''
(NG1, XL, XGE) frame buffer. Adapted from NetBSD; newport extended to support underline and fonts wider than 8 pixels, such as the default 12x22 Gallant font. Framebuffer depth computation seems to be wrong on Indy models, to be investigated later (but doesn't prevent text console from working).
-rw-r--r--sys/arch/sgi/conf/GENERIC-IP2230
-rw-r--r--sys/arch/sgi/conf/files.sgi5
-rw-r--r--sys/arch/sgi/gio/newport.c888
-rw-r--r--sys/arch/sgi/gio/newportreg.h259
-rw-r--r--sys/arch/sgi/gio/newportvar.h34
-rw-r--r--sys/arch/sgi/hpc/pckbc_hpc.c143
6 files changed, 1348 insertions, 11 deletions
diff --git a/sys/arch/sgi/conf/GENERIC-IP22 b/sys/arch/sgi/conf/GENERIC-IP22
index 60b8c634535..496478f9891 100644
--- a/sys/arch/sgi/conf/GENERIC-IP22
+++ b/sys/arch/sgi/conf/GENERIC-IP22
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC-IP22,v 1.5 2012/04/15 20:18:16 miod Exp $
+# $OpenBSD: GENERIC-IP22,v 1.6 2012/04/16 22:31:34 miod Exp $
#
# THIS KERNEL IS FOR INDIGO (IP20), INDY (IP22) AND INDIGO2 (IP24) SYSTEMS ONLY.
#
@@ -22,7 +22,7 @@ makeoption LINK_ADDRESS="0xffffffff88800000"
# physical memory, all of it fitting within CKSEG0.
option PAGE_SHIFT="14"
-#option WSDISPLAY_COMPAT_RAWKBD # Provide raw scancodes; needed for X11
+option WSDISPLAY_COMPAT_RAWKBD # Provide raw scancodes; needed for X11
option EISAVERBOSE
@@ -57,22 +57,34 @@ 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
-#haltwo* at hpc? # Indy/Indigo2 Audio
+#haltwo* at hpc? # Indy/Indigo2 Audio
#panel* at hpc? # Indy front panel buttons
-#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?
+pms* at pckbc?
+wskbd* at pckbd? mux 1
+wsmouse* at pms? mux 0
-#grtwo* at gio? # Express (GR2) graphics
+newport* at gio? # Indy Newport and Indigo2 XL graphics
+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?
+#audio* at haltwo?
+
scsibus* at scsi?
sd* at scsibus?
st* at scsibus?
diff --git a/sys/arch/sgi/conf/files.sgi b/sys/arch/sgi/conf/files.sgi
index a13ff36f3c7..4707ba9bf1e 100644
--- a/sys/arch/sgi/conf/files.sgi
+++ b/sys/arch/sgi/conf/files.sgi
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sgi,v 1.47 2012/03/28 20:44:23 miod Exp $
+# $OpenBSD: files.sgi,v 1.48 2012/04/16 22:31:34 miod Exp $
#
# maxpartitions must be first item in files.${ARCH}
#
@@ -42,6 +42,8 @@ include "dev/mii/files.mii"
include "dev/atapiscsi/files.atapiscsi"
include "dev/ata/files.ata"
+include "dev/pckbc/files.pckbc"
+
#
# System BUS types
#
@@ -181,7 +183,6 @@ attach mavb at macebus
file arch/sgi/dev/mavb.c mavb
# MACE PS/2 Controller
-include "dev/pckbc/files.pckbc"
device mkbc: pckbcslot
attach mkbc at macebus
file arch/sgi/dev/mkbc.c mkbc needs-flag
diff --git a/sys/arch/sgi/gio/newport.c b/sys/arch/sgi/gio/newport.c
new file mode 100644
index 00000000000..c70347cb65a
--- /dev/null
+++ b/sys/arch/sgi/gio/newport.c
@@ -0,0 +1,888 @@
+/* $OpenBSD: newport.c,v 1.1 2012/04/16 22:31:36 miod Exp $ */
+/* $NetBSD: newport.c,v 1.15 2009/05/12 23:51:25 macallan 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) 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>>
+ */
+
+#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/gioreg.h>
+#include <sgi/gio/giovar.h>
+#include <sgi/gio/newportreg.h>
+#include <sgi/gio/newportvar.h>
+
+struct newport_softc {
+ struct device sc_dev;
+
+ struct newport_devconfig *sc_dc;
+
+ int sc_nscreens;
+ struct wsscreen_list sc_wsl;
+ const struct wsscreen_descr *sc_scrlist[1];
+};
+
+struct newport_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_xres;
+ int dc_yres;
+ int dc_depth;
+
+#ifdef notyet
+ int dc_mode;
+#endif
+
+ int dc_boardrev;
+ int dc_vc2rev;
+ int dc_cmaprev;
+ int dc_xmaprev;
+#if 0
+ int dc_rexrev;
+#endif
+
+ struct newport_softc *dc_sc;
+ struct wsscreen_descr dc_wsd;
+};
+
+int newport_match(struct device *, void *, void *);
+void newport_attach(struct device *, struct device *, void *);
+
+struct cfdriver newport_cd = {
+ NULL, "newport", DV_DULL
+};
+
+const struct cfattach newport_ca = {
+ sizeof(struct newport_softc), newport_match, newport_attach
+};
+
+/* accessops */
+int newport_ioctl(void *, u_long, caddr_t, int, struct proc *);
+paddr_t newport_mmap(void *, off_t, int);
+int newport_alloc_screen(void *, const struct wsscreen_descr *, void **,
+ int *, int *, long *);
+void newport_free_screen(void *, void *);
+int newport_show_screen(void *, void *, int, void (*)(void *, int, int),
+ void *);
+
+struct wsdisplay_accessops newport_accessops = {
+ newport_ioctl,
+ newport_mmap,
+ newport_alloc_screen,
+ newport_free_screen,
+ newport_show_screen,
+ NULL, /* load_font */
+ NULL, /* scrollback */
+ NULL, /* getchar */
+ NULL, /* burner */
+ NULL /* pollc */
+};
+
+int newport_do_cursor(struct rasops_info *);
+int newport_putchar(void *, int, int, u_int, long);
+int newport_copycols(void *, int, int, int, int);
+int newport_erasecols(void *, int, int, int, long);
+int newport_copyrows(void *, int, int, int);
+int newport_eraserows(void *, int, int, long);
+
+static __inline__
+void rex3_write(struct newport_devconfig *, bus_size_t, uint32_t);
+static __inline__
+void rex3_write_go(struct newport_devconfig *, bus_size_t, uint32_t);
+static __inline__
+uint32_t rex3_read(struct newport_devconfig *, bus_size_t);
+static __inline__
+void rex3_wait_gfifo(struct newport_devconfig *);
+
+void vc2_write_ireg(struct newport_devconfig *, uint8_t, uint16_t);
+uint16_t vc2_read_ireg(struct newport_devconfig *, uint8_t);
+uint16_t vc2_read_ram(struct newport_devconfig *, uint16_t);
+void vc2_write_ram(struct newport_devconfig *, uint16_t, uint16_t);
+uint32_t xmap9_read(struct newport_devconfig *, int);
+void xmap9_write(struct newport_devconfig *, int, uint8_t);
+void xmap9_write_mode(struct newport_devconfig *, uint8_t, uint32_t);
+
+void newport_attach_common(struct newport_devconfig *,
+ struct gio_attach_args *);
+void newport_bitblt(struct newport_devconfig *, int, int, int, int, int, int,
+ int);
+void newport_cmap_setrgb(struct newport_devconfig *, int, uint8_t, uint8_t,
+ uint8_t);
+void newport_fill_rectangle(struct newport_devconfig *, int, int, int, int,
+ int);
+void newport_get_resolution(struct newport_devconfig *);
+void newport_init_screen(struct newport_devconfig *);
+void newport_setup_hw(struct newport_devconfig *);
+
+static struct newport_devconfig newport_console_dc;
+static int newport_is_console = 0;
+
+/**** Low-level hardware register groveling functions ****/
+static __inline__ void
+rex3_write(struct newport_devconfig *dc, bus_size_t rexreg, uint32_t val)
+{
+ bus_space_write_4(dc->dc_st, dc->dc_sh, NEWPORT_REX3_OFFSET + rexreg,
+ val);
+}
+
+static __inline__ void
+rex3_write_go(struct newport_devconfig *dc, bus_size_t rexreg, uint32_t val)
+{
+ rex3_write(dc, rexreg + REX3_REG_GO, val);
+}
+
+static __inline__ uint32_t
+rex3_read(struct newport_devconfig *dc, bus_size_t rexreg)
+{
+ return bus_space_read_4(dc->dc_st, dc->dc_sh, NEWPORT_REX3_OFFSET +
+ rexreg);
+}
+
+static __inline__ void
+rex3_wait_gfifo(struct newport_devconfig *dc)
+{
+ while (rex3_read(dc, REX3_REG_STATUS) & REX3_STATUS_GFXBUSY)
+ ;
+}
+
+void
+vc2_write_ireg(struct newport_devconfig *dc, uint8_t ireg, uint16_t val)
+{
+ rex3_write(dc, REX3_REG_DCBMODE,
+ REX3_DCBMODE_DW_3 | REX3_DCBMODE_ENCRSINC |
+ (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) |
+ (VC2_DCBCRS_INDEX << REX3_DCBMODE_DCBCRS_SHIFT) |
+ REX3_DCBMODE_ENASYNCACK | (1 << REX3_DCBMODE_CSSETUP_SHIFT));
+
+ rex3_write(dc, REX3_REG_DCBDATA0, (ireg << 24) | (val << 8));
+}
+
+uint16_t
+vc2_read_ireg(struct newport_devconfig *dc, uint8_t ireg)
+{
+ rex3_write(dc, REX3_REG_DCBMODE,
+ REX3_DCBMODE_DW_1 | REX3_DCBMODE_ENCRSINC |
+ (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) |
+ (VC2_DCBCRS_INDEX << REX3_DCBMODE_DCBCRS_SHIFT) |
+ REX3_DCBMODE_ENASYNCACK | (1 << REX3_DCBMODE_CSSETUP_SHIFT));
+
+ rex3_write(dc, REX3_REG_DCBDATA0, ireg << 24);
+
+ rex3_write(dc, REX3_REG_DCBMODE,
+ REX3_DCBMODE_DW_2 | REX3_DCBMODE_ENCRSINC |
+ (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) |
+ (VC2_DCBCRS_IREG << REX3_DCBMODE_DCBCRS_SHIFT) |
+ REX3_DCBMODE_ENASYNCACK | (1 << REX3_DCBMODE_CSSETUP_SHIFT));
+
+ return (uint16_t)(rex3_read(dc, REX3_REG_DCBDATA0) >> 16);
+}
+
+uint16_t
+vc2_read_ram(struct newport_devconfig *dc, uint16_t addr)
+{
+ vc2_write_ireg(dc, VC2_IREG_RAM_ADDRESS, addr);
+
+ rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_2 |
+ (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) |
+ (VC2_DCBCRS_RAM << REX3_DCBMODE_DCBCRS_SHIFT) |
+ REX3_DCBMODE_ENASYNCACK | (1 << REX3_DCBMODE_CSSETUP_SHIFT));
+
+ return (uint16_t)(rex3_read(dc, REX3_REG_DCBDATA0) >> 16);
+}
+
+#if 0
+void
+vc2_write_ram(struct newport_devconfig *dc, uint16_t addr, uint16_t val)
+{
+ vc2_write_ireg(dc, VC2_IREG_RAM_ADDRESS, addr);
+
+ rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_2 |
+ (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) |
+ (VC2_DCBCRS_RAM << REX3_DCBMODE_DCBCRS_SHIFT) |
+ REX3_DCBMODE_ENASYNCACK | (1 << REX3_DCBMODE_CSSETUP_SHIFT));
+
+ rex3_write(dc, REX3_REG_DCBDATA0, val << 16);
+}
+#endif
+
+uint32_t
+xmap9_read(struct newport_devconfig *dc, int crs)
+{
+ rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_1 |
+ (NEWPORT_DCBADDR_XMAP_0 << REX3_DCBMODE_DCBADDR_SHIFT) |
+ (crs << REX3_DCBMODE_DCBCRS_SHIFT) |
+ (3 << REX3_DCBMODE_CSWIDTH_SHIFT) |
+ (2 << REX3_DCBMODE_CSHOLD_SHIFT) |
+ (1 << REX3_DCBMODE_CSSETUP_SHIFT));
+ return rex3_read(dc, REX3_REG_DCBDATA0);
+}
+
+void
+xmap9_write(struct newport_devconfig *dc, int crs, uint8_t val)
+{
+ rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_1 |
+ (NEWPORT_DCBADDR_XMAP_BOTH << REX3_DCBMODE_DCBADDR_SHIFT) |
+ (crs << REX3_DCBMODE_DCBCRS_SHIFT) |
+ (3 << REX3_DCBMODE_CSWIDTH_SHIFT) |
+ (2 << REX3_DCBMODE_CSHOLD_SHIFT) |
+ (1 << REX3_DCBMODE_CSSETUP_SHIFT));
+
+ rex3_write(dc, REX3_REG_DCBDATA0, val << 24);
+}
+
+void
+xmap9_write_mode(struct newport_devconfig *dc, uint8_t index, uint32_t mode)
+{
+ rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_4 |
+ (NEWPORT_DCBADDR_XMAP_BOTH << REX3_DCBMODE_DCBADDR_SHIFT) |
+ (XMAP9_DCBCRS_MODE_SETUP << REX3_DCBMODE_DCBCRS_SHIFT) |
+ (3 << REX3_DCBMODE_CSWIDTH_SHIFT) |
+ (2 << REX3_DCBMODE_CSHOLD_SHIFT) |
+ (1 << REX3_DCBMODE_CSSETUP_SHIFT));
+
+ rex3_write(dc, REX3_REG_DCBDATA0, (index << 24) | mode);
+}
+
+/**** Helper functions ****/
+void
+newport_fill_rectangle(struct newport_devconfig *dc, int x1, int y1, int x2,
+ int y2, int bg)
+{
+ struct rasops_info *ri = &dc->dc_ri;
+
+ rex3_wait_gfifo(dc);
+
+ rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_DRAW |
+ REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_DOSETUP |
+ REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_STOPONY);
+ rex3_write(dc, REX3_REG_DRAWMODE1, REX3_DRAWMODE1_PLANES_CI |
+ REX3_DRAWMODE1_DD_DD8 | REX3_DRAWMODE1_RWPACKED |
+ REX3_DRAWMODE1_HD_HD8 | REX3_DRAWMODE1_COMPARE_LT |
+ REX3_DRAWMODE1_COMPARE_EQ | REX3_DRAWMODE1_COMPARE_GT |
+ (OPENGL_LOGIC_OP_COPY << REX3_DRAWMODE1_LOGICOP_SHIFT));
+ rex3_write(dc, REX3_REG_WRMASK, 0xffffffff);
+ rex3_write(dc, REX3_REG_COLORI, ri->ri_devcmap[bg] & 0xff);
+ rex3_write(dc, REX3_REG_XYSTARTI, (x1 << REX3_XYSTARTI_XSHIFT) | y1);
+
+ rex3_write_go(dc, REX3_REG_XYENDI, (x2 << REX3_XYENDI_XSHIFT) | y2);
+}
+
+void
+newport_bitblt(struct newport_devconfig *dc, int xs, int ys, int xd,
+ int yd, int wi, int he, int rop)
+{
+ int xe, ye;
+ uint32_t tmp;
+
+ rex3_wait_gfifo(dc);
+ if (yd > ys) {
+ /* need to copy bottom up */
+ ye = ys;
+ yd += he - 1;
+ ys += he - 1;
+ } else
+ ye = ys + he - 1;
+
+ if (xd > xs) {
+ /* need to copy right to left */
+ xe = xs;
+ xd += wi - 1;
+ xs += wi - 1;
+ } else
+ xe = xs + wi - 1;
+
+ rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_SCR2SCR |
+ REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_DOSETUP |
+ REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_STOPONY);
+ rex3_write(dc, REX3_REG_DRAWMODE1, REX3_DRAWMODE1_PLANES_CI |
+ REX3_DRAWMODE1_DD_DD8 | REX3_DRAWMODE1_RWPACKED |
+ REX3_DRAWMODE1_HD_HD8 | REX3_DRAWMODE1_COMPARE_LT |
+ REX3_DRAWMODE1_COMPARE_EQ | REX3_DRAWMODE1_COMPARE_GT |
+ (rop << REX3_DRAWMODE1_LOGICOP_SHIFT));
+ rex3_write(dc, REX3_REG_XYSTARTI, (xs << REX3_XYSTARTI_XSHIFT) | ys);
+ rex3_write(dc, REX3_REG_XYENDI, (xe << REX3_XYENDI_XSHIFT) | ye);
+
+ tmp = (yd - ys) & 0xffff;
+ tmp |= (xd - xs) << REX3_XYMOVE_XSHIFT;
+
+ rex3_write_go(dc, REX3_REG_XYMOVE, tmp);
+}
+
+void
+newport_cmap_setrgb(struct newport_devconfig *dc, int index, uint8_t r,
+ uint8_t g, uint8_t b)
+{
+ rex3_write(dc, REX3_REG_DCBMODE,
+ REX3_DCBMODE_DW_2 | REX3_DCBMODE_ENCRSINC |
+ (NEWPORT_DCBADDR_CMAP_BOTH << REX3_DCBMODE_DCBADDR_SHIFT) |
+ (CMAP_DCBCRS_ADDRESS_LOW << REX3_DCBMODE_DCBCRS_SHIFT) |
+ (1 << REX3_DCBMODE_CSWIDTH_SHIFT) |
+ (1 << REX3_DCBMODE_CSHOLD_SHIFT) |
+ (1 << REX3_DCBMODE_CSSETUP_SHIFT) | REX3_DCBMODE_SWAPENDIAN);
+
+ rex3_write(dc, REX3_REG_DCBDATA0, index << 16);
+
+ rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_3 |
+ (NEWPORT_DCBADDR_CMAP_BOTH << REX3_DCBMODE_DCBADDR_SHIFT) |
+ (CMAP_DCBCRS_PALETTE << REX3_DCBMODE_DCBCRS_SHIFT) |
+ (1 << REX3_DCBMODE_CSWIDTH_SHIFT) |
+ (1 << REX3_DCBMODE_CSHOLD_SHIFT) |
+ (1 << REX3_DCBMODE_CSSETUP_SHIFT));
+
+ rex3_write(dc, REX3_REG_DCBDATA0, (r << 24) | (g << 16) | (b << 8));
+}
+
+void
+newport_get_resolution(struct newport_devconfig *dc)
+{
+ uint16_t vep,lines;
+ uint16_t linep,cols;
+ uint16_t data;
+
+ vep = vc2_read_ireg(dc, VC2_IREG_VIDEO_ENTRY);
+
+ dc->dc_xres = 0;
+ dc->dc_yres = 0;
+
+ for (;;) {
+ /* Iterate over runs in video timing table */
+
+ cols = 0;
+
+ linep = vc2_read_ram(dc, vep++);
+ lines = vc2_read_ram(dc, vep++);
+
+ if (lines == 0)
+ break;
+
+ do {
+ /* Iterate over state runs in line sequence table */
+ data = vc2_read_ram(dc, linep++);
+
+ if ((data & 0x0001) == 0)
+ cols += (data >> 7) & 0xfe;
+
+ if ((data & 0x0080) == 0)
+ data = vc2_read_ram(dc, linep++);
+ } while ((data & 0x8000) == 0);
+
+ if (cols != 0) {
+ if (cols > dc->dc_xres)
+ dc->dc_xres = cols;
+ dc->dc_yres += lines;
+ }
+ }
+}
+
+void
+newport_setup_hw(struct newport_devconfig *dc)
+{
+ uint16_t curp,tmp;
+ int i;
+ uint32_t scratch;
+
+ /* Get various revisions */
+ rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_1 |
+ (NEWPORT_DCBADDR_CMAP_0 << REX3_DCBMODE_DCBADDR_SHIFT) |
+ (CMAP_DCBCRS_REVISION << REX3_DCBMODE_DCBCRS_SHIFT) |
+ (1 << REX3_DCBMODE_CSWIDTH_SHIFT) |
+ (1 << REX3_DCBMODE_CSHOLD_SHIFT) |
+ (1 << REX3_DCBMODE_CSSETUP_SHIFT));
+
+ scratch = vc2_read_ireg(dc, VC2_IREG_CONFIG);
+ dc->dc_vc2rev = (scratch & VC2_IREG_CONFIG_REVISION) >> 5;
+
+ scratch = rex3_read(dc, REX3_REG_DCBDATA0);
+
+ dc->dc_boardrev = (scratch >> 28) & 0x07;
+ dc->dc_cmaprev = scratch & 0x07;
+ dc->dc_xmaprev = xmap9_read(dc, XMAP9_DCBCRS_REVISION) & 0x07;
+ dc->dc_depth = ( (dc->dc_boardrev > 1) && (scratch & 0x80)) ? 8 : 24;
+
+ /* Setup cursor glyph */
+ curp = vc2_read_ireg(dc, VC2_IREG_CURSOR_ENTRY);
+
+ /* Setup VC2 to a known state */
+ tmp = vc2_read_ireg(dc, VC2_IREG_CONTROL) & VC2_CONTROL_INTERLACE;
+ vc2_write_ireg(dc, VC2_IREG_CONTROL, tmp |
+ VC2_CONTROL_DISPLAY_ENABLE | VC2_CONTROL_VTIMING_ENABLE |
+ VC2_CONTROL_DID_ENABLE | VC2_CONTROL_CURSORFUNC_ENABLE);
+
+ /* Setup XMAP9s */
+ xmap9_write(dc, XMAP9_DCBCRS_CONFIG,
+ XMAP9_CONFIG_8BIT_SYSTEM | XMAP9_CONFIG_RGBMAP_CI);
+
+ xmap9_write(dc, XMAP9_DCBCRS_CURSOR_CMAP, 0);
+
+ xmap9_write_mode(dc, 0,
+ XMAP9_MODE_GAMMA_BYPASS | XMAP9_MODE_PIXSIZE_8BPP);
+ xmap9_write(dc, XMAP9_DCBCRS_MODE_SELECT, 0);
+
+ /* Setup REX3 */
+ rex3_write(dc, REX3_REG_XYWIN, (4096 << 16) | 4096);
+ rex3_write(dc, REX3_REG_TOPSCAN, 0x3ff); /* XXX Why? XXX */
+
+ /* Setup CMAP */
+ for (i = 0; i < 256; i++)
+ newport_cmap_setrgb(dc, i, rasops_cmap[i * 3],
+ rasops_cmap[i * 3 + 1], rasops_cmap[i * 3 + 2]);
+}
+
+/**** Attach routines ****/
+int
+newport_match(struct device *parent, void *vcf, void *aux)
+{
+ struct gio_attach_args *ga = aux;
+ uint32_t dummy;
+
+ /* not looking for a frame buffer */
+ if (ga->ga_slot != -1)
+ return 0;
+
+ if (ga->ga_addr != GIO_ADDR_GFX && ga->ga_addr != GIO_ADDR_EXP0)
+ return 0;
+
+ /* Don't do the destructive probe if we're already attached */
+ if (newport_is_console && ga->ga_addr == newport_console_dc.dc_addr)
+ return 1;
+
+ if (guarded_read_4(ga->ga_ioh + NEWPORT_REX3_OFFSET + REX3_REG_XSTARTI,
+ &dummy) != 0)
+ return 0;
+ if (guarded_read_4(ga->ga_ioh + NEWPORT_REX3_OFFSET + REX3_REG_XSTART,
+ &dummy) != 0)
+ return 0;
+
+ /* Ugly, this probe is destructive, blame SGI... */
+ bus_space_write_4(ga->ga_iot, ga->ga_ioh,
+ NEWPORT_REX3_OFFSET + REX3_REG_XSTARTI, 0x12345678);
+ if (bus_space_read_4(ga->ga_iot, ga->ga_ioh,
+ NEWPORT_REX3_OFFSET + REX3_REG_XSTART) !=
+ ((0x12345678 & 0xffff) << 11))
+ return 0;
+
+ return 1;
+}
+
+void
+newport_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct newport_softc *sc = (struct newport_softc *)self;
+ struct gio_attach_args *ga = aux;
+ struct newport_devconfig *dc;
+ struct wsemuldisplaydev_attach_args waa;
+ const char *descr;
+
+ if (newport_is_console && ga->ga_addr == newport_console_dc.dc_addr) {
+ waa.console = 1;
+ dc = &newport_console_dc;
+ sc->sc_nscreens = 1;
+ } else {
+ waa.console = 0;
+ dc = malloc(sizeof(struct newport_devconfig),
+ M_DEVBUF, M_WAITOK | M_ZERO);
+ newport_attach_common(dc, ga);
+ newport_init_screen(dc);
+ }
+ sc->sc_dc = dc;
+ dc->dc_sc = sc;
+
+ descr = ga->ga_descr;
+ if (descr == NULL || *descr == '\0')
+ descr = "NG1";
+ printf(": %s (board rev %d, cmap rev %d, xmap rev %d, vc2 rev %d)\n",
+ descr,
+ dc->dc_boardrev, dc->dc_cmaprev, dc->dc_xmaprev, dc->dc_vc2rev);
+ printf("%s: %dx%d %d-bit frame buffer\n",
+ self->dv_xname, dc->dc_xres, dc->dc_yres, dc->dc_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 = &newport_accessops;
+ waa.accesscookie = dc;
+ waa.defaultscreens = 0;
+
+ config_found(self, &waa, wsemuldisplaydevprint);
+}
+
+int
+newport_cnprobe(struct gio_attach_args *ga)
+{
+ return newport_match(NULL, NULL, ga);
+}
+
+int
+newport_cnattach(struct gio_attach_args *ga)
+{
+ struct rasops_info *ri = &newport_console_dc.dc_ri;
+ long defattr;
+
+ newport_attach_common(&newport_console_dc, ga);
+ newport_init_screen(&newport_console_dc);
+
+ ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr);
+ wsdisplay_cnattach(&newport_console_dc.dc_wsd, ri, 0, 0, defattr);
+ newport_is_console = 1;
+
+ return 0;
+}
+
+void
+newport_attach_common(struct newport_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;
+
+ newport_setup_hw(dc);
+ newport_get_resolution(dc);
+}
+
+void
+newport_init_screen(struct newport_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;
+ /* for the proper operation of rasops computations, pretend 8bpp */
+ ri->ri_depth = 8;
+ ri->ri_stride = dc->dc_xres;
+ ri->ri_width = dc->dc_xres;
+ ri->ri_height = dc->dc_yres;
+
+ rasops_init(ri, 160, 160);
+
+ ri->ri_do_cursor = newport_do_cursor;
+ ri->ri_ops.copyrows = newport_copyrows;
+ ri->ri_ops.eraserows = newport_eraserows;
+ ri->ri_ops.copycols = newport_copycols;
+ ri->ri_ops.erasecols = newport_erasecols;
+ ri->ri_ops.putchar = newport_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;
+
+ newport_fill_rectangle(dc, 0, 0, dc->dc_xres - 1, dc->dc_yres - 1,
+ WSCOL_BLACK);
+
+#ifdef notyet
+ dc->dc_mode = WSDISPLAYIO_MODE_EMUL;
+#endif
+}
+
+/**** wsdisplay textops ****/
+
+int
+newport_do_cursor(struct rasops_info *ri)
+{
+ struct newport_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;
+
+ newport_bitblt(dc, x, y, x, y, w, h, OPENGL_LOGIC_OP_COPY_INVERTED);
+
+ return 0;
+}
+
+int
+newport_putchar(void *c, int row, int col, u_int ch, long attr)
+{
+ struct rasops_info *ri = c;
+ struct newport_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) {
+ newport_fill_rectangle(dc, x, y, x + font->fontwidth - 1,
+ y + font->fontheight - 1, bg);
+ return 0;
+ }
+
+ rex3_wait_gfifo(dc);
+
+ rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_DRAW |
+ REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_STOPONX |
+ REX3_DRAWMODE0_ENZPATTERN | REX3_DRAWMODE0_ZPOPAQUE);
+
+ rex3_write(dc, REX3_REG_DRAWMODE1, REX3_DRAWMODE1_PLANES_CI |
+ REX3_DRAWMODE1_DD_DD8 | REX3_DRAWMODE1_RWPACKED |
+ REX3_DRAWMODE1_HD_HD8 | REX3_DRAWMODE1_COMPARE_LT |
+ REX3_DRAWMODE1_COMPARE_EQ | REX3_DRAWMODE1_COMPARE_GT |
+ (OPENGL_LOGIC_OP_COPY << REX3_DRAWMODE1_LOGICOP_SHIFT));
+
+ rex3_write(dc, REX3_REG_XYSTARTI, (x << REX3_XYSTARTI_XSHIFT) | y);
+ rex3_write(dc, REX3_REG_XYENDI,
+ (x + font->fontwidth - 1) << REX3_XYENDI_XSHIFT);
+
+ rex3_write(dc, REX3_REG_COLORI, ri->ri_devcmap[fg] & 0xff);
+ rex3_write(dc, REX3_REG_COLORBACK, ri->ri_devcmap[bg] & 0xff);
+
+ rex3_write(dc, REX3_REG_WRMASK, 0xffffffff);
+
+ 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;
+ rex3_write_go(dc, REX3_REG_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;
+ rex3_write_go(dc, REX3_REG_ZPATTERN, pattern);
+ bitmap += font->stride;
+ }
+ }
+
+ return 0;
+}
+
+int
+newport_copycols(void *c, int row, int srccol, int dstcol, int ncols)
+{
+ struct rasops_info *ri = c;
+ struct newport_devconfig *dc = ri->ri_hw;
+ struct wsdisplay_font *font = ri->ri_font;
+ int32_t xs, xd, y, width, height;
+
+ xs = ri->ri_xorigin + font->fontwidth * srccol;
+ xd = ri->ri_xorigin + font->fontwidth * dstcol;
+ y = ri->ri_yorigin + font->fontheight * row;
+ width = font->fontwidth * ncols;
+ height = font->fontheight;
+ newport_bitblt(dc, xs, y, xd, y, width, height, OPENGL_LOGIC_OP_COPY);
+
+ return 0;
+}
+
+int
+newport_erasecols(void *c, int row, int startcol, int ncols, long attr)
+{
+ struct rasops_info *ri = c;
+ struct newport_devconfig *dc = ri->ri_hw;
+ struct wsdisplay_font *font = ri->ri_font;
+ int sx, sy, dx, dy;
+ int bg, fg;
+
+ ri->ri_ops.unpack_attr(ri, attr, &fg, &bg, NULL);
+
+ sx = ri->ri_xorigin + startcol * font->fontwidth;
+ sy = ri->ri_yorigin + row * font->fontheight;
+ dx = sx + ncols * font->fontwidth - 1;
+ dy = sy + font->fontheight - 1;
+
+ newport_fill_rectangle(dc, sx, sy, dx, dy, bg);
+
+ return 0;
+}
+
+int
+newport_copyrows(void *c, int srcrow, int dstrow, int nrows)
+{
+ struct rasops_info *ri = c;
+ struct newport_devconfig *dc = ri->ri_hw;
+ struct wsdisplay_font *font = ri->ri_font;
+ int32_t x, ys, yd, width, height;
+
+ x = ri->ri_xorigin;
+ ys = ri->ri_yorigin + font->fontheight * srcrow;
+ yd = ri->ri_yorigin + font->fontheight * dstrow;
+ width = ri->ri_emuwidth;
+ height = font->fontheight * nrows;
+
+ newport_bitblt(dc, x, ys, x, yd, width, height, OPENGL_LOGIC_OP_COPY);
+
+ return 0;
+}
+
+int
+newport_eraserows(void *c, int startrow, int nrows, long attr)
+{
+ struct rasops_info *ri = c;
+ struct newport_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)) {
+ newport_fill_rectangle(dc, 0, 0, dc->dc_xres - 1,
+ dc->dc_yres - 1, bg);
+ return 0;
+ }
+
+ newport_fill_rectangle(dc, ri->ri_xorigin,
+ ri->ri_yorigin + startrow * font->fontheight,
+ ri->ri_xorigin + ri->ri_emuwidth - 1,
+ ri->ri_yorigin + (startrow + nrows) * font->fontheight - 1, bg);
+
+ return 0;
+}
+
+/**** wsdisplay accessops ****/
+
+int
+newport_alloc_screen(void *v, const struct wsscreen_descr *type,
+ void **cookiep, int *curxp, int *curyp, long *attrp)
+{
+ struct newport_devconfig *dc = v;
+ struct rasops_info *ri = &dc->dc_ri;
+ struct newport_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
+newport_free_screen(void *v, void *cookie)
+{
+}
+
+int
+newport_show_screen(void *v, void *cookie, int waitok,
+ void (*cb)(void *, int, int), void *cbarg)
+{
+ return 0;
+}
+
+int
+newport_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ struct newport_devconfig *dc = v;
+ struct rasops_info *ri = &dc->dc_ri;
+ struct wsdisplay_fbinfo *fb;
+#ifdef notyet
+ int nmode;
+#endif
+
+ switch (cmd) {
+ case WSDISPLAYIO_GTYPE:
+ *(u_int *)data = WSDISPLAY_TYPE_NEWPORT;
+ break;
+ case WSDISPLAYIO_GINFO:
+ fb = (struct wsdisplay_fbinfo *)data;
+ fb->width = ri->ri_width;
+ fb->height = ri->ri_height;
+ fb->depth = dc->dc_depth; /* real depth */
+ if (dc->dc_depth > 8)
+ fb->cmsize = 0;
+ else
+ fb->cmsize = 1 << ri->ri_depth;
+ break;
+#ifdef notyet
+ case WSDISPLAYIO_SMODE:
+ nmode = *(int *)data;
+ if (nmode != dc->dc_mode) {
+ dc->dc_mode = nmode;
+ if (nmode == WSDISPLAYIO_MODE_EMUL) {
+ rex3_wait_gfifo(dc);
+ newport_setup_hw(dc);
+ }
+ }
+ break;
+#endif
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+paddr_t
+newport_mmap(void *v, off_t offset, int prot)
+{
+ return -1;
+}
diff --git a/sys/arch/sgi/gio/newportreg.h b/sys/arch/sgi/gio/newportreg.h
new file mode 100644
index 00000000000..92bb3ba4f50
--- /dev/null
+++ b/sys/arch/sgi/gio/newportreg.h
@@ -0,0 +1,259 @@
+/* $OpenBSD: newportreg.h,v 1.1 2012/04/16 22:31:36 miod Exp $ */
+/* $NetBSD: newportreg.h,v 1.5 2011/02/20 07:59:50 matt Exp $ */
+
+/*
+ * 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>>
+ */
+
+/* REX3 */
+
+#define NEWPORT_REX3_OFFSET 0xf0000
+
+#define REX3_REG_DRAWMODE1 0x0000
+#define REX3_DRAWMODE1_PLANES_MASK 0x00000007
+#define REX3_DRAWMODE1_PLANES_NONE 0x00000000
+#define REX3_DRAWMODE1_PLANES_RGB 0x00000001
+#define REX3_DRAWMODE1_PLANES_CI 0x00000001
+#define REX3_DRAWMODE1_PLANES_RGBA 0x00000002
+#define REX3_DRAWMODE1_PLANES_OLAY 0x00000004
+#define REX3_DRAWMODE1_PLANES_PUP 0x00000005
+#define REX3_DRAWMODE1_PLANES_CID 0x00000006
+#define REX3_DRAWMODE1_DD_MASK 0x00000018
+#define REX3_DRAWMODE1_DD_DD4 0x00000000
+#define REX3_DRAWMODE1_DD_DD8 0x00000008
+#define REX3_DRAWMODE1_DD_DD12 0x00000010
+#define REX3_DRAWMODE1_DD_DD24 0x00000018
+#define REX3_DRAWMODE1_DBLSRC 0x00000020
+#define REX3_DRAWMODE1_YFLIP 0x00000040
+#define REX3_DRAWMODE1_RWPACKED 0x00000080
+#define REX3_DRAWMODE1_HD_MASK 0x00000300
+#define REX3_DRAWMODE1_HD_HD4 0x00000000
+#define REX3_DRAWMODE1_HD_HD8 0x00000100
+#define REX3_DRAWMODE1_HD_HD12 0x00000200
+#define REX3_DRAWMODE1_HD_HD24 0x00000300
+#define REX3_DRAWMODE1_RWDOUBLE 0x00000400
+#define REX3_DRAWMODE1_SWAPENDIAN 0x00000800
+#define REX3_DRAWMODE1_COMPARE_MASK 0x00007000
+#define REX3_DRAWMODE1_COMPARE_LT 0x00001000
+#define REX3_DRAWMODE1_COMPARE_EQ 0x00002000
+#define REX3_DRAWMODE1_COMPARE_GT 0x00004000
+#define REX3_DRAWMODE1_RGBMODE 0x00008000
+#define REX3_DRAWMODE1_DITHER 0x00010000
+#define REX3_DRAWMODE1_FASTCLEAR 0x00020000
+#define REX3_DRAWMODE1_BLEND 0x00040000
+#define REX3_DRAWMODE1_SFACTOR_MASK 0x00380000
+#define REX3_DRAWMODE1_SFACTOR_ZERO 0x00000000
+#define REX3_DRAWMODE1_SFACTOR_ONE 0x00080000
+#define REX3_DRAWMODE1_SFACTOR_DC 0x00100000
+#define REX3_DRAWMODE1_SFACTOR_MDC 0x00180000
+#define REX3_DRAWMODE1_SFACTOR_SA 0x00200000
+#define REX3_DRAWMODE1_SFACTOR_MSA 0x00280000
+#define REX3_DRAWMODE1_DFACTOR_MASK 0x01c00000
+#define REX3_DRAWMODE1_DFACTOR_ZERO 0x00000000
+#define REX3_DRAWMODE1_DFACTOR_ONE 0x00400000
+#define REX3_DRAWMODE1_DFACTOR_SC 0x00800000
+#define REX3_DRAWMODE1_DFACTOR_MSC 0x00c00000
+#define REX3_DRAWMODE1_DFACTOR_SA 0x01000000
+#define REX3_DRAWMODE1_DFACTOR_MSA 0x01400000
+#define REX3_DRAWMODE1_BACKBLEND 0x02000000
+#define REX3_DRAWMODE1_PREFETCH 0x04000000
+#define REX3_DRAWMODE1_BLENDALPHA 0x08000000
+#define REX3_DRAWMODE1_LOGICOP_SHIFT 28
+
+#define REX3_REG_DRAWMODE0 0x0004
+#define REX3_DRAWMODE0_OPCODE_MASK 0x00000003
+#define REX3_DRAWMODE0_OPCODE_NOOP 0x00000000
+#define REX3_DRAWMODE0_OPCODE_READ 0x00000001
+#define REX3_DRAWMODE0_OPCODE_DRAW 0x00000002
+#define REX3_DRAWMODE0_OPCODE_SCR2SCR 0x00000003
+#define REX3_DRAWMODE0_ADRMODE_MASK 0x0000001c
+#define REX3_DRAWMODE0_ADRMODE_SPAN 0x00000000
+#define REX3_DRAWMODE0_ADRMODE_BLOCK 0x00000004
+#define REX3_DRAWMODE0_ADRMODE_I_LINE 0x00000008
+#define REX3_DRAWMODE0_ADRMODE_F_LINE 0x0000000c
+#define REX3_DRAWMODE0_ADRMODE_A_LINE 0x00000010
+#define REX3_DRAWMODE0_DOSETUP 0x00000020
+#define REX3_DRAWMODE0_COLORHOST 0x00000040
+#define REX3_DRAWMODE0_ALPHAHOST 0x00000080
+#define REX3_DRAWMODE0_STOPONX 0x00000100
+#define REX3_DRAWMODE0_STOPONY 0x00000200
+#define REX3_DRAWMODE0_SKIPFIRST 0x00000400
+#define REX3_DRAWMODE0_SKIPLAST 0x00000800
+#define REX3_DRAWMODE0_ENZPATTERN 0x00001000
+#define REX3_DRAWMODE0_ENLSPATTERN 0x00002000
+#define REX3_DRAWMODE0_LSADVLAST 0x00004000
+#define REX3_DRAWMODE0_LENGTH32 0x00008000
+#define REX3_DRAWMODE0_ZPOPAQUE 0x00010000
+#define REX3_DRAWMODE0_LSOPAQUE 0x00020000
+#define REX3_DRAWMODE0_SHADE 0x00040000
+#define REX3_DRAWMODE0_LRONLY 0x00080000
+#define REX3_DRAWMODE0_XYOFFSET 0x00100000
+#define REX3_DRAWMODE0_CICLAMP 0x00200000
+#define REX3_DRAWMODE0_ENDPTFILTER 0x00400000
+#define REX3_DRAWMODE0_YSTRIDE 0x00800000
+#define REX3_REG_LSMODE 0x0008
+
+#define REX3_REG_LSPATTERN 0x000c
+
+#define REX3_REG_LSPATSAVE 0x0010
+
+#define REX3_REG_ZPATTERN 0x0014
+
+#define REX3_REG_COLORBACK 0x0018
+
+#define REX3_REG_XSTART 0x0100
+
+#define REX3_REG_XYMOVE 0x0114
+#define REX3_XYMOVE_XSHIFT 16
+
+#define REX3_REG_XSTARTI 0x0148
+
+#define REX3_REG_XYSTARTI 0x0150
+#define REX3_XYSTARTI_XSHIFT 16
+
+#define REX3_REG_XYENDI 0x0154
+#define REX3_XYENDI_XSHIFT 16
+
+#define REX3_REG_WRMASK 0x0220
+
+#define REX3_REG_COLORI 0x0224
+
+#define REX3_REG_DCBMODE 0x0238
+#define REX3_DCBMODE_DW_MASK 0x00000003
+#define REX3_DCBMODE_DW_4 0x00000000
+#define REX3_DCBMODE_DW_1 0x00000001
+#define REX3_DCBMODE_DW_2 0x00000002
+#define REX3_DCBMODE_DW_3 0x00000003
+#define REX3_DCBMODE_ENDATAPACK 0x00000004
+#define REX3_DCBMODE_ENCRSINC 0x00000008
+#define REX3_DCBMODE_DCBCRS_MASK 0x00000070
+#define REX3_DCBMODE_DCBCRS_SHIFT 4
+#define REX3_DCBMODE_DCBADDR_MASK 0x00000780
+#define REX3_DCBMODE_DCBADDR_SHIFT 7
+#define REX3_DCBMODE_ENSYNCACK 0x00000800
+#define REX3_DCBMODE_ENASYNCACK 0x00001000
+#define REX3_DCBMODE_CSWIDTH_MASK 0x0003e000
+#define REX3_DCBMODE_CSWIDTH_SHIFT 13
+#define REX3_DCBMODE_CSHOLD_MASK 0x007c0000
+#define REX3_DCBMODE_CSHOLD_SHIFT 18
+#define REX3_DCBMODE_CSSETUP_MASK 0x0f800000
+#define REX3_DCBMODE_CSSETUP_SHIFT 23
+#define REX3_DCBMODE_SWAPENDIAN 0x10000000
+
+#define REX3_REG_DCBDATA0 0x0240
+#define REX3_REG_DCBDATA1 0x0244
+
+/* Not really a register, but in the same space */
+#define REX3_REG_GO 0x0800
+
+#define REX3_REG_TOPSCAN 0x1320
+#define REX3_REG_XYWIN 0x1324
+
+#define REX3_REG_STATUS 0x1338
+#define REX3_STATUS_GFXBUSY 0x00000008
+
+/* VC2 */
+
+#define VC2_DCBCRS_INDEX 0
+#define VC2_DCBCRS_IREG 1
+#define VC2_DCBCRS_RAM 3
+
+#define VC2_IREG_VIDEO_ENTRY 0x00
+
+#define VC2_IREG_CURSOR_ENTRY 0x01
+
+#define VC2_IREG_CURSOR_X 0x02
+
+#define VC2_IREG_CURSOR_Y 0x03
+
+#define VC2_IREG_SCANLINE_LENGTH 0x06
+
+#define VC2_IREG_RAM_ADDRESS 0x07
+
+#define VC2_IREG_CONTROL 0x10
+#define VC2_CONTROL_VINTR_ENABLE 0x0001
+#define VC2_CONTROL_DISPLAY_ENABLE 0x0002
+#define VC2_CONTROL_VTIMING_ENABLE 0x0004
+#define VC2_CONTROL_DID_ENABLE 0x0008
+#define VC2_CONTROL_CURSORFUNC_ENABLE 0x0010
+#define VC2_CONTROL_GENSYNC_ENABLE 0x0020
+#define VC2_CONTROL_INTERLACE 0x0040
+#define VC2_CONTROL_CURSOR_ENABLE 0x0080
+#define VC2_CONTROL_CROSSHAIR_CURSOR 0x0100
+#define VC2_CONTROL_LARGE_CURSOR 0x0200
+#define VC2_CONTROL_GENLOCK_1 0x0400
+
+#define VC2_IREG_CONFIG 0x1f
+#define VC2_IREG_CONFIG_SOFTRESET 0x01 /* active low */
+#define VC2_IREG_CONFIG_SLOWCLOCK 0x02
+#define VC2_IREG_CONFIG_CURSORERROR 0x04
+#define VC2_IREG_CONFIG_DIDERROR 0x08
+#define VC2_IREG_CONFIG_VTGERROR 0x10
+#define VC2_IREG_CONFIG_REVISION 0x70
+
+/* CMAP */
+
+#define CMAP_DCBCRS_ADDRESS_LOW 0
+#define CMAP_DCBCRS_ADDRESS_HIGH 1
+#define CMAP_DCBCRS_PALETTE 2
+#define CMAP_DCBCRS_REVISION 6
+
+/* XMAP9 */
+
+#define XMAP9_DCBCRS_CONFIG 0
+#define XMAP9_CONFIG_PUP_ENABLE 0x01
+#define XMAP9_CONFIG_ODD_PIXEL 0x02
+#define XMAP9_CONFIG_8BIT_SYSTEM 0x04
+#define XMAP9_CONFIG_SLOW_PCLK 0x08
+#define XMAP9_CONFIG_RGBMAP_CI 0x00
+#define XMAP9_CONFIG_RGBMAP_0 0x10
+#define XMAP9_CONFIG_RGBMAP_1 0x20
+#define XMAP9_CONFIG_RGBMAP_2 0x30
+#define XMAP9_CONFIG_EXPRESS_MODE 0x40
+#define XMAP9_CONFIG_VIDEO_ENABLE 0x80
+#define XMAP9_DCBCRS_REVISION 1
+#define XMAP9_DCBCRS_FIFOAVAIL 2
+#define XMAP9_DCBCRS_CURSOR_CMAP 3
+#define XMAP9_DCBCRS_PUP_CMAP 4
+#define XMAP9_DCBCRS_MODE_SETUP 5
+#define XMAP9_MODE_GAMMA_BYPASS 0x000004
+#define XMAP9_MODE_PIXSIZE_8BPP 0x000400
+#define XMAP9_DCBCRS_MODE_SELECT 7
+
+/* DCB addresses */
+
+#define NEWPORT_DCBADDR_VC2 0
+#define NEWPORT_DCBADDR_CMAP_BOTH 1
+#define NEWPORT_DCBADDR_CMAP_0 2
+#define NEWPORT_DCBADDR_CMAP_1 3
+#define NEWPORT_DCBADDR_XMAP_BOTH 4
+#define NEWPORT_DCBADDR_XMAP_0 5
+#define NEWPORT_DCBADDR_XMAP_1 6
+#define NEWPORT_DCBADDR_RAMDAC 7
+#define NEWPORT_DCBADDR_VIDEO_CC1 8
+#define NEWPORT_DCBADDR_VIDEO_AB1 9
diff --git a/sys/arch/sgi/gio/newportvar.h b/sys/arch/sgi/gio/newportvar.h
new file mode 100644
index 00000000000..9cc160d9d10
--- /dev/null
+++ b/sys/arch/sgi/gio/newportvar.h
@@ -0,0 +1,34 @@
+/* $OpenBSD: newportvar.h,v 1.1 2012/04/16 22:31:36 miod Exp $ */
+/* $NetBSD: newportvar.h,v 1.3 2011/07/01 18:53:46 dyoung Exp $ */
+
+/*
+ * 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>>
+ */
+
+int newport_cnattach(struct gio_attach_args *);
+int newport_cnprobe(struct gio_attach_args *);
diff --git a/sys/arch/sgi/hpc/pckbc_hpc.c b/sys/arch/sgi/hpc/pckbc_hpc.c
new file mode 100644
index 00000000000..e1b2bcd2751
--- /dev/null
+++ b/sys/arch/sgi/hpc/pckbc_hpc.c
@@ -0,0 +1,143 @@
+/* $OpenBSD: pckbc_hpc.c,v 1.1 2012/04/16 22:31:36 miod Exp $ */
+/* $NetBSD: pckbc_hpc.c,v 1.9 2008/03/15 13:23:24 cube Exp $ */
+
+/*
+ * Copyright (c) 2003 Christopher SEKIYA
+ * 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 following acknowledgement:
+ * This product includes software developed for the
+ * NetBSD Project. See http://www.NetBSD.org/ for
+ * information about NetBSD.
+ * 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/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+
+#include <machine/autoconf.h>
+#include <machine/bus.h>
+#include <mips64/archtype.h>
+
+#include <sgi/hpc/hpcreg.h>
+#include <sgi/hpc/hpcvar.h>
+#include <sgi/sgi/ip22.h>
+
+#include <dev/ic/i8042reg.h>
+#include <dev/ic/pckbcvar.h>
+
+struct pckbc_hpc_softc {
+ struct pckbc_softc sc_pckbc;
+
+ int sc_irq;
+ int sc_hasintr;
+};
+
+int pckbc_hpc_match(struct device *, void *, void *);
+void pckbc_hpc_attach(struct device *, struct device *, void *);
+void pckbc_hpc_intr_establish(struct pckbc_softc *, pckbc_slot_t);
+
+const struct cfattach pckbc_hpc_ca = {
+ sizeof(struct pckbc_hpc_softc), pckbc_hpc_match, pckbc_hpc_attach
+};
+
+int
+pckbc_hpc_match(struct device *parent, void *vcf, void *aux)
+{
+ struct cfdata *cf = vcf;
+ struct hpc_attach_args *ha = aux;
+
+ /* keyboard controller is not wired on Challenge S */
+ if (sys_config.system_subtype == IP22_CHALLS)
+ return 0;
+
+ if (strcmp(ha->ha_name, cf->cf_driver->cd_name) == 0)
+ return 1;
+
+ return 0;
+}
+
+void
+pckbc_hpc_attach(struct device *parent, struct device * self, void *aux)
+{
+ struct pckbc_hpc_softc *msc = (struct pckbc_hpc_softc *)self;
+ struct pckbc_softc *sc = &msc->sc_pckbc;
+ struct hpc_attach_args *haa = aux;
+ struct pckbc_internal *t = NULL;
+ bus_space_handle_t ioh_d, ioh_c;
+ int console;
+
+ msc->sc_irq = haa->ha_irq;
+ msc->sc_hasintr = 0;
+
+ console = pckbc_is_console(haa->ha_st,
+ XKPHYS_TO_PHYS(haa->ha_sh + haa->ha_devoff + 3));
+
+ if (console) {
+ /* pckbc_cnattach() has already been called */
+ t = &pckbc_consdata;
+ pckbc_console_attached = 1;
+ } else {
+ if (bus_space_subregion(haa->ha_st, haa->ha_sh,
+ haa->ha_devoff + 3 + KBDATAP, 1, &ioh_d) ||
+ bus_space_subregion(haa->ha_st, haa->ha_sh,
+ haa->ha_devoff + 3 + KBCMDP, 1, &ioh_c)) {
+ printf(": couldn't map registers\n");
+ return;
+ }
+
+ t = malloc(sizeof(*t), M_DEVBUF, M_NOWAIT | M_ZERO);
+ t->t_iot = haa->ha_st;
+ t->t_ioh_c = ioh_c;
+ t->t_ioh_d = ioh_d;
+ }
+
+ sc->intr_establish = pckbc_hpc_intr_establish;
+
+ t->t_cmdbyte = KC8_CPU;
+ t->t_sc = sc;
+ sc->id = t;
+
+ printf("\n");
+ pckbc_attach(sc, 0);
+}
+
+void
+pckbc_hpc_intr_establish(struct pckbc_softc *sc, pckbc_slot_t slot)
+{
+ struct pckbc_hpc_softc *msc = (struct pckbc_hpc_softc *)sc;
+
+ if (msc->sc_hasintr)
+ return;
+
+ if (hpc_intr_establish(msc->sc_irq, IPL_TTY, pckbcintr, sc,
+ sc->sc_dv.dv_xname) == NULL) {
+ printf("%s: unable to establish interrupt for %s slot\n",
+ sc->sc_dv.dv_xname, pckbc_slot_names[slot]);
+ } else {
+ msc->sc_hasintr = 1;
+ }
+}