All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yanhong Wang <yanhong.wang@starfivetech.com>
To: <u-boot@lists.denx.de>, Rick Chen <rick@andestech.com>,
	Leo <ycliang@andestech.com>, Lukasz Majewski <lukma@denx.de>,
	Sean Anderson <seanga2@gmail.com>
Cc: Lee Kuan Lim <kuanlim.lee@starfivetech.com>,
	Jianlong Huang <jianlong.huang@starfivetech.com>,
	Emil Renner Berthing <kernel@esmil.dk>,
	Yanhong Wang <yanhong.wang@starfivetech.com>
Subject: [PATCH v3 08/17] pinctrl: starfive: Add StarFive JH7110 driver
Date: Fri, 3 Mar 2023 11:24:23 +0800	[thread overview]
Message-ID: <20230303032432.7837-9-yanhong.wang@starfivetech.com> (raw)
In-Reply-To: <20230303032432.7837-1-yanhong.wang@starfivetech.com>

From: Kuan Lim Lee <kuanlim.lee@linux.starfivetech.com>

Add pinctrl driver for StarFive JH7110 SoC.

Signed-off-by: Kuan Lim Lee <kuanlim.lee@linux.starfivetech.com>
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
---
 drivers/pinctrl/Kconfig                       |   1 +
 drivers/pinctrl/Makefile                      |   1 +
 drivers/pinctrl/starfive/Kconfig              |  28 ++
 drivers/pinctrl/starfive/Makefile             |   6 +
 drivers/pinctrl/starfive/pinctrl-jh7110-aon.c | 113 +++++
 drivers/pinctrl/starfive/pinctrl-jh7110-sys.c | 399 ++++++++++++++++++
 drivers/pinctrl/starfive/pinctrl-starfive.c   | 382 +++++++++++++++++
 drivers/pinctrl/starfive/pinctrl-starfive.h   |  55 +++
 8 files changed, 985 insertions(+)
 create mode 100644 drivers/pinctrl/starfive/Kconfig
 create mode 100644 drivers/pinctrl/starfive/Makefile
 create mode 100644 drivers/pinctrl/starfive/pinctrl-jh7110-aon.c
 create mode 100644 drivers/pinctrl/starfive/pinctrl-jh7110-sys.c
 create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive.c
 create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive.h

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index b6ef2acced..75b3ff47a2 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -359,5 +359,6 @@ source "drivers/pinctrl/renesas/Kconfig"
 source "drivers/pinctrl/rockchip/Kconfig"
 source "drivers/pinctrl/sunxi/Kconfig"
 source "drivers/pinctrl/uniphier/Kconfig"
+source "drivers/pinctrl/starfive/Kconfig"
 
 endmenu
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 3b167d099f..852adee4b4 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -32,3 +32,4 @@ obj-$(CONFIG_PINCTRL_STM32)	+= pinctrl_stm32.o
 obj-$(CONFIG_$(SPL_)PINCTRL_STMFX)	+= pinctrl-stmfx.o
 obj-y				+= broadcom/
 obj-$(CONFIG_PINCTRL_ZYNQMP)	+= pinctrl-zynqmp.o
