Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F173372840
D59992.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D59992.diff
View Options
diff --git a/sys/riscv/starfive/jh7110_gpio.c b/sys/riscv/starfive/jh7110_gpio.c
--- a/sys/riscv/starfive/jh7110_gpio.c
+++ b/sys/riscv/starfive/jh7110_gpio.c
@@ -2,6 +2,10 @@
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2023 Jari Sihvola <jsihv@gmx.com>
+ * Copyright (c) 2025-2026 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Mitchell Horne
+ * <mhorne@FreeBSD.org> under sponsorship from the FreeBSD Foundation.
*/
#include <sys/param.h>
@@ -19,12 +23,16 @@
#include <machine/resource.h>
#include <dev/clk/clk.h>
+#include <dev/fdt/fdt_pinctrl.h>
#include <dev/gpio/gpiobusvar.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
+#include "fdt_pinctrl_if.h"
#include "gpio_if.h"
+#include <contrib/device-tree/src/riscv/starfive/jh7110-pinfunc.h>
+
#define PINCTRL_SYS 1
#define PINCTRL_AON 2
@@ -41,15 +49,23 @@
#define GPIOE_0 0x100
#define GPIOE_1 0x104
#define GPIOE_AON 0x20
+
+#define GP0_GPI_CFG 0x80
+#define AON_GPI_CFG 0x8
+
#define GPIO_DIN_LOW 0x118
#define GPIO_DIN_HIGH 0x11c
#define GPIO_DIN_AON 0x2c
+
#define IOMUX_SYSCFG_288 0x120
#define IOMUX_AONCFG_52 0x34
#define PAD_INPUT_EN (1 << 0)
-#define SHIFT_DRIVESTRENGTH 1
-#define PAD_DRIVESTRENGTH (0x3 << SHIFT_DRIVESTRENGTH)
+#define PAD_DRIVESTRENGTH_MASK (0x3 << 1)
+#define PAD_DRIVESTRENGTH_2 (0x0 << 1)
+#define PAD_DRIVESTRENGTH_4 (0x1 << 1)
+#define PAD_DRIVESTRENGTH_8 (0x2 << 1)
+#define PAD_DRIVESTRENGTH_12 (0x3 << 1)
#define PAD_PULLUP (1 << 3)
#define PAD_PULLDOWN (1 << 4)
#define PAD_SLEW (1 << 5)
@@ -69,10 +85,12 @@
clk_t clk;
int pinctrl; /* which pinctrl controller */
uint32_t maxpin; /* pins on this controller */
+ uint32_t maxinput; /* input sources */ /* input sources */
/* location of variable position fields for the two controllers */
uint32_t iomuxcfg;
uint32_t doutcfg;
uint32_t doencfg;
+ uint32_t gpicfg;
};
static struct ofw_compat_data compat_data[] = {
@@ -282,7 +300,7 @@
if ((flags & GPIO_PIN_INPUT) != 0) {
reg = RD4(sc, sc->iomuxcfg + PAD_OFFSET(pin));
reg |= (PAD_INPUT_EN | PAD_HYST);
- reg &= ~(PAD_DRIVESTRENGTH | PAD_SLEW);
+ reg &= ~(PAD_DRIVESTRENGTH_MASK | PAD_SLEW);
if ((flags & GPIO_PIN_PULLUP) != 0)
reg |= PAD_PULLUP;
else
@@ -402,6 +420,8 @@
sc->iomuxcfg = IOMUX_SYSCFG_288;
sc->doutcfg = GP0_DOUT_CFG;
sc->doencfg = GP0_DOEN_CFG;
+ sc->gpicfg = GP0_GPI_CFG;
+ sc->maxinput = GPI_SYS_SPI6_RXD;
} else {
WR4(sc, GPIOE_AON, 0);
WR4(sc, AON_GPIOEN, 1);
@@ -409,8 +429,16 @@
sc->iomuxcfg = IOMUX_AONCFG_52;
sc->doutcfg = AON_DOUT_CFG;
sc->doencfg = AON_DOEN_CFG;
+ sc->gpicfg = AON_GPI_CFG;
+ sc->maxinput = GPI_AON_PMU_GPIO_WAKEUP_3;
}
+ /*
+ * Register as a pinctrl device
+ */
+ fdt_pinctrl_register(dev, NULL);
+ fdt_pinctrl_configure_tree(dev);
+
sc->busdev = gpiobus_add_bus(dev);
if (sc->busdev == NULL) {
device_printf(dev, "Cannot attach gpiobus\n");
@@ -428,6 +456,141 @@
return (ofw_bus_get_node(bus));
}
+/* fdt_pinctrl configuration */
+
+static void
+jh7110_gpio_configure_pin(struct jh7110_gpio_softc *sc, uint32_t pinmux,
+ uint32_t padcfg)
+{
+ uint32_t dout, doen, reg;
+ u_int din, pin, func;
+
+ /*
+ * Split up the pinmux definition by field. See GPIOMUX and PINMUX
+ * macro definitions in the jh7110-pinfunc.h header.
+ */
+ pin = (pinmux >> 0) & 0xff;
+ func = (pinmux >> 8) & 0x03;
+ doen = (pinmux >> 10) & 0x3f;
+ dout = (pinmux >> 16) & 0xff;
+ din = (pinmux >> 24) & 0xff;
+
+ /* Not supported (yet?) */
+ if (pin > sc->maxpin)
+ return;
+
+ if (func != 0 && bootverbose) {
+ device_printf(sc->dev, "unexpected function field %u for pin "
+ "%u; ignoring\n", func, pin);
+ }
+
+ /* Set output configuration state for pin. */
+ reg = RD4(sc, sc->doutcfg + GPIO_RW_OFFSET(pin));
+ reg &= ~(DATA_OUT_MASK << GPIO_SHIFT(pin));
+ reg |= dout << GPIO_SHIFT(pin);
+ WR4(sc, sc->doutcfg + GPIO_RW_OFFSET(pin), reg);
+
+ /* Set output enable state for pin. */
+ reg = RD4(sc, sc->doencfg + GPIO_RW_OFFSET(pin));
+ reg &= ~(ENABLE_MASK << GPIO_SHIFT(pin));
+ reg |= doen << GPIO_SHIFT(pin);
+ WR4(sc, sc->doencfg + GPIO_RW_OFFSET(pin), reg);
+
+ if (din <= sc->maxinput) {
+ reg = RD4(sc, sc->gpicfg + GPIO_RW_OFFSET(din));
+ reg &= ~(0x7f << GPIO_SHIFT(din));
+ reg |= ((pin + 2) << GPIO_SHIFT(din));
+ WR4(sc, sc->gpicfg + GPIO_RW_OFFSET(din), reg);
+ }
+
+ /* Update PAD configuration for pin. */
+ WR4(sc, sc->iomuxcfg + PAD_OFFSET(pin), padcfg);
+}
+
+static uint32_t
+parse_padconfig(phandle_t node)
+{
+ uint32_t padcfg = 0;
+ u_int ds, slew;
+
+ /*
+ * See Bindings/pinctrl/starfive,jh7110-sys-pinctrl.yaml
+ */
+
+ if (OF_hasprop(node, "input-enable"))
+ padcfg |= PAD_INPUT_EN;
+
+ if (!OF_hasprop(node, "bias-disable")) {
+ if (OF_hasprop(node, "bias-pull-up")) {
+ padcfg |= PAD_PULLUP;
+ } else if (OF_hasprop(node, "bias-pull-down")) {
+ padcfg |= PAD_PULLDOWN;
+ }
+ }
+
+ if (OF_getencprop(node, "drive-strength", &ds, sizeof(ds)) != -1) {
+ switch (ds) {
+ case 12:
+ padcfg |= PAD_DRIVESTRENGTH_12;
+ break;
+ case 8:
+ padcfg |= PAD_DRIVESTRENGTH_8;
+ break;
+ case 4:
+ padcfg |= PAD_DRIVESTRENGTH_4;
+ break;
+ case 2:
+ default:
+ padcfg |= PAD_DRIVESTRENGTH_2;
+ break;
+ }
+ }
+
+ if (OF_getencprop(node, "slew-rate", &slew, sizeof(slew)) != -1 &&
+ slew == 1)
+ padcfg |= PAD_SLEW;
+
+ if (OF_hasprop(node, "input-schmitt-enable"))
+ padcfg |= PAD_HYST;
+
+ return (padcfg);
+}
+
+static int
+jh7110_gpio_configure_pins(device_t dev, phandle_t cfgxref)
+{
+ struct jh7110_gpio_softc *sc;
+ phandle_t node, child;
+ pcell_t *pinmux;
+ uint32_t padcfg;
+ int ncells;
+
+ sc = device_get_softc(dev);
+ node = OF_node_from_xref(cfgxref);
+
+ /* Process any and all children. */
+ for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+ /* Get pinmux */
+ ncells = OF_getencprop_alloc_multi(child, "pinmux",
+ sizeof(pcell_t), (void **)&pinmux);
+ if (ncells == -1)
+ continue;
+
+ /* Pad configuration for all pins described by this node. */
+ padcfg = parse_padconfig(child);
+
+ JH7110_GPIO_LOCK(sc);
+ for (int i = 0; i < ncells; i++) {
+ jh7110_gpio_configure_pin(sc, pinmux[i], padcfg);
+ }
+ JH7110_GPIO_UNLOCK(sc);
+
+ OF_prop_free(pinmux);
+ }
+
+ return (0);
+}
+
static device_method_t jh7110_gpio_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, jh7110_gpio_probe),
@@ -448,6 +611,9 @@
/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_node, jh7110_gpio_get_node),
+ /* fdt_pinctrl interface */
+ DEVMETHOD(fdt_pinctrl_configure, jh7110_gpio_configure_pins),
+
DEVMETHOD_END
};
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Sep 26, 12:59 PM (7 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39604014
Default Alt Text
D59992.diff (6 KB)
Attached To
Mode
D59992: jh7110_gpio: fdt_pinctrl interface
Attached
Detach File
Event Timeline
Log In to Comment