commit f0ae126708edb44ac3956cef4b8b87eb28f9482f Author: Mitchell Horne Date: Tue Dec 10 16:38:14 2024 -0400 WIP: JH7110 GPIO updates/improvements diff --git a/sys/riscv/starfive/files.starfive b/sys/riscv/starfive/files.starfive index 043421f37e2c..5da00b9acbef 100644 --- a/sys/riscv/starfive/files.starfive +++ b/sys/riscv/starfive/files.starfive @@ -2,7 +2,7 @@ dev/clk/starfive/jh7110_clk.c standard dev/clk/starfive/jh7110_clk_aon.c standard dev/clk/starfive/jh7110_clk_pll.c standard dev/clk/starfive/jh7110_clk_sys.c standard -dev/clk/starfive/jh7110_gpio.c optional gpio fdt +dev/clk/starfive/jh7110_clk_stg.c standard dev/mmc/host/dwmmc_starfive.c optional dwmmc_starfive fdt dev/usb/controller/cdns3/cdns3_starfive.c standard @@ -10,4 +10,5 @@ dev/eqos/if_eqos.c optional eqos dev/eqos/if_eqos_if.m optional eqos dev/eqos/if_eqos_starfive.c optional eqos +riscv/starfive/jh7110_gpio.c optional gpio fdt riscv/starfive/starfive_syscon.c standard diff --git a/sys/riscv/starfive/jh7110_gpio.c b/sys/riscv/starfive/jh7110_gpio.c index a71e45687d4d..9be0ee3704f5 100644 --- a/sys/riscv/starfive/jh7110_gpio.c +++ b/sys/riscv/starfive/jh7110_gpio.c @@ -45,6 +45,7 @@ struct jh7110_gpio_softc { struct mtx mtx; struct resource *res; clk_t clk; + struct gpio_pin gpio_pins[JH7110_GPIO_PINS]; }; static struct ofw_compat_data compat_data[] = { @@ -129,24 +130,52 @@ jh7110_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) return (0); } +static int +jh7110_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) +{ + struct jh7110_gpio_softc *sc; + + sc = device_get_softc(dev); + + if (pin >= JH7110_GPIO_PINS) + return (EINVAL); + + JH7110_GPIO_LOCK(sc); + *caps = sc->gpio_pins[pin].gp_caps; + JH7110_GPIO_UNLOCK(sc); + + return (0); +} + static int jh7110_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) { struct jh7110_gpio_softc *sc; - uint32_t reg; sc = device_get_softc(dev); if (pin >= JH7110_GPIO_PINS) return (EINVAL); - /* Reading the direction */ JH7110_GPIO_LOCK(sc); - reg = JH7110_GPIO_READ(sc, GP0_DOEN_CFG + ALIGN_4(pin)); - if ((reg & ENABLE_MASK << MOD_4(pin) * 8) == 0) - *flags |= GPIO_PIN_OUTPUT; - else - *flags |= GPIO_PIN_INPUT; + *flags = sc->gpio_pins[pin].gp_flags; + JH7110_GPIO_UNLOCK(sc); + + return (0); +} + +static int +jh7110_gpio_pin_getname(device_t dev, uint32_t pin, char *name) +{ + struct jh7110_gpio_softc *sc; + + sc = device_get_softc(dev); + + if (pin >= JH7110_GPIO_PINS) + return (EINVAL); + + JH7110_GPIO_LOCK(sc); + memcpy(name, sc->gpio_pins[pin].gp_name, GPIOMAXNAME); JH7110_GPIO_UNLOCK(sc); return (0); @@ -166,16 +195,22 @@ jh7110_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) /* Setting the direction, enable or disable output */ JH7110_GPIO_LOCK(sc); - if (flags & GPIO_PIN_INPUT) { + if ((flags & GPIO_PIN_INPUT) != 0) { reg = JH7110_GPIO_READ(sc, GP0_DOUT_CFG + ALIGN_4(pin)); reg &= ~(ENABLE_MASK << MOD_4(pin) * 8); reg |= 1 << MOD_4(pin) * 8; JH7110_GPIO_WRITE(sc, GP0_DOUT_CFG + ALIGN_4(pin), reg); - } else if (flags & GPIO_PIN_OUTPUT) { + + sc->gpio_pins[pin].gp_flags &= ~GPIO_PIN_OUTPUT; + sc->gpio_pins[pin].gp_flags |= GPIO_PIN_INPUT; + } else if ((flags & GPIO_PIN_OUTPUT) != 0) { reg = JH7110_GPIO_READ(sc, GP0_DOUT_CFG + ALIGN_4(pin)); reg &= ~(ENABLE_MASK << MOD_4(pin) * 8); reg |= 0 << MOD_4(pin) * 8; JH7110_GPIO_WRITE(sc, GP0_DOUT_CFG + ALIGN_4(pin), reg); + + sc->gpio_pins[pin].gp_flags &= ~GPIO_PIN_INPUT; + sc->gpio_pins[pin].gp_flags |= GPIO_PIN_OUTPUT; } JH7110_GPIO_UNLOCK(sc); @@ -203,8 +238,11 @@ jh7110_gpio_detach(device_t dev) sc = device_get_softc(dev); - bus_release_resources(dev, jh7110_gpio_spec, &sc->res); gpiobus_detach_bus(dev); + if (sc->clk != NULL) { + clk_release(sc->clk); + } + bus_release_resources(dev, jh7110_gpio_spec, &sc->res); mtx_destroy(&sc->mtx); return (0); @@ -214,16 +252,15 @@ static int jh7110_gpio_attach(device_t dev) { struct jh7110_gpio_softc *sc; - int err; + uint32_t reg; sc = device_get_softc(dev); sc->dev = dev; mtx_init(&sc->mtx, device_get_nameunit(sc->dev), NULL, MTX_DEF); - if (bus_alloc_resources(dev, jh7110_gpio_spec, &sc->res)) { + if (bus_alloc_resources(dev, jh7110_gpio_spec, &sc->res) != 0) { device_printf(dev, "Could not allocate resources\n"); - bus_release_resources(dev, jh7110_gpio_spec, &sc->res); mtx_destroy(&sc->mtx); return (ENXIO); } @@ -234,8 +271,7 @@ jh7110_gpio_attach(device_t dev) return (ENXIO); } - err = clk_enable(sc->clk); - if (err != 0) { + if (clk_enable(sc->clk) != 0) { device_printf(dev, "Could not enable clock %s\n", clk_get_name(sc->clk)); jh7110_gpio_detach(dev); @@ -249,7 +285,19 @@ jh7110_gpio_attach(device_t dev) return (ENXIO); } - /* Reseting GPIO interrupts */ + for (int i = 0; i < JH7110_GPIO_PINS; i++) { + reg = JH7110_GPIO_READ(sc, GP0_DOEN_CFG + ALIGN_4(i)); + + sc->gpio_pins[i].gp_pin = i; + sc->gpio_pins[i].gp_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT; + sc->gpio_pins[i].gp_flags = + ((reg & ENABLE_MASK << MOD_4(i) * 8) == 0) ? + GPIO_PIN_INPUT : GPIO_PIN_OUTPUT; + + snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME, "GPIO %d", i); + } + + /* Disable all GPIO interrupts. */ JH7110_GPIO_WRITE(sc, GPIOE_0, 0); JH7110_GPIO_WRITE(sc, GPIOE_1, 0); JH7110_GPIO_WRITE(sc, GPIOEN, 1); @@ -272,8 +320,10 @@ static device_method_t jh7110_gpio_methods[] = { /* GPIO protocol */ DEVMETHOD(gpio_get_bus, jh7110_gpio_get_bus), DEVMETHOD(gpio_pin_max, jh7110_gpio_pin_max), + DEVMETHOD(gpio_pin_getcaps, jh7110_gpio_pin_getcaps), DEVMETHOD(gpio_pin_getflags, jh7110_gpio_pin_getflags), DEVMETHOD(gpio_pin_setflags, jh7110_gpio_pin_setflags), + DEVMETHOD(gpio_pin_getname, jh7110_gpio_pin_getname), DEVMETHOD(gpio_pin_get, jh7110_gpio_pin_get), DEVMETHOD(gpio_pin_set, jh7110_gpio_pin_set),