+obj-$(CONFIG_PINCTRL_STARFIVE)	+= starfive/
diff --git a/drivers/pinctrl/starfive/Kconfig b/drivers/pinctrl/starfive/Kconfig
new file mode 100644
index 0000000000..1b859c863e
--- /dev/null
+++ b/drivers/pinctrl/starfive/Kconfig
@@ -0,0 +1,28 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config SPL_PINCTRL_STARFIVE
+	bool "Support Pinctrl driver for StarFive SoC in SPL"
+	depends on SPL_PINCTRL_FULL && STARFIVE_JH7110
+	help
+	  Enable support pin control driver for StarFive SoC.
+
+config SPL_PINCTRL_STARFIVE_JH7110
+	bool "Support Pinctrl and GPIO driver for StarFive JH7110 SoC in SPL"
+	depends on  SPL_PINCTRL_STARFIVE
+	help
+	  Enable support pinctrl and gpio driver for StarFive JH7110 in SPL.
+
+config PINCTRL_STARFIVE
+	bool "Pinctrl driver for StarFive SoC"
+	depends on PINCTRL_FULL && STARFIVE_JH7110
+	help
+	  Say yes here to support pin control on the StarFive RISC-V SoC.
+	  This also provides an interface to the GPIO pins not used by other
+	  peripherals supporting inputs, outputs, configuring pull-up/pull-down
+	  and interrupts on input changes.
+
+config PINCTRL_STARFIVE_JH7110
+	bool "Pinctrl and GPIO driver for StarFive JH7110 SoC"
+	depends on  PINCTRL_STARFIVE
+	help
+	  This selects the pinctrl driver for JH7110 starfive.
diff --git a/drivers/pinctrl/starfive/Makefile b/drivers/pinctrl/starfive/Makefile
new file mode 100644
index 0000000000..a4a12069b3
--- /dev/null
+++ b/drivers/pinctrl/starfive/Makefile
@@ -0,0 +1,6 @@
+
+# SPDX-License-Identifier: GPL-2.0
+# Core
+obj-$(CONFIG_$(SPL_TPL_)PINCTRL_STARFIVE) += pinctrl-starfive.o
+# SoC Drivers
+obj-$(CONFIG_$(SPL_TPL_)PINCTRL_STARFIVE_JH7110)	+= pinctrl-jh7110-sys.o pinctrl-jh7110-aon.o
diff --git a/drivers/pinctrl/starfive/pinctrl-jh7110-aon.c b/drivers/pinctrl/starfive/pinctrl-jh7110-aon.c
new file mode 100644
index 0000000000..2d739906e2
--- /dev/null
+++ b/drivers/pinctrl/starfive/pinctrl-jh7110-aon.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Pinctrl / GPIO driver for StarFive JH7110 SoC
+ *
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ *   Author: Lee Kuan Lim <kuanlim.lee@starfivetech.com>
+ *   Author: Jianlong Huang <jianlong.huang@starfivetech.com>
+ */
+
+#include <dm/read.h>
+#include <dm/device_compat.h>
+#include <linux/io.h>
+
+#include <dt-bindings/pinctrl/pinctrl-starfive-jh7110.h>
+#include "pinctrl-starfive.h"
+
+#define JH7110_AON_NGPIO		4
+#define JH7110_AON_GC_BASE		64
+
+/* registers */
+#define JH7110_AON_DOEN		0x0
+#define JH7110_AON_DOUT		0x4
+#define JH7110_AON_GPI			0x8
+#define JH7110_AON_GPIOIN		0x2c
+
+#define JH7110_AON_GPIOEN		0xc
+#define JH7110_AON_GPIOIS		0x10
+#define JH7110_AON_GPIOIC		0x14
+#define JH7110_AON_GPIOIBE		0x18
+#define JH7110_AON_GPIOIEV		0x1c
+#define JH7110_AON_GPIOIE		0x20
+#define JH7110_AON_GPIORIS		0x28
+#define JH7110_AON_GPIOMIS		0x28
+
+#define AON_GPO_PDA_0_5_CFG		0x30
+
+static int jh7110_aon_set_one_pin_mux(struct udevice *dev, unsigned int pin,
+				      unsigned int din, u32 dout,
+				      u32 doen, u32 func)
+{
+	struct starfive_pinctrl_priv *priv = dev_get_priv(dev);
+
+	if (pin < priv->info->ngpios && func == 0)
+		starfive_set_gpiomux(dev, pin, din, dout, doen);
+
+	return 0;
+}
+
+static int jh7110_aon_get_padcfg_base(struct udevice *dev,
+				      unsigned int pin)
+{
+	if (pin < PAD_GMAC0_MDC)
+		return AON_GPO_PDA_0_5_CFG;
+
+	return -1;
+}
+
+static void jh7110_aon_init_hw(struct udevice *dev)
+{
+	struct starfive_pinctrl_priv *priv = dev_get_priv(dev);
+
+	/* mask all GPIO interrupts */
+	writel(0, priv->base + JH7110_AON_GPIOIE);
+	/* clear edge interrupt flags */
+	writel(0, priv->base + JH7110_AON_GPIOIC);
+	writel(0x0f, priv->base + JH7110_AON_GPIOIC);
+	/* enable GPIO interrupts */
+	writel(1, priv->base + JH7110_AON_GPIOEN);
+}
+
+const struct starfive_pinctrl_soc_info jh7110_aon_pinctrl_info = {
+	/* pin conf */
+	.set_one_pinmux = jh7110_aon_set_one_pin_mux,
+	.get_padcfg_base  = jh7110_aon_get_padcfg_base,
+
+	/* gpio dout/doen/din/gpioinput register */
+	.dout_reg_base = JH7110_AON_DOUT,
+	.dout_mask = GENMASK(3, 0),
+	.doen_reg_base = JH7110_AON_DOEN,
+	.doen_mask = GENMASK(2, 0),
+	.gpi_reg_base = JH7110_AON_GPI,
+	.gpi_mask = GENMASK(3, 0),
+	.gpioin_reg_base = JH7110_AON_GPIOIN,
+
+	/* gpio */
+	.gpio_bank_name = "RGPIO",
+	.ngpios = JH7110_AON_NGPIO,
+	.gpio_init_hw = jh7110_aon_init_hw,
+};
+
+static int jh7110_aon_pinctrl_probe(struct udevice *dev)
+{
+	struct starfive_pinctrl_soc_info *info =
+		(struct starfive_pinctrl_soc_info *)dev_get_driver_data(dev);
+
+	return starfive_pinctrl_probe(dev, info);
+}
+
+static const struct udevice_id jh7110_aon_pinctrl_ids[] = {
+	/* JH7110 aon pinctrl */
+	{ .compatible = "starfive,jh7110-aon-pinctrl",
+	  .data = (ulong)&jh7110_aon_pinctrl_info, },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(jh7110_aon_pinctrl) = {
+	.name		= "jh7110-aon-pinctrl",
+	.id		= UCLASS_PINCTRL,
+	.of_match	= jh7110_aon_pinctrl_ids,
+	.priv_auto	= sizeof(struct starfive_pinctrl_priv),
+	.ops		= &starfive_pinctrl_ops,
+	.probe		= jh7110_aon_pinctrl_probe,
+};
diff --git a/drivers/pinctrl/starfive/pinctrl-jh7110-sys.c b/drivers/pinctrl/starfive/pinctrl-jh7110-sys.c
new file mode 100644
index 0000000000..dafba65eae
--- /dev/null
+++ b/drivers/pinctrl/starfive/pinctrl-jh7110-sys.c
@@ -0,0 +1,399 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Pinctrl / GPIO driver for StarFive JH7110 SoC
+ *
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ *   Author: Lee Kuan Lim <kuanlim.lee@starfivetech.com>
+ *   Author: Jianlong Huang <jianlong.huang@starfivetech.com>
+ */
+
+#include <dm/read.h>
+#include <dm/device_compat.h>
+#include <linux/io.h>
+
+#include <dt-bindings/pinctrl/pinctrl-starfive-jh7110.h>
+#include "pinctrl-starfive.h"
+
+#define JH7110_SYS_NGPIO		64
+#define JH7110_SYS_GC_BASE		0
+
+/* registers */
+#define JH7110_SYS_DOEN		0x000
+#define JH7110_SYS_DOUT		0x040
+#define JH7110_SYS_GPI			0x080
+#define JH7110_SYS_GPIOIN		0x118
+
+#define JH7110_SYS_GPIOEN		0x0dc
+#define JH7110_SYS_GPIOIS0		0x0e0
+#define JH7110_SYS_GPIOIS1		0x0e4
+#define JH7110_SYS_GPIOIC0		0x0e8
+#define JH7110_SYS_GPIOIC1		0x0ec
+#define JH7110_SYS_GPIOIBE0		0x0f0
+#define JH7110_SYS_GPIOIBE1		0x0f4
+#define JH7110_SYS_GPIOIEV0		0x0f8
+#define JH7110_SYS_GPIOIEV1		0x0fc
+#define JH7110_SYS_GPIOIE0		0x100
+#define JH7110_SYS_GPIOIE1		0x104
+#define JH7110_SYS_GPIORIS0		0x108
+#define JH7110_SYS_GPIORIS1		0x10c
+#define JH7110_SYS_GPIOMIS0		0x110
+#define JH7110_SYS_GPIOMIS1		0x114
+
+#define SYS_GPO_PDA_0_74_CFG		0x120
+#define SYS_GPO_PDA_89_94_CFG		0x284
+
+static const struct starfive_pinctrl_pin jh7110_sys_pins[] = {
+	STARFIVE_PINCTRL(PAD_GPIO0,		"GPIO0"),
+	STARFIVE_PINCTRL(PAD_GPIO1,		"GPIO1"),
+	STARFIVE_PINCTRL(PAD_GPIO2,		"GPIO2"),
+	STARFIVE_PINCTRL(PAD_GPIO3,		"GPIO3"),
+	STARFIVE_PINCTRL(PAD_GPIO4,		"GPIO4"),
+	STARFIVE_PINCTRL(PAD_GPIO5,		"GPIO5"),
+	STARFIVE_PINCTRL(PAD_GPIO6,		"GPIO6"),
+	STARFIVE_PINCTRL(PAD_GPIO7,		"GPIO7"),
+	STARFIVE_PINCTRL(PAD_GPIO8,		"GPIO8"),
+	STARFIVE_PINCTRL(PAD_GPIO9,		"GPIO9"),
+	STARFIVE_PINCTRL(PAD_GPIO10,		"GPIO10"),
+	STARFIVE_PINCTRL(PAD_GPIO11,		"GPIO11"),
+	STARFIVE_PINCTRL(PAD_GPIO12,		"GPIO12"),
+	STARFIVE_PINCTRL(PAD_GPIO13,		"GPIO13"),
+	STARFIVE_PINCTRL(PAD_GPIO14,		"GPIO14"),
+	STARFIVE_PINCTRL(PAD_GPIO15,		"GPIO15"),
+	STARFIVE_PINCTRL(PAD_GPIO16,		"GPIO16"),
+	STARFIVE_PINCTRL(PAD_GPIO17,		"GPIO17"),
+	STARFIVE_PINCTRL(PAD_GPIO18,		"GPIO18"),
+	STARFIVE_PINCTRL(PAD_GPIO19,		"GPIO19"),
+	STARFIVE_PINCTRL(PAD_GPIO20,		"GPIO20"),
+	STARFIVE_PINCTRL(PAD_GPIO21,		"GPIO21"),
+	STARFIVE_PINCTRL(PAD_GPIO22,		"GPIO22"),
+	STARFIVE_PINCTRL(PAD_GPIO23,		"GPIO23"),
+	STARFIVE_PINCTRL(PAD_GPIO24,		"GPIO24"),
+	STARFIVE_PINCTRL(PAD_GPIO25,		"GPIO25"),
+	STARFIVE_PINCTRL(PAD_GPIO26,		"GPIO26"),
+	STARFIVE_PINCTRL(PAD_GPIO27,		"GPIO27"),
+	STARFIVE_PINCTRL(PAD_GPIO28,		"GPIO28"),
+	STARFIVE_PINCTRL(PAD_GPIO29,		"GPIO29"),
+	STARFIVE_PINCTRL(PAD_GPIO30,		"GPIO30"),
+	STARFIVE_PINCTRL(PAD_GPIO31,		"GPIO31"),
+	STARFIVE_PINCTRL(PAD_GPIO32,		"GPIO32"),
+	STARFIVE_PINCTRL(PAD_GPIO33,		"GPIO33"),
+	STARFIVE_PINCTRL(PAD_GPIO34,		"GPIO34"),
+	STARFIVE_PINCTRL(PAD_GPIO35,		"GPIO35"),
+	STARFIVE_PINCTRL(PAD_GPIO36,		"GPIO36"),
+	STARFIVE_PINCTRL(PAD_GPIO37,		"GPIO37"),
+	STARFIVE_PINCTRL(PAD_GPIO38,		"GPIO38"),
+	STARFIVE_PINCTRL(PAD_GPIO39,		"GPIO39"),
+	STARFIVE_PINCTRL(PAD_GPIO40,		"GPIO40"),
+	STARFIVE_PINCTRL(PAD_GPIO41,		"GPIO41"),
+	STARFIVE_PINCTRL(PAD_GPIO42,		"GPIO42"),
+	STARFIVE_PINCTRL(PAD_GPIO43,		"GPIO43"),
+	STARFIVE_PINCTRL(PAD_GPIO44,		"GPIO44"),
+	STARFIVE_PINCTRL(PAD_GPIO45,		"GPIO45"),
+	STARFIVE_PINCTRL(PAD_GPIO46,		"GPIO46"),
+	STARFIVE_PINCTRL(PAD_GPIO47,		"GPIO47"),
+	STARFIVE_PINCTRL(PAD_GPIO48,		"GPIO48"),
+	STARFIVE_PINCTRL(PAD_GPIO49,		"GPIO49"),
+	STARFIVE_PINCTRL(PAD_GPIO50,		"GPIO50"),
+	STARFIVE_PINCTRL(PAD_GPIO51,		"GPIO51"),
+	STARFIVE_PINCTRL(PAD_GPIO52,		"GPIO52"),
+	STARFIVE_PINCTRL(PAD_GPIO53,		"GPIO53"),
+	STARFIVE_PINCTRL(PAD_GPIO54,		"GPIO54"),
+	STARFIVE_PINCTRL(PAD_GPIO55,		"GPIO55"),
+	STARFIVE_PINCTRL(PAD_GPIO56,		"GPIO56"),
+	STARFIVE_PINCTRL(PAD_GPIO57,		"GPIO57"),
+	STARFIVE_PINCTRL(PAD_GPIO58,		"GPIO58"),
+	STARFIVE_PINCTRL(PAD_GPIO59,		"GPIO59"),
+	STARFIVE_PINCTRL(PAD_GPIO60,		"GPIO60"),
+	STARFIVE_PINCTRL(PAD_GPIO61,		"GPIO61"),
+	STARFIVE_PINCTRL(PAD_GPIO62,		"GPIO62"),
+	STARFIVE_PINCTRL(PAD_GPIO63,		"GPIO63"),
+	STARFIVE_PINCTRL(PAD_SD0_CLK,		"SD0_CLK"),
+	STARFIVE_PINCTRL(PAD_SD0_CMD,		"SD0_CMD"),
+	STARFIVE_PINCTRL(PAD_SD0_DATA0,		"SD0_DATA0"),
+	STARFIVE_PINCTRL(PAD_SD0_DATA1,		"SD0_DATA1"),
+	STARFIVE_PINCTRL(PAD_SD0_DATA2,		"SD0_DATA2"),
+	STARFIVE_PINCTRL(PAD_SD0_DATA3,		"SD0_DATA3"),
+	STARFIVE_PINCTRL(PAD_SD0_DATA4,		"SD0_DATA4"),
+	STARFIVE_PINCTRL(PAD_SD0_DATA5,		"SD0_DATA5"),
+	STARFIVE_PINCTRL(PAD_SD0_DATA6,		"SD0_DATA6"),
+	STARFIVE_PINCTRL(PAD_SD0_DATA7,		"SD0_DATA7"),
+	STARFIVE_PINCTRL(PAD_SD0_STRB,		"SD0_STRB"),
+	STARFIVE_PINCTRL(PAD_GMAC1_MDC,		"GMAC1_MDC"),
+	STARFIVE_PINCTRL(PAD_GMAC1_MDIO,	"GMAC1_MDIO"),
+	STARFIVE_PINCTRL(PAD_GMAC1_RXD0,	"GMAC1_RXD0"),
+	STARFIVE_PINCTRL(PAD_GMAC1_RXD1,	"GMAC1_RXD1"),
+	STARFIVE_PINCTRL(PAD_GMAC1_RXD2,	"GMAC1_RXD2"),
+	STARFIVE_PINCTRL(PAD_GMAC1_RXD3,	"GMAC1_RXD3"),
+	STARFIVE_PINCTRL(PAD_GMAC1_RXDV,	"GMAC1_RXDV"),
+	STARFIVE_PINCTRL(PAD_GMAC1_RXC,		"GMAC1_RXC"),
+	STARFIVE_PINCTRL(PAD_GMAC1_TXD0,	"GMAC1_TXD0"),
+	STARFIVE_PINCTRL(PAD_GMAC1_TXD1,	"GMAC1_TXD1"),
+	STARFIVE_PINCTRL(PAD_GMAC1_TXD2,	"GMAC1_TXD2"),
+	STARFIVE_PINCTRL(PAD_GMAC1_TXD3,	"GMAC1_TXD3"),
+	STARFIVE_PINCTRL(PAD_GMAC1_TXEN,	"GMAC1_TXEN"),
+	STARFIVE_PINCTRL(PAD_GMAC1_TXC,		"GMAC1_TXC"),
+	STARFIVE_PINCTRL(PAD_QSPI_SCLK,		"QSPI_SCLK"),
+	STARFIVE_PINCTRL(PAD_QSPI_CS0,		"QSPI_CS0"),
+	STARFIVE_PINCTRL(PAD_QSPI_DATA0,	"QSPI_DATA0"),
+	STARFIVE_PINCTRL(PAD_QSPI_DATA1,	"QSPI_DATA1"),
+	STARFIVE_PINCTRL(PAD_QSPI_DATA2,	"QSPI_DATA2"),
+	STARFIVE_PINCTRL(PAD_QSPI_DATA3,	"QSPI_DATA3"),
+};
+
+struct jh7110_func_sel {
+	u16 offset;
+	u8 shift;
+	u8 max;
+};
+
+static const struct jh7110_func_sel
+	jh7110_sys_func_sel[ARRAY_SIZE(jh7110_sys_pins)] = {
+	[PAD_GMAC1_RXC] = { 0x29c,  0, 1 },
+	[PAD_GPIO10]    = { 0x29c,  2, 3 },
+	[PAD_GPIO11]    = { 0x29c,  5, 3 },
+	[PAD_GPIO12]    = { 0x29c,  8, 3 },
+	[PAD_GPIO13]    = { 0x29c, 11, 3 },
+	[PAD_GPIO14]    = { 0x29c, 14, 3 },
+	[PAD_GPIO15]    = { 0x29c, 17, 3 },
+	[PAD_GPIO16]    = { 0x29c, 20, 3 },
+	[PAD_GPIO17]    = { 0x29c, 23, 3 },
+	[PAD_GPIO18]    = { 0x29c, 26, 3 },
+	[PAD_GPIO19]    = { 0x29c, 29, 3 },
+
+	[PAD_GPIO20]    = { 0x2a0,  0, 3 },
+	[PAD_GPIO21]    = { 0x2a0,  3, 3 },
+	[PAD_GPIO22]    = { 0x2a0,  6, 3 },
+	[PAD_GPIO23]    = { 0x2a0,  9, 3 },
+	[PAD_GPIO24]    = { 0x2a0, 12, 3 },
+	[PAD_GPIO25]    = { 0x2a0, 15, 3 },
+	[PAD_GPIO26]    = { 0x2a0, 18, 3 },
+	[PAD_GPIO27]    = { 0x2a0, 21, 3 },
+	[PAD_GPIO28]    = { 0x2a0, 24, 3 },
+	[PAD_GPIO29]    = { 0x2a0, 27, 3 },
+
+	[PAD_GPIO30]    = { 0x2a4,  0, 3 },
+	[PAD_GPIO31]    = { 0x2a4,  3, 3 },
+	[PAD_GPIO32]    = { 0x2a4,  6, 3 },
+	[PAD_GPIO33]    = { 0x2a4,  9, 3 },
+	[PAD_GPIO34]    = { 0x2a4, 12, 3 },
+	[PAD_GPIO35]    = { 0x2a4, 15, 3 },
+	[PAD_GPIO36]    = { 0x2a4, 17, 3 },
+	[PAD_GPIO37]    = { 0x2a4, 20, 3 },
+	[PAD_GPIO38]    = { 0x2a4, 23, 3 },
+	[PAD_GPIO39]    = { 0x2a4, 26, 3 },
+	[PAD_GPIO40]    = { 0x2a4, 29, 3 },
+
+	[PAD_GPIO41]    = { 0x2a8,  0, 3 },
+	[PAD_GPIO42]    = { 0x2a8,  3, 3 },
+	[PAD_GPIO43]    = { 0x2a8,  6, 3 },
+	[PAD_GPIO44]    = { 0x2a8,  9, 3 },
+	[PAD_GPIO45]    = { 0x2a8, 12, 3 },
+	[PAD_GPIO46]    = { 0x2a8, 15, 3 },
+	[PAD_GPIO47]    = { 0x2a8, 18, 3 },
+	[PAD_GPIO48]    = { 0x2a8, 21, 3 },
+	[PAD_GPIO49]    = { 0x2a8, 24, 3 },
+	[PAD_GPIO50]    = { 0x2a8, 27, 3 },
+	[PAD_GPIO51]    = { 0x2a8, 30, 3 },
+
+	[PAD_GPIO52]    = { 0x2ac,  0, 3 },
+	[PAD_GPIO53]    = { 0x2ac,  2, 3 },
+	[PAD_GPIO54]    = { 0x2ac,  4, 3 },
+	[PAD_GPIO55]    = { 0x2ac,  6, 3 },
+	[PAD_GPIO56]    = { 0x2ac,  9, 3 },
+	[PAD_GPIO57]    = { 0x2ac, 12, 3 },
+	[PAD_GPIO58]    = { 0x2ac, 15, 3 },
+	[PAD_GPIO59]    = { 0x2ac, 18, 3 },
+	[PAD_GPIO60]    = { 0x2ac, 21, 3 },
+	[PAD_GPIO61]    = { 0x2ac, 24, 3 },
+	[PAD_GPIO62]    = { 0x2ac, 27, 3 },
+	[PAD_GPIO63]    = { 0x2ac, 30, 3 },
+
+	[PAD_GPIO6]     = { 0x2b0,  0, 3 },
+	[PAD_GPIO7]     = { 0x2b0,  2, 3 },
+	[PAD_GPIO8]     = { 0x2b0,  5, 3 },
+	[PAD_GPIO9]     = { 0x2b0,  8, 3 },
+};
+
+struct jh7110_vin_group_sel {
+	u16 offset;
+	u8 shift;
+	u8 group;
+};
+
+static const struct jh7110_vin_group_sel
+	jh7110_sys_vin_group_sel[ARRAY_SIZE(jh7110_sys_pins)] = {
+	[PAD_GPIO6]     = { 0x2b4, 21, 0 },
+	[PAD_GPIO7]     = { 0x2b4, 18, 0 },
+	[PAD_GPIO8]     = { 0x2b4, 15, 0 },
+	[PAD_GPIO9]     = { 0x2b0, 11, 0 },
+	[PAD_GPIO10]    = { 0x2b0, 20, 0 },
+	[PAD_GPIO11]    = { 0x2b0, 23, 0 },
+	[PAD_GPIO12]    = { 0x2b0, 26, 0 },
+	[PAD_GPIO13]    = { 0x2b0, 29, 0 },
+	[PAD_GPIO14]    = { 0x2b4,  0, 0 },
+	[PAD_GPIO15]    = { 0x2b4,  3, 0 },
+	[PAD_GPIO16]    = { 0x2b4,  6, 0 },
+	[PAD_GPIO17]    = { 0x2b4,  9, 0 },
+	[PAD_GPIO18]    = { 0x2b4, 12, 0 },
+	[PAD_GPIO19]    = { 0x2b0, 14, 0 },
+	[PAD_GPIO20]    = { 0x2b0, 17, 0 },
+
+	[PAD_GPIO21]    = { 0x2b4, 21, 1 },
+	[PAD_GPIO22]    = { 0x2b4, 18, 1 },
+	[PAD_GPIO23]    = { 0x2b4, 15, 1 },
+	[PAD_GPIO24]    = { 0x2b0, 11, 1 },
+	[PAD_GPIO25]    = { 0x2b0, 20, 1 },
+	[PAD_GPIO26]    = { 0x2b0, 23, 1 },
+	[PAD_GPIO27]    = { 0x2b0, 26, 1 },
+	[PAD_GPIO28]    = { 0x2b0, 29, 1 },
+	[PAD_GPIO29]    = { 0x2b4,  0, 1 },
+	[PAD_GPIO30]    = { 0x2b4,  3, 1 },
+	[PAD_GPIO31]    = { 0x2b4,  6, 1 },
+	[PAD_GPIO32]    = { 0x2b4,  9, 1 },
+	[PAD_GPIO33]    = { 0x2b4, 12, 1 },
+	[PAD_GPIO34]    = { 0x2b0, 14, 1 },
+	[PAD_GPIO35]    = { 0x2b0, 17, 1 },
+
+	[PAD_GPIO36]    = { 0x2b4, 21, 2 },
+	[PAD_GPIO37]    = { 0x2b4, 18, 2 },
+	[PAD_GPIO38]    = { 0x2b4, 15, 2 },
+	[PAD_GPIO39]    = { 0x2b0, 11, 2 },
+	[PAD_GPIO40]    = { 0x2b0, 20, 2 },
+	[PAD_GPIO41]    = { 0x2b0, 23, 2 },
+	[PAD_GPIO42]    = { 0x2b0, 26, 2 },
+	[PAD_GPIO43]    = { 0x2b0, 29, 2 },
+	[PAD_GPIO44]    = { 0x2b4,  0, 2 },
+	[PAD_GPIO45]    = { 0x2b4,  3, 2 },
+	[PAD_GPIO46]    = { 0x2b4,  6, 2 },
+	[PAD_GPIO47]    = { 0x2b4,  9, 2 },
+	[PAD_GPIO48]    = { 0x2b4, 12, 2 },
+	[PAD_GPIO49]    = { 0x2b0, 14, 2 },
+	[PAD_GPIO50]    = { 0x2b0, 17, 2 },
+};
+
+static void jh7110_set_function(struct udevice *dev,
+				unsigned int pin, u32 func)
+{
+	const struct jh7110_func_sel *fs = &jh7110_sys_func_sel[pin];
+	struct starfive_pinctrl_priv *priv = dev_get_priv(dev);
+	void __iomem *reg;
+	u32 mask;
+
+	if (!fs->offset)
+		return;
+
+	if (func > fs->max)
+		return;
+
+	reg = priv->base + fs->offset;
+	func = func << fs->shift;
+	mask = 0x3U << fs->shift;
+
+	func |= readl(reg) & ~mask;
+	writel(func, reg);
+}
+
+static void jh7110_set_vin_group(struct udevice *dev, unsigned int pin)
+{
+	const struct jh7110_vin_group_sel *gs =
+		&jh7110_sys_vin_group_sel[pin];
+	struct starfive_pinctrl_priv *priv = dev_get_priv(dev);
+	void __iomem *reg;
+	u32 mask;
+	u32 grp;
+
+	if (!gs->offset)
+		return;
+
+	reg = priv->base + gs->offset;
+	grp = gs->group << gs->shift;
+	mask = 0x3U << gs->shift;
+
+	grp |= readl(reg) & ~mask;
+	writel(grp, reg);
+}
+
+static int jh7110_sys_set_one_pin_mux(struct udevice *dev, unsigned int pin,
+				      unsigned int din, u32 dout, u32 doen, u32 func)
+{
+	struct starfive_pinctrl_priv *priv = dev_get_priv(dev);
+
+	if (pin < priv->info->ngpios && func == 0)
+		starfive_set_gpiomux(dev, pin, din, dout, doen);
+
+	jh7110_set_function(dev, pin, func);
+
+	if (pin < priv->info->ngpios && func == 2)
+		jh7110_set_vin_group(dev, pin);
+
+	return 0;
+}
+
+static int jh7110_sys_get_padcfg_base(struct udevice *dev,
+				      unsigned int pin)
+{
+	if (pin < PAD_GMAC1_MDC)
+		return SYS_GPO_PDA_0_74_CFG;
+	else if (pin > PAD_GMAC1_TXC && pin <= PAD_QSPI_DATA3)
+		return SYS_GPO_PDA_89_94_CFG;
+	else
+		return -1;
+}
+
+static void jh7110_sys_init_hw(struct udevice *dev)
+{
+	struct starfive_pinctrl_priv *priv = dev_get_priv(dev);
+
+	/* mask all GPIO interrupts */
+	writel(0U, priv->base + JH7110_SYS_GPIOIE0);
+	writel(0U, priv->base + JH7110_SYS_GPIOIE1);
+	/* clear edge interrupt flags */
+	writel(~0U, priv->base + JH7110_SYS_GPIOIC0);
+	writel(~0U, priv->base + JH7110_SYS_GPIOIC1);
+	/* enable GPIO interrupts */
+	writel(1U, priv->base + JH7110_SYS_GPIOEN);
+}
+
+const struct starfive_pinctrl_soc_info jh7110_sys_pinctrl_info = {
+	/* pin conf */
+	.set_one_pinmux = jh7110_sys_set_one_pin_mux,
+	.get_padcfg_base = jh7110_sys_get_padcfg_base,
+
+	/* gpio dout/doen/din/gpioinput register */
+	.dout_reg_base = JH7110_SYS_DOUT,
+	.dout_mask = GENMASK(6, 0),
+	.doen_reg_base = JH7110_SYS_DOEN,
+	.doen_mask = GENMASK(5, 0),
+	.gpi_reg_base = JH7110_SYS_GPI,
+	.gpi_mask = GENMASK(6, 0),
+	.gpioin_reg_base = JH7110_SYS_GPIOIN,
+
+	/* gpio */
+	.gpio_bank_name = "GPIO",
+	.ngpios = JH7110_SYS_NGPIO,
+	.gpio_init_hw = jh7110_sys_init_hw,
+};
+
+static int jh7110_sys_pinctrl_probe(struct udevice *dev)
+{
+	struct starfive_pinctrl_soc_info *info =
+		(struct starfive_pinctrl_soc_info *)dev_get_driver_data(dev);
+
+	return starfive_pinctrl_probe(dev, info);
+}
+
+static const struct udevice_id jh7110_sys_pinctrl_ids[] = {
+	/* JH7110 sys pinctrl */
+	{ .compatible = "starfive,jh7110-sys-pinctrl",
+	  .data = (ulong)&jh7110_sys_pinctrl_info, },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(jh7110_sys_pinctrl) = {
+	.name		= "jh7110-sys-pinctrl",
+	.id		= UCLASS_PINCTRL,
+	.of_match	= jh7110_sys_pinctrl_ids,
+	.priv_auto	= sizeof(struct starfive_pinctrl_priv),
+	.ops		= &starfive_pinctrl_ops,
+	.probe		= jh7110_sys_pinctrl_probe,
+};
diff --git a/drivers/pinctrl/starfive/pinctrl-starfive.c b/drivers/pinctrl/starfive/pinctrl-starfive.c
new file mode 100644
index 0000000000..1be9f36bb3
--- /dev/null
+++ b/drivers/pinctrl/starfive/pinctrl-starfive.c
@@ -0,0 +1,382 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Pinctrl / GPIO driver for StarFive JH7100 SoC
+ *
+ * Copyright (C) 2022 Shanghai StarFive Technology Co., Ltd.
+ *   Author: Lee Kuan Lim <kuanlim.lee@starfivetech.com>
+ *   Author: Jianlong Huang <jianlong.huang@starfivetech.com>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/pinctrl.h>
+#include <asm-generic/gpio.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <dm/device_compat.h>
+#include <dt-bindings/pinctrl/pinctrl-starfive-jh7110.h>
+
+#include "pinctrl-starfive.h"
+
+/* pad control bits */
+#define STARFIVE_PADCFG_POS	BIT(7)
+#define STARFIVE_PADCFG_SMT	BIT(6)
+#define STARFIVE_PADCFG_SLEW	BIT(5)
+#define STARFIVE_PADCFG_PD	BIT(4)
+#define STARFIVE_PADCFG_PU	BIT(3)
+#define STARFIVE_PADCFG_BIAS	(STARFIVE_PADCFG_PD | STARFIVE_PADCFG_PU)
+#define STARFIVE_PADCFG_DS_MASK	GENMASK(2, 1)
+#define STARFIVE_PADCFG_DS_2MA	(0U << 1)
+#define STARFIVE_PADCFG_DS_4MA	BIT(1)
+#define STARFIVE_PADCFG_DS_8MA	(2U << 1)
+#define STARFIVE_PADCFG_DS_12MA	(3U << 1)
+#define STARFIVE_PADCFG_IE	BIT(0)
+#define GPIO_NUM_PER_WORD	32
+
+/*
+ * The packed pinmux values from the device tree look like this:
+ *
+ *  | 31 - 24 | 23 - 16 | 15 - 10 |  9 - 8   | 7 - 0 |
+ *  |   din   |  dout   |  doen   | function |  pin  |
+ */
+static unsigned int starfive_pinmux_din(u32 v)
+{
+	return (v & GENMASK(31, 24)) >> 24;
+}
+
+static u32 starfive_pinmux_dout(u32 v)
+{
+	return (v & GENMASK(23, 16)) >> 16;
+}
+
+static u32 starfive_pinmux_doen(u32 v)
+{
+	return (v & GENMASK(15, 10)) >> 10;
+}
+
+static u32 starfive_pinmux_function(u32 v)
+{
+	return (v & GENMASK(9, 8)) >> 8;
+}
+
+static unsigned int starfive_pinmux_pin(u32 v)
+{
+	return v & GENMASK(7, 0);
+}
+
+void starfive_set_gpiomux(struct udevice *dev, unsigned int pin,
+			  unsigned int din, u32 dout, u32 doen)
+{
+	struct starfive_pinctrl_priv *priv = dev_get_priv(dev);
+	const struct starfive_pinctrl_soc_info *info = priv->info;
+
+	unsigned int offset = 4 * (pin / 4);
+	unsigned int shift  = 8 * (pin % 4);
+	u32 dout_mask = info->dout_mask << shift;
+	u32 done_mask = info->doen_mask << shift;
+	u32 ival, imask;
+	void __iomem *reg_dout;
+	void __iomem *reg_doen;
+	void __iomem *reg_din;
+
+	reg_dout = priv->base + info->dout_reg_base + offset;
+	reg_doen = priv->base + info->doen_reg_base + offset;
+	dout <<= shift;
+	doen <<= shift;
+	if (din != GPI_NONE) {
+		unsigned int ioffset = 4 * (din / 4);
+		unsigned int ishift  = 8 * (din % 4);
+
+		reg_din = priv->base + info->gpi_reg_base + ioffset;
+		ival = (pin + 2) << ishift;
+		imask = info->gpi_mask << ishift;
+	} else {
+		reg_din = NULL;
+	}
+
+	dout |= readl(reg_dout) & ~dout_mask;
+	writel(dout, reg_dout);
+	doen |= readl(reg_doen) & ~done_mask;
+	writel(doen, reg_doen);
+	if (reg_din) {
+		ival |= readl(reg_din) & ~imask;
+		writel(ival, reg_din);
+	}
+}
+
+static const struct pinconf_param starfive_pinconf_params[] = {
+	{ "bias-disable",	PIN_CONFIG_BIAS_DISABLE,	0 },
+	{ "bias-pull-up",	PIN_CONFIG_BIAS_PULL_UP,	1 },
+	{ "bias-pull-down",	PIN_CONFIG_BIAS_PULL_DOWN,	1 },
+	{ "drive-strength",	PIN_CONFIG_DRIVE_STRENGTH,	0 },
+	{ "input-schmitt-enable",  PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
+	{ "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
+	{ "input-enable",	PIN_CONFIG_INPUT_ENABLE,	1 },
+	{ "input-disable",	PIN_CONFIG_INPUT_ENABLE,	0 },
+	{ "slew-rate",		PIN_CONFIG_SLEW_RATE,		0 },
+};
+
+static const u8 starfive_drive_strength_mA[4] = { 2, 4, 8, 12 };
+
+static u32 starfive_padcfg_ds_from_mA(u32 v)
+{
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		if (v <= starfive_drive_strength_mA[i])
+			break;
+	}
+	return i << 1;
+}
+
+static void starfive_padcfg_rmw(struct udevice *dev,
+				unsigned int pin, u32 mask, u32 value)
+{
+	struct starfive_pinctrl_priv *priv = dev_get_priv(dev);
+	struct starfive_pinctrl_soc_info *info = priv->info;
+	void __iomem *reg;
+	int padcfg_base;
+
+	if (!info->get_padcfg_base)
+		return;
+
+	padcfg_base = info->get_padcfg_base(dev, pin);
+	if (padcfg_base < 0)
+		return;
+
+	reg = priv->base + padcfg_base + 4 * pin;
+	value &= mask;
+
+	value |= readl(reg) & ~mask;
+	writel(value, reg);
+}
+
+static int starfive_pinconf_set(struct udevice *dev, unsigned int pin,
+				unsigned int param, unsigned int arg)
+{
+	u16 mask = 0;
+	u16 value = 0;
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+		mask |= STARFIVE_PADCFG_BIAS;
+		value &= ~STARFIVE_PADCFG_BIAS;
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		if (arg == 0)
+			return -EINVAL;
+		mask |= STARFIVE_PADCFG_BIAS;
+		value = (value & ~STARFIVE_PADCFG_BIAS) | STARFIVE_PADCFG_PD;
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (arg == 0)
+			return -EINVAL;
+		mask |= STARFIVE_PADCFG_BIAS;
+		value = (value & ~STARFIVE_PADCFG_BIAS) | STARFIVE_PADCFG_PU;
+		break;
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		mask |= STARFIVE_PADCFG_DS_MASK;
+		value = (value & ~STARFIVE_PADCFG_DS_MASK) |
+			starfive_padcfg_ds_from_mA(arg);
+		break;
+	case PIN_CONFIG_INPUT_ENABLE:
+		mask |= STARFIVE_PADCFG_IE;
+		if (arg)
+			value |= STARFIVE_PADCFG_IE;
+		else
+			value &= ~STARFIVE_PADCFG_IE;
+		break;
+	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+		mask |= STARFIVE_PADCFG_SMT;
+		if (arg)
+			value |= STARFIVE_PADCFG_SMT;
+		else
+			value &= ~STARFIVE_PADCFG_SMT;
+		break;
+	case PIN_CONFIG_SLEW_RATE:
+		mask |= STARFIVE_PADCFG_SLEW;
+		if (arg)
+			value |= STARFIVE_PADCFG_SLEW;
+		else
+			value &= ~STARFIVE_PADCFG_SLEW;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	starfive_padcfg_rmw(dev, pin, mask, value);
+
+	return 0;
+}
+
+static int starfive_property_set(struct udevice *dev, u32 pinmux_group)
+{
+	struct starfive_pinctrl_priv *priv = dev_get_priv(dev);
+	struct starfive_pinctrl_soc_info *info = priv->info;
+
+	if (info->set_one_pinmux)
+		info->set_one_pinmux(dev,
+			starfive_pinmux_pin(pinmux_group),
+			starfive_pinmux_din(pinmux_group),
+			starfive_pinmux_dout(pinmux_group),
+			starfive_pinmux_doen(pinmux_group),
+			starfive_pinmux_function(pinmux_group));
+
+	return starfive_pinmux_pin(pinmux_group);
+}
+
+const struct pinctrl_ops starfive_pinctrl_ops = {
+	.set_state = pinctrl_generic_set_state,
+	.pinconf_num_params	= ARRAY_SIZE(starfive_pinconf_params),
+	.pinconf_params		= starfive_pinconf_params,
+	.pinconf_set		= starfive_pinconf_set,
+	.pinmux_property_set = starfive_property_set,
+};
+
+static int starfive_gpio_direction_input(struct udevice *dev, unsigned int off)
+{
+	struct udevice *pdev = dev->parent;
+	struct starfive_pinctrl_priv *priv = dev_get_priv(dev);
+	struct starfive_pinctrl_soc_info *info = priv->info;
+
+	/* enable input and schmitt trigger */
+	starfive_padcfg_rmw(pdev, off,
+			    STARFIVE_PADCFG_IE | STARFIVE_PADCFG_SMT,
+			    STARFIVE_PADCFG_IE | STARFIVE_PADCFG_SMT);
+
+	if (info->set_one_pinmux)
+		info->set_one_pinmux(pdev, off,
+				GPI_NONE, GPOUT_LOW, GPOEN_DISABLE, 0);
+
+	return 0;
+}
+
+static int starfive_gpio_direction_output(struct udevice *dev,
+					  unsigned int off, int val)
+{
+	struct udevice *pdev = dev->parent;
+	struct starfive_pinctrl_priv *priv = dev_get_priv(dev);
+	struct starfive_pinctrl_soc_info *info = priv->info;
+
+	if (info->set_one_pinmux)
+		info->set_one_pinmux(pdev, off,
+				GPI_NONE, val ? GPOUT_HIGH : GPOUT_LOW,
+				GPOEN_ENABLE, 0);
+
+	/* disable input, schmitt trigger and bias */
+	starfive_padcfg_rmw(pdev, off,
+			    STARFIVE_PADCFG_IE | STARFIVE_PADCFG_SMT
+			    | STARFIVE_PADCFG_BIAS,
+			    0);
+
+	return 0;
+}
+
+static int starfive_gpio_get_value(struct udevice *dev, unsigned int off)
+{
+	struct udevice *pdev = dev->parent;
+	struct starfive_pinctrl_priv *priv = dev_get_priv(pdev);
+	struct starfive_pinctrl_soc_info *info = priv->info;
+
+	void __iomem *reg = priv->base + info->gpioin_reg_base
+			+ 4 * (off / GPIO_NUM_PER_WORD);
+
+	return !!(readl(reg) & BIT(off % GPIO_NUM_PER_WORD));
+}
+
+static int starfive_gpio_set_value(struct udevice *dev,
+				   unsigned int off, int val)
+{
+	struct udevice *pdev = dev->parent;
+	struct starfive_pinctrl_priv *priv = dev_get_priv(pdev);
+	struct starfive_pinctrl_soc_info *info = priv->info;
+
+	unsigned int offset = 4 * (off / 4);
+	unsigned int shift  = 8 * (off % 4);
+	void __iomem *reg_dout = priv->base + info->dout_reg_base + offset;
+	u32 dout = (val ? GPOUT_HIGH : GPOUT_LOW) << shift;
+	u32 mask = info->dout_mask << shift;
+
+	dout |= readl(reg_dout) & ~mask;
+	writel(dout, reg_dout);
+
+	return 0;
+}
+
+static int starfive_gpio_probe(struct udevice *dev)
+{
+	struct gpio_dev_priv *uc_priv;
+	struct udevice *pdev = dev->parent;
+	struct starfive_pinctrl_priv *priv = dev_get_priv(pdev);
+	struct starfive_pinctrl_soc_info *info = priv->info;
+
+	uc_priv = dev_get_uclass_priv(dev);
+	uc_priv->bank_name = info->gpio_bank_name;
+	uc_priv->gpio_count = info->ngpios;
+
+	if (!info->gpio_init_hw)
+		return -ENXIO;
+
+	info->gpio_init_hw(pdev);
+
+	return 0;
+}
+
+static const struct dm_gpio_ops starfive_gpio_ops = {
+	.direction_input = starfive_gpio_direction_input,
+	.direction_output = starfive_gpio_direction_output,
+	.get_value = starfive_gpio_get_value,
+	.set_value = starfive_gpio_set_value,
+};
+
+static struct driver starfive_gpio_driver = {
+	.name = "starfive_gpio",
+	.id = UCLASS_GPIO,
+	.probe = starfive_gpio_probe,
+	.ops = &starfive_gpio_ops,
+};
+
+static int starfive_gpiochip_register(struct udevice *parent)
+{
+	struct uclass_driver *drv;
+	struct udevice *dev;
+	int ret;
+	ofnode node;
+
+	drv = lists_uclass_lookup(UCLASS_GPIO);
+	if (!drv)
+		return -ENOENT;
+
+	node = dev_ofnode(parent);
+	ret = device_bind_with_driver_data(parent, &starfive_gpio_driver,
+					   "starfive_gpio", 0, node, &dev);
+
+	return (ret == 0) ? 0 : ret;
+}
+
+int starfive_pinctrl_probe(struct udevice *dev,
+			   const struct starfive_pinctrl_soc_info *info)
+{
+	struct starfive_pinctrl_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	/* Bind pinctrl_info from .data to priv */
+	priv->info =
+		(struct starfive_pinctrl_soc_info *)dev_get_driver_data(dev);
+
+	if (!priv->info)
+		return -EINVAL;
+
+	priv->base = dev_read_addr_ptr(dev);
+	if (!priv->base)
+		return -EINVAL;
+
+	/* gpiochip register */
+	ret = starfive_gpiochip_register(dev);
+
+	return (ret == 0) ? 0 : ret;
+}
diff --git a/drivers/pinctrl/starfive/pinctrl-starfive.h b/drivers/pinctrl/starfive/pinctrl-starfive.h
new file mode 100644
index 0000000000..5721c3c36e
--- /dev/null
+++ b/drivers/pinctrl/starfive/pinctrl-starfive.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Pinctrl / GPIO driver for StarFive SoC
+ *
+ * Copyright (C) 2022 Shanghai StarFive Technology Co., Ltd.
+ *   Author: Lee Kuan Lim <kuanlim.lee@starfivetech.com>
+ *   Author: Jianlong Huang <jianlong.huang@starfivetech.com>
+ */
+
+#define STARFIVE_PINCTRL(a, b) { .number = a, .name = b }
+
+extern const struct pinctrl_ops starfive_pinctrl_ops;
+
+struct starfive_pinctrl_pin {
+	unsigned int number;
+	const char *name;
+};
+
+struct starfive_pinctrl_soc_info {
+	/* pinctrl */
+	int (*set_one_pinmux)(struct udevice *dev, unsigned int pin,
+			      unsigned int din, u32 dout, u32 doen, u32 func);
+	int (*get_padcfg_base)(struct udevice *dev,
+			       unsigned int pin);
+
+	/* gpio dout/doen/din/gpioinput register */
+	unsigned int dout_reg_base;
+	unsigned int dout_mask;
+	unsigned int doen_reg_base;
+	unsigned int doen_mask;
+	unsigned int gpi_reg_base;
+	unsigned int gpi_mask;
+	unsigned int gpioin_reg_base;
+
+	/* gpio */
+	const char *gpio_bank_name;
+	int ngpios;
+	void (*gpio_init_hw)(struct udevice *dev);
+};
+
+/*
+ * struct starfive_pinctrl_priv - private data for Starfive pinctrl driver
+ *
+ * @padctl_base: base address of the pinctrl device
+ * @info: SoC specific data & function
+ */
+struct starfive_pinctrl_priv {
+	void __iomem *base;
+	struct starfive_pinctrl_soc_info *info;
+};
+
+void starfive_set_gpiomux(struct udevice *dev, unsigned int pin,
+			  unsigned int din, u32 dout, u32 doen);
+int starfive_pinctrl_probe(struct udevice *dev,
+			   const struct starfive_pinctrl_soc_info *info);
-- 
2.17.1


  parent reply	other threads:[~2023-03-03  3:26 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-03  3:24 [PATCH v3 00/17] Basic StarFive JH7110 RISC-V SoC support Yanhong Wang
2023-03-03  3:24 ` [PATCH v3 01/17] riscv: cpu: jh7110: Add support for jh7110 SoC Yanhong Wang
2023-03-03  3:24 ` [PATCH v3 02/17] cache: starfive: Add StarFive JH7110 support Yanhong Wang
2023-03-03 21:07   ` Conor Dooley
2023-03-06  1:56     ` yanhong wang
2023-03-03  3:24 ` [PATCH v3 04/17] reset: starfive: jh7110: Add reset driver for StarFive JH7110 SoC Yanhong Wang
2023-03-03  3:24 ` [PATCH v3 05/17] dt-bindings: clock: Add StarFive JH7110 clock definitions Yanhong Wang
2023-03-03  3:24 ` [PATCH v3 06/17] clk: starfive: Add StarFive JH7110 clock driver Yanhong Wang
2023-03-03  3:24 ` [PATCH v3 07/17] dt-bindings: pinctrl: Add StarFive JH7110 pinctrl definitions Yanhong Wang
2023-03-03  3:24 ` Yanhong Wang [this message]
2023-03-03  3:24 ` [PATCH v3 09/17] ram: starfive: add ddr driver Yanhong Wang
2023-03-03  3:24 ` [PATCH v3 10/17] board: starfive: add StarFive VisionFive v2 board support Yanhong Wang
2023-03-03  3:24 ` [PATCH v3 11/17] riscv: cpu: jh7110: Add Kconfig for StarFive JH7110 SoC Yanhong Wang
2023-03-03  3:24 ` [PATCH v3 12/17] board: starfive: Add Kconfig for StarFive VisionFive v2 Board Yanhong Wang
2023-03-03  3:24 ` [PATCH v3 13/17] board: starfive: Add TARGET_STARFIVE_VISIONFIVE2 to Kconfig Yanhong Wang
2023-03-03  3:24 ` [PATCH v3 14/17] riscv: dts: jh7110: Add initial StarFive JH7110 device tree Yanhong Wang
2023-03-03 21:16   ` Conor Dooley
2023-03-07  1:59     ` yanhong wang
2023-03-07  6:30       ` Conor Dooley
2023-03-07 18:07         ` Conor Dooley
2023-03-03  3:24 ` [PATCH v3 15/17] riscv: dts: jh7110: Add initial u-boot " Yanhong Wang
2023-03-03  3:24 ` [PATCH v3 16/17] riscv: dts: jh7110: Add initial StarFive VisionFive v2 board " Yanhong Wang
2023-03-03 21:20   ` Conor Dooley
2023-03-06  2:37     ` yanhong wang
2023-03-03  3:24 ` [PATCH v3 17/17] configs: starfive: add starfive_visionfive2_defconfig Yanhong Wang
2023-03-03 21:08 ` [PATCH v3 00/17] Basic StarFive JH7110 RISC-V SoC support Conor Dooley
2023-03-06  2:52   ` yanhong wang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230303032432.7837-9-yanhong.wang@starfivetech.com \
    --to=yanhong.wang@starfivetech.com \
    --cc=jianlong.huang@starfivetech.com \
    --cc=kernel@esmil.dk \
    --cc=kuanlim.lee@starfivetech.com \
    --cc=lukma@denx.de \
    --cc=rick@andestech.com \
    --cc=seanga2@gmail.com \
    --cc=u-boot@lists.denx.de \
    --cc=ycliang@andestech.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.