diff options
author | 2019-01-12 16:59:38 +0000 | |
---|---|---|
committer | 2019-01-12 16:59:38 +0000 | |
commit | 4c76d6caa7a3bb2f8b3e92f0155c46acb2ada8db (patch) | |
tree | df6eb609e12ea5faa5fadf460e371151f2a00b26 | |
parent | Fix potential use-after-free if xfer allocation fails when otus(4) attaches. (diff) | |
download | wireguard-openbsd-4c76d6caa7a3bb2f8b3e92f0155c46acb2ada8db.tar.xz wireguard-openbsd-4c76d6caa7a3bb2f8b3e92f0155c46acb2ada8db.zip |
Add a driver for OCTEON GPIO controller.
-rw-r--r-- | sys/arch/octeon/conf/GENERIC | 3 | ||||
-rw-r--r-- | sys/arch/octeon/conf/RAMDISK | 3 | ||||
-rw-r--r-- | sys/arch/octeon/conf/files.octeon | 6 | ||||
-rw-r--r-- | sys/arch/octeon/dev/octgpio.c | 192 |
4 files changed, 201 insertions, 3 deletions
diff --git a/sys/arch/octeon/conf/GENERIC b/sys/arch/octeon/conf/GENERIC index 6ccb10f2ed7..60739b108df 100644 --- a/sys/arch/octeon/conf/GENERIC +++ b/sys/arch/octeon/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.44 2018/08/22 15:38:46 mpi Exp $ +# $OpenBSD: GENERIC,v 1.45 2019/01/12 16:59:38 visa Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -53,6 +53,7 @@ com* at fdt_octeon? octcib* at fdt? # Interrupt controller octcit* at fdt? # Interrupt controller v3 octciu* at fdt? # Interrupt controller v1 +octgpio* at fdt? # GPIO controller octmmc* at fdt? # MMC host controller sdmmc* at octmmc? # SD/MMC bus diff --git a/sys/arch/octeon/conf/RAMDISK b/sys/arch/octeon/conf/RAMDISK index c3f8b701457..329bdfcb5fc 100644 --- a/sys/arch/octeon/conf/RAMDISK +++ b/sys/arch/octeon/conf/RAMDISK @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISK,v 1.38 2018/06/01 17:15:27 visa Exp $ +# $OpenBSD: RAMDISK,v 1.39 2019/01/12 16:59:38 visa Exp $ machine octeon mips64 maxusers 4 @@ -53,6 +53,7 @@ com* at fdt_octeon? octcib* at fdt? # Interrupt controller octcit* at fdt? # Interrupt controller v3 octciu* at fdt? # Interrupt controller v1 +octgpio* at fdt? # GPIO controller octmmc* at fdt? # MMC host controller sdmmc* at octmmc? # SD/MMC bus diff --git a/sys/arch/octeon/conf/files.octeon b/sys/arch/octeon/conf/files.octeon index af6f4b96bf4..9c57abd094a 100644 --- a/sys/arch/octeon/conf/files.octeon +++ b/sys/arch/octeon/conf/files.octeon @@ -1,4 +1,4 @@ -# $OpenBSD: files.octeon,v 1.48 2018/06/01 17:15:27 visa Exp $ +# $OpenBSD: files.octeon,v 1.49 2019/01/12 16:59:38 visa Exp $ # Standard stanzas config(8) can't run without maxpartitions 16 @@ -145,6 +145,10 @@ device octciu attach octciu at fdt file arch/octeon/dev/octciu.c octciu +device octgpio +attach octgpio at fdt +file arch/octeon/dev/octgpio.c octgpio + device octmmc: sdmmcbus attach octmmc at fdt file arch/octeon/dev/octmmc.c octmmc diff --git a/sys/arch/octeon/dev/octgpio.c b/sys/arch/octeon/dev/octgpio.c new file mode 100644 index 00000000000..83bb314ddc1 --- /dev/null +++ b/sys/arch/octeon/dev/octgpio.c @@ -0,0 +1,192 @@ +/* $OpenBSD: octgpio.c,v 1.1 2019/01/12 16:59:38 visa Exp $ */ + +/* + * Copyright (c) 2019 Visa Hankala + * + * 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 OCTEON GPIO controller. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> +#include <sys/malloc.h> + +#include <dev/ofw/fdt.h> +#include <dev/ofw/ofw_gpio.h> +#include <dev/ofw/openfirm.h> + +#include <machine/fdt.h> +#include <machine/octeon_model.h> + +#define GPIO_BIT_CFG(x) (0x0000u + (x) * 8) +#define GPIO_BIT_CFG_INT_EN 0x0000000000000004ull +#define GPIO_BIT_CFG_RX_XOR 0x0000000000000002ull +#define GPIO_BIT_CFG_TX_OE 0x0000000000000001ull +#define GPIO_XBIT_CFG(x) (0x0100u + (x) * 8) +#define GPIO_RX_DAT 0x0080u +#define GPIO_TX_SET 0x0088u +#define GPIO_TX_CLR 0x0090u + +#define GPIO_RD_8(sc, reg) \ + bus_space_read_8((sc)->sc_iot, (sc)->sc_ioh, (reg)) +#define GPIO_WR_8(sc, reg, val) \ + bus_space_write_8((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) + +struct octgpio_softc { + struct device sc_dev; + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + struct gpio_controller sc_gc; + uint32_t sc_npins; + uint32_t sc_xbit; +}; + +int octgpio_match(struct device *, void *, void *); +void octgpio_attach(struct device *, struct device *, void *); + +void octgpio_config_pin(void *, uint32_t *, int); +int octgpio_get_pin(void *, uint32_t *); +void octgpio_set_pin(void *, uint32_t *, int); + +const struct cfattach octgpio_ca = { + sizeof(struct octgpio_softc), octgpio_match, octgpio_attach +}; + +struct cfdriver octgpio_cd = { + NULL, "octgpio", DV_DULL +}; + +int +octgpio_match(struct device *parent, void *match, void *aux) +{ + struct fdt_attach_args *faa = aux; + + return OF_is_compatible(faa->fa_node, "cavium,octeon-3860-gpio") || + OF_is_compatible(faa->fa_node, "cavium,octeon-7890-gpio"); +} + +void +octgpio_attach(struct device *parent, struct device *self, void *aux) +{ + struct fdt_attach_args *faa = aux; + struct octgpio_softc *sc = (struct octgpio_softc *)self; + uint32_t chipid; + + if (faa->fa_nreg != 1) { + printf(": no registers\n"); + return; + } + + sc->sc_iot = faa->fa_iot; + if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, faa->fa_reg[0].size, + 0, &sc->sc_ioh)) { + printf(": can't map registers\n"); + return; + } + + chipid = octeon_get_chipid(); + switch (octeon_model_family(chipid)) { + case OCTEON_MODEL_FAMILY_CN61XX: + case OCTEON_MODEL_FAMILY_CN63XX: + case OCTEON_MODEL_FAMILY_CN66XX: + case OCTEON_MODEL_FAMILY_CN68XX: + case OCTEON_MODEL_FAMILY_CN71XX: + sc->sc_npins = 20; + sc->sc_xbit = 16; + break; + case OCTEON_MODEL_FAMILY_CN73XX: + sc->sc_npins = 32; + sc->sc_xbit = 0; + break; + case OCTEON_MODEL_FAMILY_CN78XX: + sc->sc_npins = 20; + sc->sc_xbit = 0; + break; + default: + sc->sc_npins = 24; + sc->sc_xbit = 16; + break; + } + + sc->sc_gc.gc_node = faa->fa_node; + sc->sc_gc.gc_cookie = sc; + sc->sc_gc.gc_config_pin = octgpio_config_pin; + sc->sc_gc.gc_get_pin = octgpio_get_pin; + sc->sc_gc.gc_set_pin = octgpio_set_pin; + gpio_controller_register(&sc->sc_gc); + + printf(": %u pins, xbit %u\n", sc->sc_npins, sc->sc_xbit); +} + +void +octgpio_config_pin(void *cookie, uint32_t *cells, int config) +{ + struct octgpio_softc *sc = cookie; + uint64_t reg, value; + uint32_t pin = cells[0]; + + if (pin >= sc->sc_npins) + return; + if (pin >= sc->sc_xbit) + reg = GPIO_XBIT_CFG(pin - sc->sc_xbit); + else + reg = GPIO_BIT_CFG(pin); + + value = GPIO_RD_8(sc, reg); + if (config & GPIO_CONFIG_OUTPUT) + value |= GPIO_BIT_CFG_TX_OE; + else + value &= ~(GPIO_BIT_CFG_TX_OE | GPIO_BIT_CFG_RX_XOR); + /* There is no INT_EN bit on true XBIT pins. */ + value &= ~GPIO_BIT_CFG_INT_EN; + GPIO_WR_8(sc, reg, value); +} + +int +octgpio_get_pin(void *cookie, uint32_t *cells) +{ + struct octgpio_softc *sc = cookie; + uint32_t pin = cells[0]; + uint32_t flags = cells[1]; + int value; + + if (pin >= sc->sc_npins) + return 0; + + value = (GPIO_RD_8(sc, GPIO_RX_DAT) >> pin) & 1; + if (flags & GPIO_ACTIVE_LOW) + value = !value; + return value; +} + +void +octgpio_set_pin(void *cookie, uint32_t *cells, int value) +{ + struct octgpio_softc *sc = cookie; + uint32_t pin = cells[0]; + uint32_t flags = cells[1]; + + if (pin >= sc->sc_npins) + return; + + if (flags & GPIO_ACTIVE_LOW) + value = !value; + if (value) + GPIO_WR_8(sc, GPIO_TX_SET, 1ul << pin); + else + GPIO_WR_8(sc, GPIO_TX_CLR, 1ul << pin); +} |