Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 10 Dec 2024 21:31:17 GMT
From:      Mitchell Horne <mhorne@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 719245455853 - main - aw_gpio: support Allwinner D1 GPIO
Message-ID:  <202412102131.4BALVHnd094348@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202412102131.4BALVHnd094348>