git: 719245455853 - main - aw_gpio: support Allwinner D1 GPIO
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 10 Dec 2024 21:31:17 UTC
The branch main has been updated by mhorne:
URL: https://cgit.FreeBSD.org/src/commit/?id=7192454558532101229629a8575d161013f3a7cb
commit 7192454558532101229629a8575d161013f3a7cb
Author: Julien Cassette <julien.cassette@gmail.com>
AuthorDate: 2024-12-10 21:22:40 +0000
Commit: Mitchell Horne <mhorne@FreeBSD.org>
CommitDate: 2024-12-10 21:30:13 +0000
aw_gpio: support Allwinner D1 GPIO
The GPIO controls the multiplexing of the D1 pins to its peripherals,
so this adds the definitions needed by the aw_gpio driver to support
the D1.
Also, this modifies the aw_gpio driver to support the differences of
the D1 controller:
- pins can have up to 15 functions
- each port is mapped with an alignment of 0x30
- CFG registers have 4 bits per pin
- DRV registers have 4 bits per pin
- the offset of PULL registers is 0x24
Signed-off-by: Julien Cassette <julien.cassette@gmail.com>
Reviewed by: mhorne
Differential Revision: https://reviews.freebsd.org/D35593
---
share/man/man4/man4.arm/aw_gpio.4 | 5 +-
sys/arm/allwinner/allwinner_pinctrl.h | 4 +-
sys/arm/allwinner/aw_gpio.c | 136 ++++++++++++++++++++++++++--------
sys/riscv/allwinner/d1_padconf.c | 129 ++++++++++++++++++++++++++++++++
sys/riscv/allwinner/files.allwinner | 3 +
sys/riscv/conf/GENERIC | 1 +
sys/riscv/conf/std.allwinner | 1 +
7 files changed, 247 insertions(+), 32 deletions(-)
diff --git a/share/man/man4/man4.arm/aw_gpio.4 b/share/man/man4/man4.arm/aw_gpio.4
index 3d72e82b3efc..5cbc7562d9bd 100644
--- a/share/man/man4/man4.arm/aw_gpio.4
+++ b/share/man/man4/man4.arm/aw_gpio.4
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd Dec 25, 2017
+.Dd October 8, 2024
.Dt AW_GPIO 4
.Os
.Sh NAME
@@ -41,6 +41,7 @@
.Cd "options SOC_ALLWINNER_H3"
.Cd "options SOC_ALLWINNER_A64"
.Cd "options SOC_ALLWINNER_H5"
+.Cd "options SOC_ALLWINNER_D1"
.Sh DESCRIPTION
The
.Nm
@@ -81,6 +82,8 @@ allwinner,sun8i-h3-r-pinctrl
allwinner,sun50i-a64-pinctrl
.It
allwinner,sun50i-a64-r-pinctrl
+.It
+allwinner,sun20i-d1-pinctrl
.El
.Sh SEE ALSO
.Xr fdt 4 ,
diff --git a/sys/arm/allwinner/allwinner_pinctrl.h b/sys/arm/allwinner/allwinner_pinctrl.h
index 4eaa2d84146c..67fd13683a46 100644
--- a/sys/arm/allwinner/allwinner_pinctrl.h
+++ b/sys/arm/allwinner/allwinner_pinctrl.h
@@ -26,13 +26,13 @@
#ifndef _ALLWINNER_PINCTRL_H_
#define _ALLWINNER_PINCTRL_H_
-#define AW_MAX_FUNC_BY_PIN 8
+#define AW_MAX_FUNC_BY_PIN 15
struct allwinner_pins {
const char *name;
uint8_t port;
uint8_t pin;
- const char *functions[8];
+ const char *functions[AW_MAX_FUNC_BY_PIN];
uint8_t eint_func;
uint8_t eint_num;
uint8_t eint_bank;
diff --git a/sys/arm/allwinner/aw_gpio.c b/sys/arm/allwinner/aw_gpio.c
index 6ff0516acb3f..b469a7fb453d 100644
--- a/sys/arm/allwinner/aw_gpio.c
+++ b/sys/arm/allwinner/aw_gpio.c
@@ -4,6 +4,7 @@
* Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@freebsd.org>
* Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
* Copyright (c) 2012 Luiz Otavio O Souza.
+ * Copyright (c) 2022 Julien Cassette <julien.cassette@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -56,7 +57,7 @@
#include <dev/hwreset/hwreset.h>
#include <dev/regulator/regulator.h>
-#if defined(__aarch64__)
+#if defined(__aarch64__) || defined(__riscv)
#include "opt_soc.h"
#endif
@@ -82,9 +83,18 @@
#define AW_PINCTRL 1
#define AW_R_PINCTRL 2
+#if defined(__arm__) || defined(__aarch64__)
+#define IRQ_MEMORY_BARRIER(x) arm_irq_memory_barrier(x)
+#else
+#define IRQ_MEMORY_BARRIER(x) fence()
+#endif
+
struct aw_gpio_conf {
struct allwinner_padconf *padconf;
const char *banks;
+ uint32_t bank_size;
+ uint32_t drv_pin_shift;
+ uint32_t pul_offset;
};
/* Defined in aw_padconf.c */
@@ -93,6 +103,9 @@ extern struct allwinner_padconf a10_padconf;
struct aw_gpio_conf a10_gpio_conf = {
.padconf = &a10_padconf,
.banks = "abcdefghi",
+ .bank_size = 0x24,
+ .drv_pin_shift = 1,
+ .pul_offset = 0x1C,
};
#endif
@@ -102,6 +115,9 @@ extern struct allwinner_padconf a13_padconf;
struct aw_gpio_conf a13_gpio_conf = {
.padconf = &a13_padconf,
.banks = "bcdefg",
+ .bank_size = 0x24,
+ .drv_pin_shift = 1,
+ .pul_offset = 0x1C,
};
#endif
@@ -111,6 +127,9 @@ extern struct allwinner_padconf a20_padconf;
struct aw_gpio_conf a20_gpio_conf = {
.padconf = &a20_padconf,
.banks = "abcdefghi",
+ .bank_size = 0x24,
+ .drv_pin_shift = 1,
+ .pul_offset = 0x1C,
};
#endif
@@ -120,6 +139,9 @@ extern struct allwinner_padconf a31_padconf;
struct aw_gpio_conf a31_gpio_conf = {
.padconf = &a31_padconf,
.banks = "abcdefgh",
+ .bank_size = 0x24,
+ .drv_pin_shift = 1,
+ .pul_offset = 0x1C,
};
#endif
@@ -129,6 +151,9 @@ extern struct allwinner_padconf a31s_padconf;
struct aw_gpio_conf a31s_gpio_conf = {
.padconf = &a31s_padconf,
.banks = "abcdefgh",
+ .bank_size = 0x24,
+ .drv_pin_shift = 1,
+ .pul_offset = 0x1C,
};
#endif
@@ -137,6 +162,9 @@ extern struct allwinner_padconf a31_r_padconf;
struct aw_gpio_conf a31_r_gpio_conf = {
.padconf = &a31_r_padconf,
.banks = "lm",
+ .bank_size = 0x24,
+ .drv_pin_shift = 1,
+ .pul_offset = 0x1C,
};
#endif
@@ -146,6 +174,9 @@ extern struct allwinner_padconf a33_padconf;
struct aw_gpio_conf a33_gpio_conf = {
.padconf = &a33_padconf,
.banks = "bcdefgh",
+ .bank_size = 0x24,
+ .drv_pin_shift = 1,
+ .pul_offset = 0x1C,
};
#endif
@@ -156,10 +187,16 @@ extern struct allwinner_padconf h3_r_padconf;
struct aw_gpio_conf h3_gpio_conf = {
.padconf = &h3_padconf,
.banks = "acdefg",
+ .bank_size = 0x24,
+ .drv_pin_shift = 1,
+ .pul_offset = 0x1C,
};
struct aw_gpio_conf h3_r_gpio_conf = {
.padconf = &h3_r_padconf,
.banks = "l",
+ .bank_size = 0x24,
+ .drv_pin_shift = 1,
+ .pul_offset = 0x1C,
};
#endif
@@ -170,10 +207,16 @@ extern struct allwinner_padconf a83t_r_padconf;
struct aw_gpio_conf a83t_gpio_conf = {
.padconf = &a83t_padconf,
.banks = "bcdefgh"
+ .bank_size = 0x24,
+ .drv_pin_shift = 1,
+ .pul_offset = 0x1C,
};
struct aw_gpio_conf a83t_r_gpio_conf = {
.padconf = &a83t_r_padconf,
.banks = "l",
+ .bank_size = 0x24,
+ .drv_pin_shift = 1,
+ .pul_offset = 0x1C,
};
#endif
@@ -184,10 +227,28 @@ extern struct allwinner_padconf a64_r_padconf;
struct aw_gpio_conf a64_gpio_conf = {
.padconf = &a64_padconf,
.banks = "bcdefgh",
+ .bank_size = 0x24,
+ .drv_pin_shift = 1,
+ .pul_offset = 0x1C,
};
struct aw_gpio_conf a64_r_gpio_conf = {
.padconf = &a64_r_padconf,
.banks = "l",
+ .bank_size = 0x24,
+ .drv_pin_shift = 1,
+ .pul_offset = 0x1C,
+};
+#endif
+
+/* Defined in d1_padconf.c */
+#ifdef SOC_ALLWINNER_D1
+extern struct allwinner_padconf d1_padconf;
+struct aw_gpio_conf d1_gpio_conf = {
+ .padconf = &d1_padconf,
+ .banks = "bcdefg",
+ .bank_size = 0x30,
+ .drv_pin_shift = 2,
+ .pul_offset = 0x24,
};
#endif
@@ -198,10 +259,16 @@ extern struct allwinner_padconf h6_r_padconf;
struct aw_gpio_conf h6_gpio_conf = {
.padconf = &h6_padconf,
.banks = "cdfgh",
+ .bank_size = 0x24,
+ .drv_pin_shift = 1,
+ .pul_offset = 0x1C,
};
struct aw_gpio_conf h6_r_gpio_conf = {
.padconf = &h6_r_padconf,
.banks = "lm",
+ .bank_size = 0x24,
+ .drv_pin_shift = 1,
+ .pul_offset = 0x1C,
};
#endif
@@ -240,6 +307,9 @@ static struct ofw_compat_data compat_data[] = {
{"allwinner,sun50i-a64-pinctrl", (uintptr_t)&a64_gpio_conf},
{"allwinner,sun50i-a64-r-pinctrl", (uintptr_t)&a64_r_gpio_conf},
#endif
+#ifdef SOC_ALLWINNER_D1
+ {"allwinner,sun20i-d1-pinctrl", (uintptr_t)&d1_gpio_conf},
+#endif
#ifdef SOC_ALLWINNER_H6
{"allwinner,sun50i-h6-pinctrl", (uintptr_t)&h6_gpio_conf},
{"allwinner,sun50i-h6-r-pinctrl", (uintptr_t)&h6_r_gpio_conf},
@@ -293,10 +363,16 @@ static struct resource_spec aw_gpio_res_spec[] = {
#define AW_GPIO_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->sc_mtx)
#define AW_GPIO_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
-#define AW_GPIO_GP_CFG(_bank, _idx) 0x00 + ((_bank) * 0x24) + ((_idx) << 2)
-#define AW_GPIO_GP_DAT(_bank) 0x10 + ((_bank) * 0x24)
-#define AW_GPIO_GP_DRV(_bank, _idx) 0x14 + ((_bank) * 0x24) + ((_idx) << 2)
-#define AW_GPIO_GP_PUL(_bank, _idx) 0x1c + ((_bank) * 0x24) + ((_idx) << 2)
+#define AW_GPIO_GP_BASE(_sc, _bank) ((_sc)->conf->bank_size * (_bank))
+
+#define AW_GPIO_GP_CFG(_sc, _bank, _idx) \
+ (AW_GPIO_GP_BASE(_sc, _bank) + 0x00 + ((_idx) << 2))
+#define AW_GPIO_GP_DAT(_sc, _bank) \
+ (AW_GPIO_GP_BASE(_sc, _bank) + 0x10)
+#define AW_GPIO_GP_DRV(_sc, _bank, _idx) \
+ (AW_GPIO_GP_BASE(_sc, _bank) + 0x14 + ((_idx) << 2))
+#define AW_GPIO_GP_PUL(_sc, _bank, _idx) \
+ (AW_GPIO_GP_BASE(_sc, _bank) + (_sc)->conf->pul_offset + ((_idx) << 2))
#define AW_GPIO_GP_INT_BASE(_bank) (0x200 + 0x20 * _bank)
@@ -346,9 +422,9 @@ aw_gpio_get_function(struct aw_gpio_softc *sc, uint32_t pin)
pin = sc->conf->padconf->pins[pin].pin;
offset = ((pin & 0x07) << 2);
- func = AW_GPIO_READ(sc, AW_GPIO_GP_CFG(bank, pin >> 3));
+ func = AW_GPIO_READ(sc, AW_GPIO_GP_CFG(sc, bank, pin >> 3));
- return ((func >> offset) & 0x7);
+ return ((func >> offset) & 0xF);
}
static int
@@ -367,10 +443,10 @@ aw_gpio_set_function(struct aw_gpio_softc *sc, uint32_t pin, uint32_t f)
pin = sc->conf->padconf->pins[pin].pin;
offset = ((pin & 0x07) << 2);
- data = AW_GPIO_READ(sc, AW_GPIO_GP_CFG(bank, pin >> 3));
- data &= ~(7 << offset);
+ data = AW_GPIO_READ(sc, AW_GPIO_GP_CFG(sc, bank, pin >> 3));
+ data &= ~(0xF << offset);
data |= (f << offset);
- AW_GPIO_WRITE(sc, AW_GPIO_GP_CFG(bank, pin >> 3), data);
+ AW_GPIO_WRITE(sc, AW_GPIO_GP_CFG(sc, bank, pin >> 3), data);
return (0);
}
@@ -387,7 +463,7 @@ aw_gpio_get_pud(struct aw_gpio_softc *sc, uint32_t pin)
pin = sc->conf->padconf->pins[pin].pin;
offset = ((pin & 0x0f) << 1);
- val = AW_GPIO_READ(sc, AW_GPIO_GP_PUL(bank, pin >> 4));
+ val = AW_GPIO_READ(sc, AW_GPIO_GP_PUL(sc, bank, pin >> 4));
return ((val >> offset) & AW_GPIO_PUD_MASK);
}
@@ -407,25 +483,26 @@ aw_gpio_set_pud(struct aw_gpio_softc *sc, uint32_t pin, uint32_t state)
pin = sc->conf->padconf->pins[pin].pin;
offset = ((pin & 0x0f) << 1);
- val = AW_GPIO_READ(sc, AW_GPIO_GP_PUL(bank, pin >> 4));
+ val = AW_GPIO_READ(sc, AW_GPIO_GP_PUL(sc, bank, pin >> 4));
val &= ~(AW_GPIO_PUD_MASK << offset);
val |= (state << offset);
- AW_GPIO_WRITE(sc, AW_GPIO_GP_PUL(bank, pin >> 4), val);
+ AW_GPIO_WRITE(sc, AW_GPIO_GP_PUL(sc, bank, pin >> 4), val);
}
static uint32_t
aw_gpio_get_drv(struct aw_gpio_softc *sc, uint32_t pin)
{
- uint32_t bank, offset, val;
+ uint32_t bank, idx, offset, val;
/* Must be called with lock held. */
AW_GPIO_LOCK_ASSERT(sc);
bank = sc->conf->padconf->pins[pin].port;
pin = sc->conf->padconf->pins[pin].pin;
- offset = ((pin & 0x0f) << 1);
+ offset = (pin << sc->conf->drv_pin_shift) & 0x1F;
+ idx = (pin << sc->conf->drv_pin_shift) >> 5;
- val = AW_GPIO_READ(sc, AW_GPIO_GP_DRV(bank, pin >> 4));
+ val = AW_GPIO_READ(sc, AW_GPIO_GP_DRV(sc, bank, idx));
return ((val >> offset) & AW_GPIO_DRV_MASK);
}
@@ -433,7 +510,7 @@ aw_gpio_get_drv(struct aw_gpio_softc *sc, uint32_t pin)
static void
aw_gpio_set_drv(struct aw_gpio_softc *sc, uint32_t pin, uint32_t drive)
{
- uint32_t bank, offset, val;
+ uint32_t bank, idx, offset, val;
if (aw_gpio_get_drv(sc, pin) == drive)
return;
@@ -443,12 +520,13 @@ aw_gpio_set_drv(struct aw_gpio_softc *sc, uint32_t pin, uint32_t drive)
bank = sc->conf->padconf->pins[pin].port;
pin = sc->conf->padconf->pins[pin].pin;
- offset = ((pin & 0x0f) << 1);
+ offset = (pin << sc->conf->drv_pin_shift) & 0x1F;
+ idx = (pin << sc->conf->drv_pin_shift) >> 5;
- val = AW_GPIO_READ(sc, AW_GPIO_GP_DRV(bank, pin >> 4));
+ val = AW_GPIO_READ(sc, AW_GPIO_GP_DRV(sc, bank, idx));
val &= ~(AW_GPIO_DRV_MASK << offset);
val |= (drive << offset);
- AW_GPIO_WRITE(sc, AW_GPIO_GP_DRV(bank, pin >> 4), val);
+ AW_GPIO_WRITE(sc, AW_GPIO_GP_DRV(sc, bank, idx), val);
}
static int
@@ -624,12 +702,12 @@ aw_gpio_pin_set_locked(struct aw_gpio_softc *sc, uint32_t pin,
bank = sc->conf->padconf->pins[pin].port;
pin = sc->conf->padconf->pins[pin].pin;
- data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
+ data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(sc, bank));
if (value)
data |= (1 << pin);
else
data &= ~(1 << pin);
- AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(bank), data);
+ AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(sc, bank), data);
return (0);
}
@@ -672,7 +750,7 @@ aw_gpio_pin_get_locked(struct aw_gpio_softc *sc,uint32_t pin,
bank = sc->conf->padconf->pins[pin].port;
pin = sc->conf->padconf->pins[pin].pin;
- reg_data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
+ reg_data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(sc, bank));
*val = (reg_data & (1 << pin)) ? 1 : 0;
if (func == sc->conf->padconf->pins[pin].eint_func)
@@ -779,12 +857,12 @@ aw_gpio_pin_toggle(device_t dev, uint32_t pin)
pin = sc->conf->padconf->pins[pin].pin;
AW_GPIO_LOCK(sc);
- data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
+ data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(sc, bank));
if (data & (1 << pin))
data &= ~(1 << pin);
else
data |= (1 << pin);
- AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(bank), data);
+ AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(sc, bank), data);
AW_GPIO_UNLOCK(sc);
return (0);
@@ -813,9 +891,9 @@ aw_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins,
return (EINVAL);
AW_GPIO_LOCK(sc);
- data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
+ data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(sc, bank));
if ((clear_pins | change_pins) != 0)
- AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(bank),
+ AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(sc, bank),
(data & ~clear_pins) ^ change_pins);
AW_GPIO_UNLOCK(sc);
@@ -1408,7 +1486,7 @@ aw_gpio_pic_post_filter(device_t dev, struct intr_irqsrc *isrc)
sc = device_get_softc(dev);
gi = (struct gpio_irqsrc *)isrc;
- arm_irq_memory_barrier(0);
+ IRQ_MEMORY_BARRIER(0);
AW_GPIO_WRITE(sc, AW_GPIO_GP_INT_STA(gi->bank), 1 << gi->intnum);
}
@@ -1421,7 +1499,7 @@ aw_gpio_pic_post_ithread(device_t dev, struct intr_irqsrc *isrc)
sc = device_get_softc(dev);
gi = (struct gpio_irqsrc *)isrc;
- arm_irq_memory_barrier(0);
+ IRQ_MEMORY_BARRIER(0);
AW_GPIO_WRITE(sc, AW_GPIO_GP_INT_STA(gi->bank), 1 << gi->intnum);
aw_gpio_pic_enable_intr(dev, isrc);
}
diff --git a/sys/riscv/allwinner/d1_padconf.c b/sys/riscv/allwinner/d1_padconf.c
new file mode 100644
index 000000000000..7a429d216051
--- /dev/null
+++ b/sys/riscv/allwinner/d1_padconf.c
@@ -0,0 +1,129 @@
+/*-
+ * Copyright (c) 2022 Julien Cassette <julien.cassette@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/types.h>
+
+#include <arm/allwinner/allwinner_pinctrl.h>
+
+#include "opt_soc.h"
+
+static const struct allwinner_pins d1_pins[] = {
+ { "PB0", 1, 0, { "gpio_in", "gpio_out", "pwm3", "ir", "i2c2", "spi1", "uart0", "uart2", "spdif", [14] = "pb_eint0" }, 14, 0, 1 },
+ { "PB1", 1, 1, { "gpio_in", "gpio_out", "pwm4", "i2s2", "i2c2", "i2s2", "uart0", "uart2", "ir", [14] = "pb_eint1" }, 14, 1, 1 },
+ { "PB2", 1, 2, { "gpio_in", "gpio_out", "lcd0", "i2s2", "i2c0", "i2s2", "lcd0", "uart4", NULL, [14] = "pb_eint2" }, 14, 2, 1 },
+ { "PB3", 1, 3, { "gpio_in", "gpio_out", "lcd0", "i2s2", "i2c0", "i2s2", "lcd0", "uart4", NULL, [14] = "pb_eint3" }, 14, 3, 1 },
+ { "PB4", 1, 4, { "gpio_in", "gpio_out", "lcd0", "i2s2", "i2c1", "i2s2", "lcd0", "uart5", NULL, [14] = "pb_eint4" }, 14, 4, 1 },
+ { "PB5", 1, 5, { "gpio_in", "gpio_out", "lcd0", "i2s2", "i2c1", "pwm0", "lcd0", "uart5", NULL, [14] = "pb_eint5" }, 14, 5, 1 },
+ { "PB6", 1, 6, { "gpio_in", "gpio_out", "lcd0", "i2s2", "i2c3", "pwm1", "lcd0", "uart3", "cpu", [14] = "pb_eint6" }, 14, 6, 1 },
+ { "PB7", 1, 7, { "gpio_in", "gpio_out", "lcd0", "i2s2", "i2c3", "ir", "lcd0", "uart3", "cpu", [14] = "pb_eint7" }, 14, 7, 1 },
+ { "PB8", 1, 8, { "gpio_in", "gpio_out", "dmic", "pwm5", "i2c2", "spi1", "uart0", "uart1", NULL, [14] = "pb_eint8" }, 14, 8, 1 },
+ { "PB9", 1, 9, { "gpio_in", "gpio_out", "dmic", "pwm6", "i2c2", "spi1", "uart0", "uart1", NULL, [14] = "pb_eint9" }, 14, 9, 1 },
+ { "PB10", 1, 10, { "gpio_in", "gpio_out", "dmic", "pwm7", "i2c0", "spi1", "clk", "uart1", NULL, [14] = "pb_eint10" }, 14, 10, 1 },
+ { "PB11", 1, 11, { "gpio_in", "gpio_out", "dmic", "pwm2", "i2c0", "spi1", "clk", "uart1", NULL, [14] = "pb_eint11" }, 14, 11, 1 },
+ { "PB12", 1, 12, { "gpio_in", "gpio_out", "dmic", "pwm0", "spdif", "spi1", "clk", "ir", NULL, [14] = "pb_eint12" }, 14, 12, 1 },
+ { "PC0", 2, 0, { "gpio_in", "gpio_out", "uart2", "i2c2", "ledc", NULL, NULL, NULL, NULL, [14] = "pc_eint0" }, 14, 0, 2 },
+ { "PC1", 2, 1, { "gpio_in", "gpio_out", "uart2", "i2c2", NULL, NULL, NULL, NULL, NULL, [14] = "pc_eint1" }, 14, 1, 2 },
+ { "PC2", 2, 2, { "gpio_in", "gpio_out", "spi0", "mmc2", NULL, NULL, NULL, NULL, NULL, [14] = "pc_eint2" }, 14, 2, 2 },
+ { "PC3", 2, 3, { "gpio_in", "gpio_out", "spi0", "mmc2", NULL, NULL, NULL, NULL, NULL, [14] = "pc_eint3" }, 14, 3, 2 },
+ { "PC4", 2, 4, { "gpio_in", "gpio_out", "spi0", "mmc2", "boot", NULL, NULL, NULL, NULL, [14] = "pc_eint4" }, 14, 4, 2 },
+ { "PC5", 2, 5, { "gpio_in", "gpio_out", "spi0", "mmc2", "boot", NULL, NULL, NULL, NULL, [14] = "pc_eint5" }, 14, 5, 2 },
+ { "PC6", 2, 6, { "gpio_in", "gpio_out", "spi0", "mmc2", "uart3", "i2c3", "dbg", NULL, NULL, [14] = "pc_eint6" }, 14, 6, 2 },
+ { "PC7", 2, 7, { "gpio_in", "gpio_out", "spi0", "mmc2", "uart3", "i2c3", "tcon", NULL, NULL, [14] = "pc_eint7" }, 14, 7, 2 },
+ { "PD0", 3, 0, { "gpio_in", "gpio_out", "lcd0", "lvds0", "dsi", "i2c0", NULL, NULL, NULL, [14] = "pd_eint0" }, 14, 0, 3 },
+ { "PD1", 3, 1, { "gpio_in", "gpio_out", "lcd0", "lvds0", "dsi", "uart2", NULL, NULL, NULL, [14] = "pd_eint1" }, 14, 1, 3 },
+ { "PD2", 3, 2, { "gpio_in", "gpio_out", "lcd0", "lvds0", "dsi", "uart2", NULL, NULL, NULL, [14] = "pd_eint2" }, 14, 2, 3 },
+ { "PD3", 3, 3, { "gpio_in", "gpio_out", "lcd0", "lvds0", "dsi", "uart2", NULL, NULL, NULL, [14] = "pd_eint3" }, 14, 3, 3 },
+ { "PD4", 3, 4, { "gpio_in", "gpio_out", "lcd0", "lvds0", "dsi", "uart2", NULL, NULL, NULL, [14] = "pd_eint4" }, 14, 4, 3 },
+ { "PD5", 3, 5, { "gpio_in", "gpio_out", "lcd0", "lvds0", "dsi", "uart5", NULL, NULL, NULL, [14] = "pd_eint5" }, 14, 5, 3 },
+ { "PD6", 3, 6, { "gpio_in", "gpio_out", "lcd0", "lvds0", "dsi", "uart5", NULL, NULL, NULL, [14] = "pd_eint6" }, 14, 6, 3 },
+ { "PD7", 3, 7, { "gpio_in", "gpio_out", "lcd0", "lvds0", "dsi", "uart4", NULL, NULL, NULL, [14] = "pd_eint7" }, 14, 7, 3 },
+ { "PD8", 3, 8, { "gpio_in", "gpio_out", "lcd0", "lvds0", "dsi", "uart4", NULL, NULL, NULL, [14] = "pd_eint8" }, 14, 8, 3 },
+ { "PD9", 3, 9, { "gpio_in", "gpio_out", "lcd0", "lvds0", "dsi", "pwm6", NULL, NULL, NULL, [14] = "pd_eint9" }, 14, 9, 3 },
+ { "PD10", 3, 10, { "gpio_in", "gpio_out", "lcd0", "lvds1", "spi1", "uart3", NULL, NULL, NULL, [14] = "pd_eint10" }, 14, 10, 3 },
+ { "PD11", 3, 11, { "gpio_in", "gpio_out", "lcd0", "lvds1", "spi1", "uart3", NULL, NULL, NULL, [14] = "pd_eint11" }, 14, 11, 3 },
+ { "PD12", 3, 12, { "gpio_in", "gpio_out", "lcd0", "lvds1", "spi1", "i2c0", NULL, NULL, NULL, [14] = "pd_eint12" }, 14, 12, 3 },
+ { "PD13", 3, 13, { "gpio_in", "gpio_out", "lcd0", "lvds1", "spi1", "uart3", NULL, NULL, NULL, [14] = "pd_eint13" }, 14, 13, 3 },
+ { "PD14", 3, 14, { "gpio_in", "gpio_out", "lcd0", "lvds1", "spi1", "uart3", NULL, NULL, NULL, [14] = "pd_eint14" }, 14, 14, 3 },
+ { "PD15", 3, 15, { "gpio_in", "gpio_out", "lcd0", "lvds1", "spi1", "ir", NULL, NULL, NULL, [14] = "pd_eint15" }, 14, 15, 3 },
+ { "PD16", 3, 16, { "gpio_in", "gpio_out", "lcd0", "lvds1", "dmic", "pwm0", NULL, NULL, NULL, [14] = "pd_eint16" }, 14, 16, 3 },
+ { "PD17", 3, 17, { "gpio_in", "gpio_out", "lcd0", "lvds1", "dmic", "pwm1", NULL, NULL, NULL, [14] = "pd_eint17" }, 14, 17, 3 },
+ { "PD18", 3, 18, { "gpio_in", "gpio_out", "lcd0", "lvds1", "dmic", "pwm2", NULL, NULL, NULL, [14] = "pd_eint18" }, 14, 18, 3 },
+ { "PD19", 3, 19, { "gpio_in", "gpio_out", "lcd0", "lvds1", "dmic", "pwm3", NULL, NULL, NULL, [14] = "pd_eint19" }, 14, 19, 3 },
+ { "PD20", 3, 20, { "gpio_in", "gpio_out", "lcd0", "i2c2", "dmic", "pwm4", NULL, NULL, NULL, [14] = "pd_eint20" }, 14, 20, 3 },
+ { "PD21", 3, 21, { "gpio_in", "gpio_out", "lcd0", "i2c2", "uart1", "pwm5", NULL, NULL, NULL, [14] = "pd_eint21" }, 14, 21, 3 },
+ { "PD22", 3, 22, { "gpio_in", "gpio_out", "spdif", "ir", "uart1", "pwm7", NULL, NULL, NULL, [14] = "pd_eint22" }, 14, 22, 3 },
+ { "PE0", 4, 0, { "gpio_in", "gpio_out", "ncsi0", "uart2", "i2c1", "lcd0", NULL, NULL, "emac", [14] = "pe_eint0" }, 14, 0, 4 },
+ { "PE1", 4, 1, { "gpio_in", "gpio_out", "ncsi0", "uart2", "i2c1", "lcd0", NULL, NULL, "emac", [14] = "pe_eint1" }, 14, 1, 4 },
+ { "PE2", 4, 2, { "gpio_in", "gpio_out", "ncsi0", "uart2", "i2c0", "clk", "uart0", NULL, "emac", [14] = "pe_eint2" }, 14, 2, 4 },
+ { "PE3", 4, 3, { "gpio_in", "gpio_out", "ncsi0", "uart2", "i2c0", "clk", "uart0", NULL, "emac", [14] = "pe_eint3" }, 14, 3, 4 },
+ { "PE4", 4, 4, { "gpio_in", "gpio_out", "ncsi0", "uart4", "i2c2", "clk", "jtag", "jtag", "emac", [14] = "pe_eint4" }, 14, 4, 4 },
+ { "PE5", 4, 5, { "gpio_in", "gpio_out", "ncsi0", "uart4", "i2c2", "ledc", "jtag", "jtag", "emac", [14] = "pe_eint5" }, 14, 5, 4 },
+ { "PE6", 4, 6, { "gpio_in", "gpio_out", "ncsi0", "uart5", "i2c3", "spdif", "jtag", "jtag", "emac", [14] = "pe_eint6" }, 14, 6, 4 },
+ { "PE7", 4, 7, { "gpio_in", "gpio_out", "ncsi0", "uart5", "i2c3", "spdif", "jtag", "jtag", "emac", [14] = "pe_eint7" }, 14, 7, 4 },
+ { "PE8", 4, 8, { "gpio_in", "gpio_out", "ncsi0", "uart1", "pwm2", "uart3", "jtag", NULL, "emac", [14] = "pe_eint8" }, 14, 8, 4 },
+ { "PE9", 4, 9, { "gpio_in", "gpio_out", "ncsi0", "uart1", "pwm3", "uart3", "jtag", NULL, "emac", [14] = "pe_eint9" }, 14, 9, 4 },
+ { "PE10", 4, 10, { "gpio_in", "gpio_out", "ncsi0", "uart1", "pwm4", "ir", "jtag", NULL, "emac", [14] = "pe_eint10" }, 14, 10, 4 },
+ { "PE11", 4, 11, { "gpio_in", "gpio_out", "ncsi0", "uart1", "i2s0", "i2s0", "jtag", NULL, "emac", [14] = "pe_eint11" }, 14, 11, 4 },
+ { "PE12", 4, 12, { "gpio_in", "gpio_out", "i2c2", "ncsi0", "i2s0", "i2s0", NULL, NULL, "emac", [14] = "pe_eint12" }, 14, 12, 4 },
+ { "PE13", 4, 13, { "gpio_in", "gpio_out", "i2c2", "pwm5", "i2s0", "i2s0", "dmic", NULL, "emac", [14] = "pe_eint13" }, 14, 13, 4 },
+ { "PE14", 4, 14, { "gpio_in", "gpio_out", "i2c1", "jtag", "i2s0", "i2s0", "dmic", NULL, "emac", [14] = "pe_eint14" }, 14, 14, 4 },
+ { "PE15", 4, 15, { "gpio_in", "gpio_out", "i2c1", "jtag", "pwm6", "i2s0", "dmic", NULL, "emac", [14] = "pe_eint15" }, 14, 15, 4 },
+ { "PE16", 4, 16, { "gpio_in", "gpio_out", "i2c3", "jtag", "pwm7", "i2s0", "dmic", NULL, NULL, [14] = "pe_eint16" }, 14, 16, 4 },
+ { "PE17", 4, 17, { "gpio_in", "gpio_out", "i2c3", "jtag", "ir", "i2s0", "dmic", NULL, NULL, [14] = "pe_eint17" }, 14, 17, 4 },
+ { "PF0", 5, 0, { "gpio_in", "gpio_out", "mmc0", NULL, "jtag", "i2s2", "i2s2", NULL, NULL, [14] = "pf_eint0" }, 14, 0, 5 },
+ { "PF1", 5, 1, { "gpio_in", "gpio_out", "mmc0", NULL, "jtag", "i2s2", "i2s2", NULL, NULL, [14] = "pf_eint1" }, 14, 1, 5 },
+ { "PF2", 5, 2, { "gpio_in", "gpio_out", "mmc0", "uart0", "i2c0", "ledc", "spdif", NULL, NULL, [14] = "pf_eint2" }, 14, 2, 5 },
+ { "PF3", 5, 3, { "gpio_in", "gpio_out", "mmc0", NULL, "jtag", "i2s2", NULL, NULL, NULL, [14] = "pf_eint3" }, 14, 3, 5 },
+ { "PF4", 5, 4, { "gpio_in", "gpio_out", "mmc0", "uart0", "i2c0", "pwm6", "ir", NULL, NULL, [14] = "pf_eint4" }, 14, 4, 5 },
+ { "PF5", 5, 5, { "gpio_in", "gpio_out", "mmc0", NULL, "jtag", "i2s2", NULL, NULL, NULL, [14] = "pf_eint5" }, 14, 5, 5 },
+ { "PF6", 5, 6, { "gpio_in", "gpio_out", NULL, "spdif", "ir", "i2s2", "pwm5", NULL, NULL, [14] = "pf_eint6" }, 14, 6, 5 },
+ { "PG0", 6, 0, { "gpio_in", "gpio_out", "mmc1", "uart3", "emac", "pwm7", NULL, NULL, NULL, [14] = "pg_eint0" }, 14, 0, 6 },
+ { "PG1", 6, 1, { "gpio_in", "gpio_out", "mmc1", "uart3", "emac", "pwm6", NULL, NULL, NULL, [14] = "pg_eint1" }, 14, 1, 6 },
+ { "PG2", 6, 2, { "gpio_in", "gpio_out", "mmc1", "uart3", "emac", "uart4", NULL, NULL, NULL, [14] = "pg_eint2" }, 14, 2, 6 },
+ { "PG3", 6, 3, { "gpio_in", "gpio_out", "mmc1", "uart3", "emac", "uart4", NULL, NULL, NULL, [14] = "pg_eint3" }, 14, 3, 6 },
+ { "PG4", 6, 4, { "gpio_in", "gpio_out", "mmc1", "uart5", "emac", "pwm5", NULL, NULL, NULL, [14] = "pg_eint4" }, 14, 4, 6 },
+ { "PG5", 6, 5, { "gpio_in", "gpio_out", "mmc1", "uart5", "emac", "pwm4", NULL, NULL, NULL, [14] = "pg_eint5" }, 14, 5, 6 },
+ { "PG6", 6, 6, { "gpio_in", "gpio_out", "uart1", "i2c2", "emac", "pwm1", NULL, NULL, NULL, [14] = "pg_eint6" }, 14, 6, 6 },
+ { "PG7", 6, 7, { "gpio_in", "gpio_out", "uart1", "i2c2", "emac", "spdif", NULL, NULL, NULL, [14] = "pg_eint7" }, 14, 7, 6 },
+ { "PG8", 6, 8, { "gpio_in", "gpio_out", "uart1", "i2c1", "emac", "uart3", NULL, NULL, NULL, [14] = "pg_eint8" }, 14, 8, 6 },
+ { "PG9", 6, 9, { "gpio_in", "gpio_out", "uart1", "i2c1", "emac", "uart3", NULL, NULL, NULL, [14] = "pg_eint9" }, 14, 9, 6 },
+ { "PG10", 6, 10, { "gpio_in", "gpio_out", "pwm3", "i2c3", "emac", "clk", "ir", NULL, NULL, [14] = "pg_eint10" }, 14, 10, 6 },
+ { "PG11", 6, 11, { "gpio_in", "gpio_out", "i2s1", "i2c3", "emac", "clk", "tcon", NULL, NULL, [14] = "pg_eint11" }, 14, 11, 6 },
+ { "PG12", 6, 12, { "gpio_in", "gpio_out", "i2s1", "i2c0", "emac", "clk", "pwm0", "uart1", NULL, [14] = "pg_eint12" }, 14, 12, 6 },
+ { "PG13", 6, 13, { "gpio_in", "gpio_out", "i2s1", "i2c0", "emac", "pwm2", "ledc", "uart1", NULL, [14] = "pg_eint13" }, 14, 13, 6 },
+ { "PG14", 6, 14, { "gpio_in", "gpio_out", "i2s1", "i2c2", "emac", "i2s1", "spi0", "uart1", NULL, [14] = "pg_eint14" }, 14, 14, 6 },
+ { "PG15", 6, 15, { "gpio_in", "gpio_out", "i2s1", "i2c2", "emac", "i2s1", "spi0", "uart1", NULL, [14] = "pg_eint15" }, 14, 15, 6 },
+ { "PG16", 6, 16, { "gpio_in", "gpio_out", "ir", "tcon", "pwm5", "clk", "spdif", "ledc", NULL, [14] = "pg_eint16" }, 14, 16, 6 },
+ { "PG17", 6, 17, { "gpio_in", "gpio_out", "uart2", "i2c3", "pwm7", "clk", "ir", "uart0", NULL, [14] = "pg_eint17" }, 14, 17, 6 },
+ { "PG18", 6, 18, { "gpio_in", "gpio_out", "uart2", "i2c3", "pwm6", "clk", "spdif", "uart0", NULL, [14] = "pg_eint18" }, 14, 18, 6 },
+};
+
+const struct allwinner_padconf d1_padconf = {
+ .npins = nitems(d1_pins),
+ .pins = d1_pins,
+};
diff --git a/sys/riscv/allwinner/files.allwinner b/sys/riscv/allwinner/files.allwinner
index f6be2cf97e57..f55d883abf57 100644
--- a/sys/riscv/allwinner/files.allwinner
+++ b/sys/riscv/allwinner/files.allwinner
@@ -1,4 +1,5 @@
+arm/allwinner/aw_gpio.c optional gpio aw_gpio fdt
arm/allwinner/aw_rtc.c optional aw_rtc fdt
arm/allwinner/aw_syscon.c optional syscon
arm/allwinner/aw_sid.c optional aw_sid nvmem
@@ -16,3 +17,5 @@ dev/clk/allwinner/aw_clk_nmm.c optional aw_ccu fdt
dev/clk/allwinner/aw_clk_np.c optional aw_ccu fdt
dev/clk/allwinner/aw_clk_prediv_mux.c optional aw_ccu fdt
dev/clk/allwinner/ccu_d1.c optional soc_allwinner_d1 aw_ccu fdt
+
+riscv/allwinner/d1_padconf.c optional soc_allwinner_d1 aw_gpio fdt
diff --git a/sys/riscv/conf/GENERIC b/sys/riscv/conf/GENERIC
index 4fdb1bdd6403..5dfc624c9dfe 100644
--- a/sys/riscv/conf/GENERIC
+++ b/sys/riscv/conf/GENERIC
@@ -152,6 +152,7 @@ device axidma # Xilinx AXI DMA Controller
# GPIO
device gpio
+device fdt_pinctrl
# SPI
device spibus
diff --git a/sys/riscv/conf/std.allwinner b/sys/riscv/conf/std.allwinner
index 4f3d98250cc5..a888e4d5d370 100644
--- a/sys/riscv/conf/std.allwinner
+++ b/sys/riscv/conf/std.allwinner
@@ -6,6 +6,7 @@
options SOC_ALLWINNER_D1
device aw_ccu # Allwinner clock controller
+device aw_gpio # Allwinner GPIO controller
device aw_rtc # Allwinner Real-time Clock
device aw_sid # Allwinner Secure ID EFUSE
device aw_wdog # Allwinner Watchdog