diff options
author | Alexander Yurchenko <grange@cvs.openbsd.org> | 2004-06-03 18:22:22 +0000 |
---|---|---|
committer | Alexander Yurchenko <grange@cvs.openbsd.org> | 2004-06-03 18:22:22 +0000 |
commit | 559da32aab1ceb9534a2e3843d87bf17b9c8dd07 (patch) | |
tree | 73dc1fa3997cdfa45e842a4a4362dcc494baea74 | |
parent | d4d87f9a7a3f4fdedbce6b4420f08f857036512c (diff) |
gscpcib(4) -- National Semiconductor Geode SC1100 PCI-ISA bridge driver.
Besides the core pcib(4) functionality, the gscpcib driver provides
support for the GPIO interface of this device.
ok deraadt@
-rw-r--r-- | sys/arch/i386/conf/GENERIC | 5 | ||||
-rw-r--r-- | sys/arch/i386/conf/RAMDISK | 4 | ||||
-rw-r--r-- | sys/arch/i386/conf/RAMDISKB | 4 | ||||
-rw-r--r-- | sys/arch/i386/conf/RAMDISKC | 4 | ||||
-rw-r--r-- | sys/arch/i386/conf/RAMDISK_CD | 4 | ||||
-rw-r--r-- | sys/arch/i386/conf/files.i386 | 9 | ||||
-rw-r--r-- | sys/arch/i386/pci/gscpcib.c | 208 | ||||
-rw-r--r-- | sys/arch/i386/pci/gscpcibreg.h | 42 |
8 files changed, 273 insertions, 7 deletions
diff --git a/sys/arch/i386/conf/GENERIC b/sys/arch/i386/conf/GENERIC index 3b84018218e..d0ac7b871df 100644 --- a/sys/arch/i386/conf/GENERIC +++ b/sys/arch/i386/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.365 2004/05/30 08:11:26 grange Exp $ +# $OpenBSD: GENERIC,v 1.366 2004/06/03 18:22:21 grange Exp $ # # GENERIC -- everything that's currently supported # @@ -46,6 +46,7 @@ pcibios0 at bios0 flags 0x0000 # use 0x30 for a total verbose isa0 at mainbus0 isa0 at pcib? isa0 at ichpcib? +isa0 at gscpcib? eisa0 at mainbus0 pci* at mainbus0 bus ? @@ -59,6 +60,8 @@ pci* at ppb? bus ? pci* at pchb? bus ? pcib* at pci? dev ? function ? # PCI-ISA bridge ichpcib* at pci? dev ? function ? # Intel ICHx/ICHx-M LPC bridges +gscpcib* at pci? dev ? function ? # NS Geode SC1100 PCI-ISA bridge +gpio* at gscpcib? # power management and other environmental stuff #amdpm* at pci? dev ? function ? # AMD768MPX diff --git a/sys/arch/i386/conf/RAMDISK b/sys/arch/i386/conf/RAMDISK index 26a3a1dfd3b..b7f528ea3d3 100644 --- a/sys/arch/i386/conf/RAMDISK +++ b/sys/arch/i386/conf/RAMDISK @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISK,v 1.128 2004/06/03 03:12:55 deraadt Exp $ +# $OpenBSD: RAMDISK,v 1.129 2004/06/03 18:22:21 grange Exp $ machine i386 # architecture, used by config; REQUIRED @@ -50,6 +50,7 @@ pcibios0 at bios0 flags 0x0000 isa0 at mainbus0 isa0 at pcib? isa0 at ichpcib? +isa0 at gscpcib? eisa0 at mainbus0 pci* at mainbus0 @@ -62,6 +63,7 @@ pci* at ppb? bus ? pci* at pchb? bus ? pcib* at pci? dev ? function ? # PCI-ISA bridge ichpcib* at pci? dev ? function ? # Intel ICHx/ICHx-M LPC bridges +gscpcib* at pci? dev ? function ? # NS Geode SC1100 PCI-ISA bridge # ISA PCMCIA controllers pcic0 at isa? port 0x3e0 iomem 0xd0000 iosiz 0x4000 diff --git a/sys/arch/i386/conf/RAMDISKB b/sys/arch/i386/conf/RAMDISKB index d9eb2bc96bd..c7a0d727224 100644 --- a/sys/arch/i386/conf/RAMDISKB +++ b/sys/arch/i386/conf/RAMDISKB @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISKB,v 1.69 2004/06/03 03:12:55 deraadt Exp $ +# $OpenBSD: RAMDISKB,v 1.70 2004/06/03 18:22:21 grange Exp $ machine i386 # architecture, used by config; REQUIRED @@ -50,6 +50,7 @@ pcibios0 at bios0 flags 0x0000 isa0 at mainbus0 isa0 at pcib? isa0 at ichpcib? +isa0 at gscpcib? eisa0 at mainbus0 pci* at mainbus0 @@ -62,6 +63,7 @@ pci* at ppb? bus ? pci* at pchb? bus ? pcib* at pci? dev ? function ? # PCI-ISA bridge ichpcib* at pci? dev ? function ? # Intel ICHx/ICHx-M LPC bridges +gscpcib* at pci? dev ? function ? # NS Geode SC1100 PCI-ISA bridge # ISA PCMCIA controllers #pcic0 at isa? port 0x3e0 iomem 0xd0000 iosiz 0x4000 diff --git a/sys/arch/i386/conf/RAMDISKC b/sys/arch/i386/conf/RAMDISKC index d2c0b3f28ec..76e9db57d6f 100644 --- a/sys/arch/i386/conf/RAMDISKC +++ b/sys/arch/i386/conf/RAMDISKC @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISKC,v 1.38 2004/06/03 04:07:38 deraadt Exp $ +# $OpenBSD: RAMDISKC,v 1.39 2004/06/03 18:22:21 grange Exp $ machine i386 # architecture, used by config; REQUIRED @@ -50,6 +50,7 @@ pcibios0 at bios0 flags 0x0000 isa0 at mainbus0 isa0 at pcib? isa0 at ichpcib? +isa0 at gscpcib? eisa0 at mainbus0 pci* at mainbus0 @@ -62,6 +63,7 @@ pci* at ppb? bus ? pci* at pchb? bus ? pcib* at pci? dev ? function ? # PCI-ISA bridge ichpcib* at pci? dev ? function ? # Intel ICHx/ICHx-M LPC bridges +gscpcib* at pci? dev ? function ? # NS Geode SC1100 PCI-ISA bridge # ISA PCMCIA controllers pcic0 at isa? port 0x3e0 iomem 0xd0000 iosiz 0x4000 diff --git a/sys/arch/i386/conf/RAMDISK_CD b/sys/arch/i386/conf/RAMDISK_CD index e628eb4d105..9f2213ba41e 100644 --- a/sys/arch/i386/conf/RAMDISK_CD +++ b/sys/arch/i386/conf/RAMDISK_CD @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISK_CD,v 1.72 2004/06/03 03:12:38 deraadt Exp $ +# $OpenBSD: RAMDISK_CD,v 1.73 2004/06/03 18:22:21 grange Exp $ machine i386 # architecture, used by config; REQUIRED @@ -51,6 +51,7 @@ pcibios0 at bios0 flags 0x0000 isa0 at mainbus0 isa0 at pcib? isa0 at ichpcib? +isa0 at gscpcib? eisa0 at mainbus0 pci* at mainbus0 @@ -63,6 +64,7 @@ pci* at ppb? bus ? pci* at pchb? bus ? pcib* at pci? dev ? function ? # PCI-ISA bridge ichpcib* at pci? dev ? function ? # Intel ICHx/ICHx-M LPC bridges +gscpcib* at pci? dev ? function ? # NS Geode SC1100 PCI-ISA bridge # CardBus bus support cardbus* at cardslot? diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386 index 3b81e09b868..71623e52636 100644 --- a/sys/arch/i386/conf/files.i386 +++ b/sys/arch/i386/conf/files.i386 @@ -1,4 +1,4 @@ -# $OpenBSD: files.i386,v 1.120 2004/06/03 18:13:13 grange Exp $ +# $OpenBSD: files.i386,v 1.121 2004/06/03 18:22:21 grange Exp $ # # new style config file for i386 architecture # @@ -121,13 +121,18 @@ file arch/i386/pci/geodesc.c geodesc # PCI-ISA bridge chipsets device pcib: isabus attach pcib at pci -file arch/i386/pci/pcib.c pcib | ichpcib +file arch/i386/pci/pcib.c pcib | ichpcib | gscpcib # Intel ICHx/ICHx-M LPC bridges device ichpcib: isabus attach ichpcib at pci file arch/i386/pci/ichpcib.c ichpcib +# National Semiconductor Geode SC1100 PCI-ISA bridge +device gscpcib: isabus, gpiobus +attach gscpcib at pci +file arch/i386/pci/gscpcib.c gscpcib + device hme: ether, ifnet, mii, ifmedia file dev/ic/hme.c hme attach hme at pci with hme_pci diff --git a/sys/arch/i386/pci/gscpcib.c b/sys/arch/i386/pci/gscpcib.c new file mode 100644 index 00000000000..19316ec1269 --- /dev/null +++ b/sys/arch/i386/pci/gscpcib.c @@ -0,0 +1,208 @@ +/* $OpenBSD: gscpcib.c,v 1.1 2004/06/03 18:22:21 grange Exp $ */ +/* + * Copyright (c) 2004 Alexander Yurchenko <grange@openbsd.org> + * + * 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. + */ + +/* + * Special driver for the National Semiconductor Geode SC1100 PCI-ISA bridge + * that attaches instead of pcib(4). In addition to the core pcib(4) + * functionality this driver provides support for the GPIO interface. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> +#include <sys/gpio.h> +#include <sys/kernel.h> + +#include <machine/bus.h> + +#include <dev/pci/pcidevs.h> +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> + +#include <dev/gpio/gpiovar.h> + +#include <i386/pci/gscpcibreg.h> + +#include "gpio.h" + +struct gscpcib_softc { + struct device sc_dev; + + /* GPIO interface */ + bus_space_tag_t sc_gpio_iot; + bus_space_handle_t sc_gpio_ioh; + struct gpio_chipset_tag sc_gpio_gc; + gpio_pin_t sc_gpio_pins[GSCGPIO_NPINS]; +}; + +int gscpcib_match(struct device *, void *, void *); +void gscpcib_attach(struct device *, struct device *, void *); + +int gscpcib_gpio_pin_read(void *, int); +void gscpcib_gpio_pin_write(void *, int, int); +void gscpcib_gpio_pin_ctl(void *, int, int); + +/* arch/i386/pci/pcib.c */ +void pcibattach(struct device *, struct device *, void *); + +struct cfattach gscpcib_ca = { + sizeof (struct gscpcib_softc), + gscpcib_match, + gscpcib_attach +}; + +struct cfdriver gscpcib_cd = { + NULL, "gscpcib", DV_DULL +}; + +int +gscpcib_match(struct device *parent, void *match, void *aux) +{ + struct pci_attach_args *pa = aux; + + if (PCI_CLASS(pa->pa_class) != PCI_CLASS_BRIDGE || + PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_BRIDGE_ISA) + return (0); + + if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NS && + PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NS_SC1100_ISA) + return (2); /* supersede pcib(4) */ + + return (0); +} + +void +gscpcib_attach(struct device *parent, struct device *self, void *aux) +{ +#if NGPIO > 0 + struct gscpcib_softc *sc = (struct gscpcib_softc *)self; + struct pci_attach_args *pa = aux; + struct gpiobus_attach_args gba; + pcireg_t gpiobase; + int i; + int gpio_present = 0; + + /* Map GPIO I/O space */ + gpiobase = pci_conf_read(pa->pa_pc, pa->pa_tag, GSCGPIO_BASE); + sc->sc_gpio_iot = pa->pa_iot; + if (bus_space_map(sc->sc_gpio_iot, PCI_MAPREG_IO_ADDR(gpiobase), + GSCGPIO_SIZE, 0, &sc->sc_gpio_ioh)) { + printf(": failed to map GPIO I/O space"); + goto corepcib; + } + + /* Initialize pins array */ + for (i = 0; i < GSCGPIO_NPINS; i++) { + sc->sc_gpio_pins[i].pin_num = i; + sc->sc_gpio_pins[i].pin_caps = GPIO_PIN_INPUT | + GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN | + GPIO_PIN_PUSHPULL | GPIO_PIN_TRISTATE | + GPIO_PIN_PULLUP; + + /* safe defaults */ + sc->sc_gpio_pins[i].pin_flags = GPIO_PIN_TRISTATE; + sc->sc_gpio_pins[i].pin_state = GPIO_PIN_LOW; + gscpcib_gpio_pin_ctl(sc, i, sc->sc_gpio_pins[i].pin_flags); + gscpcib_gpio_pin_write(sc, i, sc->sc_gpio_pins[i].pin_state); + } + + /* Create controller tag */ + sc->sc_gpio_gc.gp_cookie = sc; + sc->sc_gpio_gc.gp_pin_read = gscpcib_gpio_pin_read; + sc->sc_gpio_gc.gp_pin_write = gscpcib_gpio_pin_write; + sc->sc_gpio_gc.gp_pin_ctl = gscpcib_gpio_pin_ctl; + + gba.gba_name = "gpio"; + gba.gba_gc = &sc->sc_gpio_gc; + gba.gba_pins = sc->sc_gpio_pins; + gba.gba_npins = GSCGPIO_NPINS; + + gpio_present = 1; + +corepcib: +#endif + /* Provide core pcib(4) functionality */ + pcibattach(parent, self, aux); + +#if NGPIO > 0 + /* Attach GPIO framework */ + if (gpio_present) + config_found(&sc->sc_dev, &gba, gpiobus_print); +#endif +} + +#if NGPIO > 0 +static __inline void +gscpcib_gpio_pin_select(struct gscpcib_softc *sc, int pin) +{ + bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, GSCGPIO_SEL, pin); +} + +int +gscpcib_gpio_pin_read(void *arg, int pin) +{ + struct gscpcib_softc *sc = arg; + int reg, shift; + u_int32_t data; + + reg = (pin < 32 ? GSCGPIO_GPDI0 : GSCGPIO_GPDI1); + shift = pin % 32; + data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); + + return ((data >> shift) & 0x1); +} + +void +gscpcib_gpio_pin_write(void *arg, int pin, int value) +{ + struct gscpcib_softc *sc = arg; + int reg, shift; + u_int32_t data; + + reg = (pin < 32 ? GSCGPIO_GPDO0 : GSCGPIO_GPDO1); + shift = pin % 32; + data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); + if (value == 0) + data &= ~(1 << shift); + else if (value == 1) + data |= (1 << shift); + + bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg, data); +} + +void +gscpcib_gpio_pin_ctl(void *arg, int pin, int flags) +{ + struct gscpcib_softc *sc = arg; + u_int32_t conf; + + gscpcib_gpio_pin_select(sc, pin); + conf = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, + GSCGPIO_CONF); + + conf &= ~(GSCGPIO_CONF_OUTPUTEN | GSCGPIO_CONF_PUSHPULL | + GSCGPIO_CONF_PULLUP); + if ((flags & GPIO_PIN_TRISTATE) == 0) + conf |= GSCGPIO_CONF_OUTPUTEN; + if (flags & GPIO_PIN_PUSHPULL) + conf |= GSCGPIO_CONF_PUSHPULL; + if (flags & GPIO_PIN_PULLUP) + conf |= GSCGPIO_CONF_PULLUP; + bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, + GSCGPIO_CONF, conf); +} +#endif diff --git a/sys/arch/i386/pci/gscpcibreg.h b/sys/arch/i386/pci/gscpcibreg.h new file mode 100644 index 00000000000..9178f4e27ed --- /dev/null +++ b/sys/arch/i386/pci/gscpcibreg.h @@ -0,0 +1,42 @@ +/* $OpenBSD: gscpcibreg.h,v 1.1 2004/06/03 18:22:21 grange Exp $ */ +/* + * Copyright (c) 2004 Alexander Yurchenko <grange@openbsd.org> + * + * 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. + */ + +#ifndef _I386_PCI_GSCGPIOREG_H_ +#define _I386_PCI_GSCGPIOREG_H_ + +#define GSCGPIO_NPINS 64 + +#define GSCGPIO_BASE 0x10 +#define GSCGPIO_SIZE 64 + +#define GSCGPIO_GPDO0 0x00 +#define GSCGPIO_GPDI0 0x04 +#define GSCGPIO_GPIEN0 0x08 +#define GSCGPIO_GPST0 0x0c +#define GSCGPIO_GPDO1 0x10 +#define GSCGPIO_GPDI1 0x14 +#define GSCGPIO_GPIEN1 0x18 +#define GSCGPIO_GPST1 0x1c +#define GSCGPIO_SEL 0x20 +#define GSCGPIO_CONF 0x24 +#define GSCGPIO_RESET 0x28 + +#define GSCGPIO_CONF_OUTPUTEN (1 << 0) +#define GSCGPIO_CONF_PUSHPULL (1 << 1) +#define GSCGPIO_CONF_PULLUP (1 << 2) + +#endif /* !_I386_PCI_GSCGPIOREG_H_ */ |