summaryrefslogtreecommitdiff
path: root/sys/arch/sgi/gio
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2012-04-18 17:28:25 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2012-04-18 17:28:25 +0000
commit7733653e71155e17cac84345e1c8dbd080f6c0b2 (patch)
tree518bb2772904bfacde0e404039349c3413931749 /sys/arch/sgi/gio
parent6f87851cb7fdd0607b5acf0225911e4b319d6e0d (diff)
Split the existing impact@xbow attachment into generic impact routines, and
bus-specific attachment; impactreg.h and impactvar.h move from sgi/xbow/ to sgi/dev/. Teach the generic impact code how to code with pre-ImpactSR boards, which have a slightly different register layout (information obtained from Peter Fuerst's Linux IP28 patches). Add an impact@gio attachment (unfortunately untested, no Impact GIO boards here). All Indigo 2 graphics options should be supported now (assuming the Extreme/Ultra will actually work with grtwo(4) out of the box). Tested not to disturb operation on IP30. ** ATTENTION! If you are building IP27 or IP30 kernels, be sure to rm impact.d ** before building a new kernel.
Diffstat (limited to 'sys/arch/sgi/gio')
-rw-r--r--sys/arch/sgi/gio/files.gio19
-rw-r--r--sys/arch/sgi/gio/gio.c88
-rw-r--r--sys/arch/sgi/gio/impact_gio.c142
3 files changed, 202 insertions, 47 deletions
diff --git a/sys/arch/sgi/gio/files.gio b/sys/arch/sgi/gio/files.gio
index f8131536844..e915bdd4cb8 100644
--- a/sys/arch/sgi/gio/files.gio
+++ b/sys/arch/sgi/gio/files.gio
@@ -1,31 +1,36 @@
-# $OpenBSD: files.gio,v 1.2 2012/04/17 15:36:55 miod Exp $
+# $OpenBSD: files.gio,v 1.3 2012/04/18 17:28:24 miod Exp $
# $NetBSD: files.gio,v 1.11 2009/02/12 06:33:57 rumble Exp $
device gio {[slot = -1], [addr = -1]}
attach gio at giobus
-file arch/sgi/gio/gio.c gio needs-flag
+file arch/sgi/gio/gio.c gio needs-flag
device hpc {[offset = -1]}: smc93cx6
attach hpc at gio
-file arch/sgi/hpc/hpc.c hpc
+file arch/sgi/hpc/hpc.c hpc
# XL graphics
device newport: wsemuldisplaydev, rasops8
attach newport at gio
-file arch/sgi/gio/newport.c newport needs-flag
+file arch/sgi/gio/newport.c newport needs-flag
# GR2 graphics
device grtwo: wsemuldisplaydev, rasops8
attach grtwo at gio
-file arch/sgi/gio/grtwo.c grtwo needs-flag
+file arch/sgi/gio/grtwo.c grtwo needs-flag
# LG1/LG2 graphics
device light: wsemuldisplaydev, rasops8
attach light at gio
-file arch/sgi/gio/light.c light needs-flag
+file arch/sgi/gio/light.c light needs-flag
+
+# Impact graphics
+attach impact at gio with impact_gio
+file arch/sgi/gio/impact_gio.c impact &
+ impact_gio needs-flag
# PCI cards glued to the GIO bus
device giopci: pcibus
attach giopci at gio
-file arch/sgi/gio/pci_gio.c giopci
+file arch/sgi/gio/pci_gio.c giopci
diff --git a/sys/arch/sgi/gio/gio.c b/sys/arch/sgi/gio/gio.c
index 039d7202e16..e2d42e50ff4 100644
--- a/sys/arch/sgi/gio/gio.c
+++ b/sys/arch/sgi/gio/gio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gio.c,v 1.4 2012/04/18 10:59:45 miod Exp $ */
+/* $OpenBSD: gio.c,v 1.5 2012/04/18 17:28:24 miod Exp $ */
/* $NetBSD: gio.c,v 1.32 2011/07/01 18:53:46 dyoung Exp $ */
/*
@@ -59,6 +59,7 @@
#include <sgi/gio/gioreg.h>
#include <sgi/gio/giovar.h>
+#include <sgi/gio/giodevs.h>
#include <sgi/gio/giodevs_data.h>
#include <sgi/gio/grtworeg.h>
@@ -68,12 +69,16 @@
#include <sgi/sgi/ip22.h>
#include "grtwo.h"
+#include "impact.h"
#include "light.h"
#include "newport.h"
#if NGRTWO > 0
#include <sgi/gio/grtwovar.h>
#endif
+#if NIMPACT_GIO > 0
+#include <sgi/dev/impactvar.h>
+#endif
#if NLIGHT > 0
#include <sgi/gio/lightvar.h>
#endif
@@ -273,9 +278,6 @@ gio_attach(struct device *parent, struct device *self, void *aux)
slot_bases[i].mach_subtype != sys_config.system_subtype)
continue;
- if (slot_bases[i].base == giofb_consaddr)
- continue;
-
for (j = 0; j < ngfx; j++) {
if (slot_bases[i].base == gfx[j]) {
skip = 1;
@@ -367,7 +369,7 @@ gio_id(vaddr_t va, paddr_t pa, int maybe_gfx)
/*
* If there is a frame buffer device, then either we have hit a
* device register (light, grtwo), or we did not fault because
- * the slot is pipelined (impact, newport).
+ * the slot is pipelined (newport).
* In the latter case, we attempt to probe a known register
* offset.
*/
@@ -376,17 +378,8 @@ gio_id(vaddr_t va, paddr_t pa, int maybe_gfx)
if (id32 != 4 || id16 != 2 || id8 != 1)
return GIO_FAKE_FB_ID;
- /* could be impact(4) */
- va += 0x70000;
- if (guarded_read_4(va, &id32) == 0 &&
- guarded_read_2(va | 2, &id16) == 0 &&
- guarded_read_1(va | 3, &id8) == 0) {
- if (id32 != 4 || id16 != 2 || id8 != 1)
- return GIO_FAKE_FB_ID;
- }
-
/* could be newport(4) */
- va += 0x80000;
+ va += 0xf0000;
if (guarded_read_4(va, &id32) == 0 &&
guarded_read_2(va | 2, &id16) == 0 &&
guarded_read_1(va | 3, &id8) == 0) {
@@ -522,21 +515,29 @@ giofb_cnprobe()
ga.ga_product = -1;
ga.ga_descr = NULL;
- if (gio_id(ga.ga_ioh, ga.ga_addr, 1) != GIO_FAKE_FB_ID)
- continue;
-
+ switch (gio_id(ga.ga_ioh, ga.ga_addr, 1)) {
+ case GIO_PRODUCT_IMPACT:
+#if NIMPACT_GIO > 0
+ ga.ga_product = GIO_PRODUCT_IMPACT;
+ if (impact_gio_cnprobe(&ga) != 0)
+ return 0;
+#endif
+ break;
+ case GIO_FAKE_FB_ID:
#if NGRTWO > 0
- if (grtwo_cnprobe(&ga) != 0)
- return 0;
+ if (grtwo_cnprobe(&ga) != 0)
+ return 0;
#endif
#if NLIGHT > 0
- if (light_cnprobe(&ga) != 0)
- return 0;
+ if (light_cnprobe(&ga) != 0)
+ return 0;
#endif
#if NNEWPORT > 0
- if (newport_cnprobe(&ga) != 0)
- return 0;
+ if (newport_cnprobe(&ga) != 0)
+ return 0;
#endif
+ break;
+ }
}
return ENXIO;
@@ -569,28 +570,35 @@ giofb_cnattach()
ga.ga_product = -1;
ga.ga_descr = NULL;
- if (gio_id(ga.ga_ioh, ga.ga_addr, 1) != GIO_FAKE_FB_ID)
- continue;
-
- /*
- * We still need to probe before attach since we don't
- * know the frame buffer type here.
- */
+ switch (gio_id(ga.ga_ioh, ga.ga_addr, 1)) {
+ case GIO_PRODUCT_IMPACT:
+#if NIMPACT_GIO > 0
+ if (impact_gio_cnattach(&ga) == 0)
+ return 0;
+#endif
+ break;
+ case GIO_FAKE_FB_ID:
+ /*
+ * We still need to probe before attach since we don't
+ * know the frame buffer type here.
+ */
#if NGRTWO > 0
- if (grtwo_cnprobe(&ga) != 0 &&
- grtwo_cnattach(&ga) == 0)
- return 0;
+ if (grtwo_cnprobe(&ga) != 0 &&
+ grtwo_cnattach(&ga) == 0)
+ return 0;
#endif
#if NLIGHT > 0
- if (light_cnprobe(&ga) != 0 &&
- light_cnattach(&ga) == 0)
- return 0;
+ if (light_cnprobe(&ga) != 0 &&
+ light_cnattach(&ga) == 0)
+ return 0;
#endif
#if NNEWPORT > 0
- if (newport_cnprobe(&ga) != 0 &&
- newport_cnattach(&ga) == 0)
- return 0;
+ if (newport_cnprobe(&ga) != 0 &&
+ newport_cnattach(&ga) == 0)
+ return 0;
#endif
+ break;
+ }
}
giofb_consaddr = 0;
diff --git a/sys/arch/sgi/gio/impact_gio.c b/sys/arch/sgi/gio/impact_gio.c
new file mode 100644
index 00000000000..4fb2f2b6ee3
--- /dev/null
+++ b/sys/arch/sgi/gio/impact_gio.c
@@ -0,0 +1,142 @@
+/* $OpenBSD: impact_gio.c,v 1.1 2012/04/18 17:28:24 miod 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.
+ */
+
+/*
+ * Driver for the SGI Impact graphics board (GIO attachment).
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/types.h>
+
+#include <machine/autoconf.h>
+#include <mips64/archtype.h>
+
+#include <mips64/arcbios.h>
+
+#include <sgi/dev/impactreg.h>
+#include <sgi/dev/impactvar.h>
+#include <sgi/gio/giodevs.h>
+#include <sgi/gio/gioreg.h>
+#include <sgi/gio/giovar.h>
+#include <sgi/sgi/ip22.h>
+
+#define IMPACT_REG_OFFSET 0x00000000
+#define IMPACT_REG_SIZE 0x00080000
+
+int impact_gio_match(struct device *, void *, void *);
+void impact_gio_attach(struct device *, struct device *, void *);
+
+const struct cfattach impact_gio_ca = {
+ sizeof(struct impact_softc), impact_gio_match, impact_gio_attach
+};
+
+int
+impact_gio_match(struct device *parent, void *match, void *aux)
+{
+ struct gio_attach_args *ga = aux;
+
+ /* Impact only exists on Indigo 2 systems */
+ if (sys_config.system_type != SGI_IP22 ||
+ sys_config.system_subtype != IP22_INDIGO2)
+ return 0;
+
+ /* not looking for a frame buffer */
+ if (ga->ga_slot != -1)
+ return 0;
+
+ /* EXP1 does not exist on Indigo2 */
+ if (ga->ga_addr != GIO_ADDR_GFX && ga->ga_addr != GIO_ADDR_EXP0)
+ return 0;
+
+ /* Impact has a real GIO ID */
+ if (ga->ga_product != GIO_PRODUCT_IMPACT)
+ return 0;
+
+ return 1;
+}
+
+void
+impact_gio_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct gio_attach_args *ga = aux;
+ struct impact_softc *sc = (struct impact_softc *)self;
+ bus_space_tag_t iot;
+ bus_space_handle_t ioh;
+ int console;
+
+ if (strncmp(bios_graphics, "alive", 5) != 0) {
+ printf(" device has not been setup by firmware!\n");
+ return;
+ }
+
+ console = giofb_consaddr == ga->ga_addr;
+
+ if (console != 0) {
+ iot = NULL;
+ ioh = 0;
+ } else {
+ iot = ga->ga_iot;
+
+ /* Setup bus space mappings. */
+ if (bus_space_map(iot, ga->ga_addr + IMPACT_REG_OFFSET,
+ IMPACT_REG_SIZE, 0, &ioh)) {
+ printf("failed to map registers\n");
+ return;
+ }
+ }
+
+ if (impact_attach_common(sc, iot, ioh, console, 0) != 0) {
+ if (console == 0)
+ bus_space_unmap(iot, ioh, IMPACT_REG_SIZE);
+ }
+}
+
+/*
+ * Console support.
+ */
+
+int
+impact_gio_cnprobe(struct gio_attach_args *ga)
+{
+ return impact_gio_match(NULL, NULL, ga);
+}
+
+int
+impact_gio_cnattach(struct gio_attach_args *ga)
+{
+ bus_space_tag_t iot;
+ bus_space_handle_t ioh;
+ int rc;
+
+ iot = ga->ga_iot;
+ rc = bus_space_map(iot, ga->ga_addr + IMPACT_REG_OFFSET,
+ IMPACT_REG_SIZE, 0, &ioh);
+ if (rc != 0)
+ return rc;
+
+ rc = impact_cnattach_common(iot, ioh, 0);
+ if (rc != 0) {
+ bus_space_unmap(iot, ioh, IMPACT_REG_SIZE);
+ return rc;
+ }
+
+ return 0;
+}