diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2012-04-18 17:28:25 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2012-04-18 17:28:25 +0000 |
commit | 7733653e71155e17cac84345e1c8dbd080f6c0b2 (patch) | |
tree | 518bb2772904bfacde0e404039349c3413931749 /sys/arch/sgi/gio | |
parent | 6f87851cb7fdd0607b5acf0225911e4b319d6e0d (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.gio | 19 | ||||
-rw-r--r-- | sys/arch/sgi/gio/gio.c | 88 | ||||
-rw-r--r-- | sys/arch/sgi/gio/impact_gio.c | 142 |
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; +} |