* [PATCH 0/2] pinctrl: fix on Spacemit K1 SoC
@ 2026-08-24 8:13 Eric Chung
2026-08-24 8:13 ` [PATCH 1/2] pinctrl: k1: fix drive strength configuration Eric Chung
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Eric Chung @ 2026-08-24 8:13 UTC (permalink / raw)
To: u-boot-spacemit, u-boot, u-boot
Cc: Tim Ouyang, Leo Liang, Yao Zi, Huan Zhou, Tom Rini, Eric Chung,
Raymond Mao, Yixun Lan
- Add IO power domain control register programming via APBC block with
ASAR unlocking for dual-voltage GPIO banks (3.3V/1.8V switching)
- Fix drive strength configuration: use FIELD_PREP(), preserve io_type,
return correct pin number, and remove redundant initialization
Signed-off-by: Eric Chung <eric.chung@riscstar.com>
---
Eric Chung (2):
pinctrl: k1: fix drive strength configuration
pinctrl: k1: add IO power domain configuration support
drivers/pinctrl/spacemit/pinctrl-k1.c | 107 +++++++++++++++++++++++++++++++---
1 file changed, 100 insertions(+), 7 deletions(-)
---
base-commit: 6073c36b2c8d39afe3ecc789b281667a3ddebc70
change-id: 20260824-pinctrl-718fe50eb9f8
Best regards,
--
Eric Chung <eric.chung@riscstar.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2] pinctrl: k1: fix drive strength configuration
2026-08-24 8:13 [PATCH 0/2] pinctrl: fix on Spacemit K1 SoC Eric Chung
@ 2026-08-24 8:13 ` Eric Chung
2026-08-24 8:14 ` [PATCH 2/2] pinctrl: k1: add IO power domain configuration support Eric Chung
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Eric Chung @ 2026-08-24 8:13 UTC (permalink / raw)
To: u-boot-spacemit, u-boot, u-boot
Cc: Tim Ouyang, Leo Liang, Yao Zi, Huan Zhou, Tom Rini, Eric Chung,
Raymond Mao, Yixun Lan
Fix drive strength configuration by:
- Using FIELD_PREP() to properly set the PAD_DRIVE mask bits
- Not overriding io_type with IO_TYPE_EXTERNAL for external pins
- Returning the pin number instead of 0 from pinmux_property_set
- Removing redundant zero-initialization of the mask variable
Signed-off-by: Eric Chung <eric.chung@riscstar.com>
---
drivers/pinctrl/spacemit/pinctrl-k1.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/pinctrl/spacemit/pinctrl-k1.c b/drivers/pinctrl/spacemit/pinctrl-k1.c
index a6a22eacac7b..6ed511879daf 100644
--- a/drivers/pinctrl/spacemit/pinctrl-k1.c
+++ b/drivers/pinctrl/spacemit/pinctrl-k1.c
@@ -9,6 +9,7 @@
#include <dm/device_compat.h>
#include <dm/pinctrl.h>
#include <dm/read.h>
+#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/errno.h>
#include <linux/io.h>
@@ -386,10 +387,12 @@ static int spacemit_pinmux_set(struct udevice *dev, unsigned int pin,
static int spacemit_pinmux_property_set(struct udevice *dev, u32 pinmux_group)
{
u32 pin, mux;
+ int ret;
pin = spacemit_dt_get_pin(pinmux_group);
mux = spacemit_dt_get_pin_mux(pinmux_group);
- return spacemit_pinmux_set(dev, pin, mux);
+ ret = spacemit_pinmux_set(dev, pin, mux);
+ return ret ? ret : pin;
}
static const struct pinconf_param spacemit_pinconf_params[] = {
@@ -406,7 +409,7 @@ static int spacemit_pinconf_set(struct udevice *dev, unsigned int pin_selector,
struct spacemit_pinctrl_data *data;
struct spacemit_pinctrl_priv *priv = dev_get_priv(dev);
void __iomem *addr;
- u32 mask = 0;
+ u32 mask;
unsigned int io_type;
u8 ds;
bool found;
@@ -433,7 +436,8 @@ static int spacemit_pinconf_set(struct udevice *dev, unsigned int pin_selector,
for (i = 0; i < priv->nr_io_pins; i++) {
if (priv->io_pins[i].pin != pin_selector)
continue;
- io_type = priv->io_pins[i].io_type;
+ if (priv->io_pins[i].io_type != IO_TYPE_EXTERNAL)
+ io_type = priv->io_pins[i].io_type;
break;
}
if (io_type != IO_TYPE_3V3 && io_type != IO_TYPE_1V8) {
@@ -441,7 +445,7 @@ static int spacemit_pinconf_set(struct udevice *dev, unsigned int pin_selector,
return -EINVAL;
}
ds = spacemit_get_drive_strength(io_type, argument);
- clrsetbits_le32(addr, PAD_DRIVE, ds);
+ clrsetbits_le32(addr, PAD_DRIVE, FIELD_PREP(PAD_DRIVE, ds));
break;
case PIN_CONFIG_POWER_SOURCE:
for (i = 0, found = false; i < priv->nr_io_pins; i++) {
--
2.51.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] pinctrl: k1: add IO power domain configuration support
2026-08-24 8:13 [PATCH 0/2] pinctrl: fix on Spacemit K1 SoC Eric Chung
2026-08-24 8:13 ` [PATCH 1/2] pinctrl: k1: fix drive strength configuration Eric Chung
@ 2026-08-24 8:14 ` Eric Chung
2026-09-02 1:52 ` [PATCH 0/2] pinctrl: fix on Spacemit K1 SoC Eric Chung
2026-09-05 11:36 ` Yixun Lan
3 siblings, 0 replies; 5+ messages in thread
From: Eric Chung @ 2026-08-24 8:14 UTC (permalink / raw)
To: u-boot-spacemit, u-boot, u-boot
Cc: Tim Ouyang, Leo Liang, Yao Zi, Huan Zhou, Tom Rini, Eric Chung,
Raymond Mao, Yixun Lan
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>
---
drivers/pinctrl/spacemit/pinctrl-k1.c | 95 +++++++++++++++++++++++++++++++++--
1 file changed, 92 insertions(+), 3 deletions(-)
diff --git a/drivers/pinctrl/spacemit/pinctrl-k1.c b/drivers/pinctrl/spacemit/pinctrl-k1.c
index 6ed511879daf..ccfe26af310b 100644
--- a/drivers/pinctrl/spacemit/pinctrl-k1.c
+++ b/drivers/pinctrl/spacemit/pinctrl-k1.c
@@ -13,6 +13,7 @@
#include <linux/bitops.h>
#include <linux/errno.h>
#include <linux/io.h>
+#include <regmap.h>
/*
* +---------+----------+-----------+--------+--------+----------+--------+
@@ -35,8 +36,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 +77,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 +215,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 +443,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 +487,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:
@@ -460,10 +530,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;
@@ -476,6 +550,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;
@@ -493,6 +568,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) {
@@ -520,6 +608,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
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 0/2] pinctrl: fix on Spacemit K1 SoC
2026-08-24 8:13 [PATCH 0/2] pinctrl: fix on Spacemit K1 SoC Eric Chung
2026-08-24 8:13 ` [PATCH 1/2] pinctrl: k1: fix drive strength configuration Eric Chung
2026-08-24 8:14 ` [PATCH 2/2] pinctrl: k1: add IO power domain configuration support Eric Chung
@ 2026-09-02 1:52 ` Eric Chung
2026-09-05 11:36 ` Yixun Lan
3 siblings, 0 replies; 5+ messages in thread
From: Eric Chung @ 2026-09-02 1:52 UTC (permalink / raw)
To: u-boot-spacemit, u-boot
Cc: Tim Ouyang, Leo Liang, Yao Zi, Huan Zhou, Tom Rini, Raymond Mao,
Yixun Lan
On Mon, Aug 24, 2026 at 4:14 PM Eric Chung <eric.chung@riscstar.com> wrote:
>
> - Add IO power domain control register programming via APBC block with
> ASAR unlocking for dual-voltage GPIO banks (3.3V/1.8V switching)
> - Fix drive strength configuration: use FIELD_PREP(), preserve io_type,
> return correct pin number, and remove redundant initialization
>
> Signed-off-by: Eric Chung <eric.chung@riscstar.com>
>
> ---
> Eric Chung (2):
> pinctrl: k1: fix drive strength configuration
> pinctrl: k1: add IO power domain configuration support
>
> drivers/pinctrl/spacemit/pinctrl-k1.c | 107 +++++++++++++++++++++++++++++++---
> 1 file changed, 100 insertions(+), 7 deletions(-)
> ---
> base-commit: 6073c36b2c8d39afe3ecc789b281667a3ddebc70
> change-id: 20260824-pinctrl-718fe50eb9f8
>
Hi Tim, Leo & Yao,
Could this patch set be merged now?
> Best regards,
> --
> Eric Chung <eric.chung@riscstar.com>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 0/2] pinctrl: fix on Spacemit K1 SoC
2026-08-24 8:13 [PATCH 0/2] pinctrl: fix on Spacemit K1 SoC Eric Chung
` (2 preceding siblings ...)
2026-09-02 1:52 ` [PATCH 0/2] pinctrl: fix on Spacemit K1 SoC Eric Chung
@ 2026-09-05 11:36 ` Yixun Lan
3 siblings, 0 replies; 5+ messages in thread
From: Yixun Lan @ 2026-09-05 11:36 UTC (permalink / raw)
To: Eric Chung
Cc: u-boot-spacemit, u-boot, Tim Ouyang, Leo Liang, Yao Zi, Huan Zhou,
Tom Rini, Raymond Mao, Yixun Lan
Hi Eric,
On 16:13 Mon 24 Aug , Eric Chung wrote:
> - Add IO power domain control register programming via APBC block with
> ASAR unlocking for dual-voltage GPIO banks (3.3V/1.8V switching)
> - Fix drive strength configuration: use FIELD_PREP(), preserve io_type,
> return correct pin number, and remove redundant initialization
>
You should mention this is split from previous mmc series
I previous have some comments for patch 1 which you missed?
also you lost my review tags, or should explain if not applying the tags
https://lore.kernel.org/all/20260817021216-GKB566872@kernel.org/
https://lore.kernel.org/all/20260817024807-GKC566872@kernel.org/
> Signed-off-by: Eric Chung <eric.chung@riscstar.com>
>
> ---
> Eric Chung (2):
> pinctrl: k1: fix drive strength configuration
> pinctrl: k1: add IO power domain configuration support
>
> drivers/pinctrl/spacemit/pinctrl-k1.c | 107 +++++++++++++++++++++++++++++++---
> 1 file changed, 100 insertions(+), 7 deletions(-)
> ---
> base-commit: 6073c36b2c8d39afe3ecc789b281667a3ddebc70
> change-id: 20260824-pinctrl-718fe50eb9f8
>
> Best regards,
> --
> Eric Chung <eric.chung@riscstar.com>
>
--
Yixun Lan (dlan)
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-05 11:36 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-24 8:13 [PATCH 0/2] pinctrl: fix on Spacemit K1 SoC Eric Chung
2026-08-24 8:13 ` [PATCH 1/2] pinctrl: k1: fix drive strength configuration Eric Chung
2026-08-24 8:14 ` [PATCH 2/2] pinctrl: k1: add IO power domain configuration support Eric Chung
2026-09-02 1:52 ` [PATCH 0/2] pinctrl: fix on Spacemit K1 SoC Eric Chung
2026-09-05 11:36 ` Yixun Lan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox