All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Chung <eric.chung@riscstar.com>
To: u-boot-spacemit@groups.io, u-boot@lists.u-boot-project.org,
	 u-boot@lists.u-boot-project.org
Cc: Tom Rini <trini@konsulko.com>, Tim Ouyang <tim609@andestech.com>,
	 Leo Liang <leo.liang@sifive.com>, Peng Fan <peng.fan@nxp.com>,
	 Huan Zhou <pericycle.cc@gmail.com>,
	Raymond Mao <raymond.mao@riscstar.com>,
	 Jaehoon Chung <jh80.chung@samsung.com>,
	 Bhimeswararao Matsa <bhimeswararao.matsa@gmail.com>,
	 Tanmay Kathpalia <tanmay.kathpalia@altera.com>,
	 Kaustabh Chakraborty <kauschluss@disroot.org>,
	Han Xu <han.xu@nxp.com>,  Yanir Levin <yanir.levin@tandemg.com>,
	 Christoph Stoidner <c.stoidner@phytec.de>,
	 Balsundar Ponnusamy <balsundar.ponnusamy@altera.com>,
	 Daniel Palmer <daniel@thingy.jp>, Anshul Dalal <anshuld@ti.com>,
	 Bastien Curutchet <bastien.curutchet@bootlin.com>,
	 Angelo Dureghello <angelo@kernel-space.org>,
	 Johan Jonker <jbx6244@gmail.com>,
	 Sam Protsenko <semen.protsenko@linaro.org>,
	 Guodong Xu <guodong@riscstar.com>, Yao Zi <me@ziyao.cc>,
	 Rick Chen <rick@andestech.com>, Leo <ycliang@andestech.com>,
	 Eric Chung <eric.chung@riscstar.com>
Subject: [PATCH v6 04/11] pinctrl: k1: add IO power domain configuration support
Date: Mon, 27 Jul 2026 14:59:06 +0800	[thread overview]
Message-ID: <20260727-m4-v6-4-2f58566d48ca@riscstar.com> (raw)
In-Reply-To: <20260727-m4-v6-0-2f58566d48ca@riscstar.com>

Dual-voltage GPIO banks default to 3.3V, but when externally supplied
with 1.8V the internal logic must be explicitly reconfigured to match.

Add the ability to program IO power domain control registers through the
APBC block. These registers require unlocking the AIB Secure Access
Register (ASAR) before every read/write, since configuring a 1.8V domain
while 3.3V is externally supplied can cause back-powering and pin damage.

Signed-off-by: Eric Chung <eric.chung@riscstar.com>
Reviewed-by: Yao Zi <me@ziyao.cc>

---
v6:
- Use dev_read_phandle_with_args() to fetch "spacemit,apbc" instead.
v5:
- Use tabs for macro definition alignment.
- Fix the missing power source argument.
v3:
- Add SYSCON dependency in Kconfig.
- Fix not sorted issue in the driver.
---
 drivers/pinctrl/spacemit/Kconfig      |  2 +-
 drivers/pinctrl/spacemit/pinctrl-k1.c | 96 +++++++++++++++++++++++++++++++++--
 2 files changed, 94 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/spacemit/Kconfig b/drivers/pinctrl/spacemit/Kconfig
index 6aab89e160c..ff754f5839c 100644
--- a/drivers/pinctrl/spacemit/Kconfig
+++ b/drivers/pinctrl/spacemit/Kconfig
@@ -1,6 +1,6 @@
 config PINCTRL_SPACEMIT_K1
 	bool "Spacemit K1 SoC pinctrl driver"
-	depends on PINCTRL_GENERIC && DM
+	depends on PINCTRL_GENERIC && DM && SYSCON
 	help
 	  Supports pin multiplexing control on Spacemit K1 SoCs.
 
diff --git a/drivers/pinctrl/spacemit/pinctrl-k1.c b/drivers/pinctrl/spacemit/pinctrl-k1.c
index 454bc307ba3..c5e71e902b4 100644
--- a/drivers/pinctrl/spacemit/pinctrl-k1.c
+++ b/drivers/pinctrl/spacemit/pinctrl-k1.c
@@ -13,6 +13,8 @@
 #include <linux/bitops.h>
 #include <linux/errno.h>
 #include <linux/io.h>
+#include <regmap.h>
+#include <syscon.h>
 
 /*
  * +---------+----------+-----------+--------+--------+----------+--------+
@@ -35,8 +37,23 @@
 #define PAD_PULLUP		BIT(14)
 #define PAD_PULL_EN		BIT(15)
 
-#define PIN_POWER_STATE_1V8		1800
-#define PIN_POWER_STATE_3V3		3300
+#define IO_PWR_DOMAIN_OFFSET	0x800
+
+#define IO_PWR_DOMAIN_GPIO2_Kx	0x0c
+#define IO_PWR_DOMAIN_GPIO3_K1	0x10
+#define IO_PWR_DOMAIN_MMC_Kx	0x1c
+#define IO_PWR_DOMAIN_QSPI_K1	0x20
+
+#define IO_PWR_DOMAIN_V18EN	BIT(2)
+
+#define APBC_ASFAR		0x50
+#define APBC_ASSAR		0x54
+
+#define APBC_ASFAR_AKEY		0xbaba
+#define APBC_ASSAR_AKEY		0xeb10
+
+#define PIN_POWER_STATE_1V8	1800
+#define PIN_POWER_STATE_3V3	3300
 
 enum spacemit_pin_io_type {
 	IO_TYPE_NONE = 0,
@@ -61,12 +78,14 @@ struct spacemit_pinctrl_data {
 	int (*get_pins)(struct udevice *dev);
 	int (*get_functions)(struct udevice *dev);
 	int (*get_io_type)(struct udevice *dev, unsigned int pin);
+	unsigned int (*pin_to_io_pd_offset)(unsigned int pin);
 };
 
 struct spacemit_pinctrl_priv {
 	void __iomem		*regs;
 	struct spacemit_pin_io	*io_pins;
 	int			nr_io_pins;
+	struct regmap		*regmap;
 };
 
 struct spacemit_pin_mux_config {
@@ -197,6 +216,28 @@ static int k1_get_io_type(struct udevice *dev, unsigned int selector)
 	return -EINVAL;
 }
 
+static unsigned int spacemit_k1_pin_to_io_pd_offset(unsigned int pin)
+{
+	unsigned int offset = 0;
+
+	switch (pin) {
+	case 47 ... 52:
+		offset = IO_PWR_DOMAIN_GPIO3_K1;
+		break;
+	case 75 ... 80:
+		offset = IO_PWR_DOMAIN_GPIO2_Kx;
+		break;
+	case 98 ... 103:
+		offset = IO_PWR_DOMAIN_QSPI_K1;
+		break;
+	case 104 ... 109:
+		offset = IO_PWR_DOMAIN_MMC_Kx;
+		break;
+	}
+
+	return offset;
+}
+
 /* use IO high level output current as the table */
 static struct spacemit_pin_drv_strength spacemit_ds_1v8_tbl[4] = {
 	{ 0, 11 },
@@ -403,6 +444,35 @@ static const struct pinconf_param spacemit_pinconf_params[] = {
 	{ "power-source",	PIN_CONFIG_POWER_SOURCE,	U32_MAX },
 };
 
+static void spacemit_set_io_power_domain(struct udevice *dev,
+					 unsigned int pin,
+					 unsigned int io_type)
+{
+	struct spacemit_pinctrl_priv *priv = dev_get_priv(dev);
+	struct spacemit_pinctrl_data *data;
+	unsigned int offset;
+	u32 val = 0;
+
+	if (!priv->regmap)
+		return;
+
+	data = (struct spacemit_pinctrl_data *)dev_get_driver_data(dev);
+	if (!data || !data->pin_to_io_pd_offset)
+		return;
+
+	offset = data->pin_to_io_pd_offset(pin);
+	if (!offset)
+		return;
+
+	if (io_type == IO_TYPE_1V8)
+		val = IO_PWR_DOMAIN_V18EN;
+
+	regmap_write(priv->regmap, APBC_ASFAR, APBC_ASFAR_AKEY);
+	regmap_write(priv->regmap, APBC_ASSAR, APBC_ASSAR_AKEY);
+
+	writel(val, priv->regs + IO_PWR_DOMAIN_OFFSET + offset);
+}
+
 static int spacemit_pinconf_set(struct udevice *dev, unsigned int pin_selector,
 				unsigned int param, unsigned int argument)
 {
@@ -418,6 +488,7 @@ static int spacemit_pinconf_set(struct udevice *dev, unsigned int pin_selector,
 	data = (struct spacemit_pinctrl_data *)dev_get_driver_data(dev);
 	if (!data || !data->pin_to_reg)
 		return -EINVAL;
+
 	addr = data->pin_to_reg(dev, pin_selector);
 	switch (param) {
 	case PIN_CONFIG_BIAS_DISABLE:
@@ -466,10 +537,14 @@ static int spacemit_pinconf_set(struct udevice *dev, unsigned int pin_selector,
 			}
 			break;
 		}
-		if (!found && argument != PIN_POWER_STATE_1V8) {
+		if (!found && argument != PIN_POWER_STATE_1V8 &&
+		    argument != PIN_POWER_STATE_3V3) {
 			dev_err(dev, "Invalid power source (%d)\n", argument);
 			return -EINVAL;
 		}
+		if (found)
+			spacemit_set_io_power_domain(dev, pin_selector,
+						     priv->io_pins[i].io_type);
 		break;
 	default:
 		return -EOPNOTSUPP;
@@ -482,6 +557,7 @@ static int spacemit_pinctrl_probe(struct udevice *dev)
 	struct spacemit_pinctrl_data *data;
 	struct spacemit_pinctrl_priv *priv;
 	struct clk_bulk clks;
+	struct ofnode_phandle_args args;
 	size_t size;
 	int ret;
 
@@ -499,6 +575,19 @@ static int spacemit_pinctrl_probe(struct udevice *dev)
 		dev_err(dev, "Fail to allocate memory\n");
 		return -ENOMEM;
 	}
+	ret = dev_read_phandle_with_args(dev, "spacemit,apbc",
+					 NULL, 0, 0, &args);
+	if (ret) {
+		dev_warn(dev, "no APBC phandle found, disable IO power domain switching\n");
+		priv->regmap = NULL;
+	} else {
+		ret = regmap_init_mem(args.node, &priv->regmap);
+		if (ret) {
+			dev_warn(dev, "failed to get APBC regmap,"
+				 " disable IO power domain switching\n");
+			priv->regmap = NULL;
+		}
+	}
 
 	ret = clk_get_bulk(dev, &clks);
 	if (ret) {
@@ -526,6 +615,7 @@ static const struct spacemit_pinctrl_data k1_pinctrl_data = {
 	.get_pins	= k1_get_pins,
 	.get_functions	= k1_get_functions,
 	.get_io_type	= k1_get_io_type,
+	.pin_to_io_pd_offset = spacemit_k1_pin_to_io_pd_offset,
 };
 
 static const struct udevice_id spacemit_pinctrl_ids[] = {

-- 
2.51.0


  parent reply	other threads:[~2026-07-27  6:59 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-27  6:59 [PATCH v6 00/11] spacemit mmc driver Eric Chung
2026-07-27  6:59 ` [PATCH v6 01/11] spacemit: k1: select boot device via config registers Eric Chung
2026-07-27  6:59 ` [PATCH v6 02/11] pinctrl: k1: fix drive strength configuration Eric Chung
2026-07-27  6:59 ` [PATCH v6 03/11] pinctrl: k1: fix pull-up/pull-down configuration Eric Chung
2026-07-27  8:20   ` Yao Zi
2026-07-27  8:24     ` Yao Zi
2026-07-27  6:59 ` Eric Chung [this message]
2026-07-28 17:15   ` [PATCH v6 04/11] pinctrl: k1: add IO power domain configuration support Junhui Liu
2026-07-27  6:59 ` [PATCH v6 05/11] mmc: k1: add sdhci platform driver Eric Chung
2026-07-27  6:59 ` [PATCH v6 06/11] dts: k1: add SD card support in u-boot overlay Eric Chung
2026-07-27 11:51   ` Yao Zi
2026-07-27 13:08     ` Eric Chung
2026-07-27 17:07       ` Yao Zi
2026-07-28  1:04         ` Eric Chung
2026-07-28  9:10           ` Yao Zi
2026-07-29 14:05             ` Eric Chung
2026-07-29 15:58               ` Yao Zi
2026-07-30  5:18                 ` Eric Chung
2026-07-27  6:59 ` [PATCH v6 07/11] configs: k1: enable SD and eMMC support Eric Chung
2026-07-27 17:15   ` Yao Zi
2026-07-27  6:59 ` [PATCH v6 08/11] MAINTAINER: update Spacemit K1 entry Eric Chung
2026-07-27  6:59 ` [PATCH v6 09/11] doc: spacemit: flash on K1 SoC based boards Eric Chung
2026-07-27 17:26   ` Yao Zi
2026-07-28  0:53     ` Eric Chung
2026-07-28  9:45       ` Yao Zi
2026-07-29 13:49         ` Eric Chung
2026-07-29 15:32           ` Yao Zi
2026-07-30  6:25             ` Eric Chung
2026-07-30 15:20               ` Yao Zi
2026-07-31  0:31                 ` Eric Chung
2026-07-27  6:59 ` [PATCH v6 10/11] config: k1: enable ENV support for eMMC Eric Chung
2026-07-27  6:59 ` [PATCH v6 11/11] spacemit: k1: load product name from environment variable Eric Chung
2026-07-27 17:41   ` Yao Zi

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=20260727-m4-v6-4-2f58566d48ca@riscstar.com \
    --to=eric.chung@riscstar.com \
    --cc=angelo@kernel-space.org \
    --cc=anshuld@ti.com \
    --cc=balsundar.ponnusamy@altera.com \
    --cc=bastien.curutchet@bootlin.com \
    --cc=bhimeswararao.matsa@gmail.com \
    --cc=c.stoidner@phytec.de \
    --cc=daniel@thingy.jp \
    --cc=guodong@riscstar.com \
    --cc=han.xu@nxp.com \
    --cc=jbx6244@gmail.com \
    --cc=jh80.chung@samsung.com \
    --cc=kauschluss@disroot.org \
    --cc=leo.liang@sifive.com \
    --cc=me@ziyao.cc \
    --cc=peng.fan@nxp.com \
    --cc=pericycle.cc@gmail.com \
    --cc=raymond.mao@riscstar.com \
    --cc=rick@andestech.com \
    --cc=semen.protsenko@linaro.org \
    --cc=tanmay.kathpalia@altera.com \
    --cc=tim609@andestech.com \
    --cc=trini@konsulko.com \
    --cc=u-boot-spacemit@groups.io \
    --cc=u-boot@lists.u-boot-project.org \
    --cc=yanir.levin@tandemg.com \
    --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.