U-Boot Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: E Shattow <e@freeshell.de>
To: Yixun Lan <dlan@kernel.org>, u-boot@lists.u-boot-project.org
Cc: Eric Chung <eric.chung@riscstar.com>,
	Raymond Mao <raymond.mao@riscstar.com>,
	Junhui Liu <junhui.liu@pigmoral.tech>,
	Tom Rini <trini@konsulko.com>
Subject: Re: [PATCH v2 2/2] pinctrl: spacemit: k3: add K3 pin support
Date: Wed, 7 Oct 2026 02:12:03 -0700	[thread overview]
Message-ID: <5fa4e2df-d0c5-4404-a29d-eded3cb72eb3@freeshell.de> (raw)
In-Reply-To: <20260923-01-k3-pinctrl-support-v2-2-e76a917ee252@kernel.org>

On 9/23/26 06:06, Yixun Lan wrote:
> Based on upstream Linux:
>   7412311c4655 ("pinctrl: spacemit: k3: add initial pin support")
>   3f20bdf71518 ("pinctrl: spacemit: k3: adjust drive strength and schmitter trigger")
> 
> K3 uses a different pin-to-register mapping than K1, so add a
> K3-specific pin_to_reg path and pin/IO power-domain tables. Drive
> strength expands to 4 bits with larger mA tables, and the shared
> pinctrl data gains per-SoC drive_mask and drive-strength tables so
> K1 and K3 can live in the same driver.
> 
> Signed-off-by: Yixun Lan <dlan@kernel.org>
> ---
>  drivers/pinctrl/spacemit/Kconfig      |   4 +-
>  drivers/pinctrl/spacemit/pinctrl-k1.c | 291 ++++++++++++++++++++++++++++++----
>  2 files changed, 259 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/pinctrl/spacemit/Kconfig b/drivers/pinctrl/spacemit/Kconfig
> index 6aab89e160c..87cba336923 100644
> --- a/drivers/pinctrl/spacemit/Kconfig
> +++ b/drivers/pinctrl/spacemit/Kconfig
> @@ -1,8 +1,8 @@
>  config PINCTRL_SPACEMIT_K1
> -	bool "Spacemit K1 SoC pinctrl driver"
> +	bool "Spacemit K1/K3 SoC pinctrl driver"
>  	depends on PINCTRL_GENERIC && DM
>  	help
> -	  Supports pin multiplexing control on Spacemit K1 SoCs.
> +	  Supports pin multiplexing control on Spacemit K1 and K3 SoCs.
>  
>  	  The driver is controlled by a device tree node which contains both
>  	  the GPIO definitions and pin control functions for each available
> diff --git a/drivers/pinctrl/spacemit/pinctrl-k1.c b/drivers/pinctrl/spacemit/pinctrl-k1.c
> index ff0fa3a4b18..002878862dc 100644
> --- a/drivers/pinctrl/spacemit/pinctrl-k1.c
> +++ b/drivers/pinctrl/spacemit/pinctrl-k1.c
> @@ -30,8 +30,10 @@
>  #define PAD_EDGE_CLEAR		BIT(6)
>  #define PAD_SLEW_RATE		GENMASK(12, 11)
>  #define PAD_SLEW_RATE_EN	BIT(7)
> -#define PAD_SCHMITT		GENMASK(9, 8)
> -#define PAD_DRIVE		GENMASK(12, 10)
> +#define PAD_SCHMITT_K1		GENMASK(9, 8)
> +#define PAD_DRIVE_K1		GENMASK(12, 10)
> +#define PAD_SCHMITT_K3		BIT(8)
> +#define PAD_DRIVE_K3		GENMASK(12, 9)
>  #define PAD_PULLDOWN		BIT(13)
>  #define PAD_PULLUP		BIT(14)
>  #define PAD_PULL_EN		BIT(15)
> @@ -43,6 +45,11 @@
>  #define IO_PWR_DOMAIN_MMC_Kx	0x1c
>  #define IO_PWR_DOMAIN_QSPI_K1	0x20
>  
> +#define IO_PWR_DOMAIN_GPIO1_K3  0x04
> +#define IO_PWR_DOMAIN_GPIO5_K3  0x10
> +#define IO_PWR_DOMAIN_GPIO4_K3  0x20
> +#define IO_PWR_DOMAIN_QSPI_K3   0x2c
> +
>  #define IO_PWR_DOMAIN_V18EN	BIT(2)
>  
>  #define APBC_ASFAR		0x50
> @@ -68,6 +75,12 @@ struct spacemit_pin_io {
>  	unsigned int	reserved : 8;
>  };
>  
> +struct spacemit_pin_drv_strength {
> +	unsigned int	val : 8;
> +	unsigned int	ma : 16;
> +	unsigned int	reserved : 8;
> +};
> +
>  struct spacemit_pinctrl_data {
>  	struct spacemit_pin_io *io_pins;
>  	int nr_io_pins;
> @@ -78,6 +91,12 @@ struct spacemit_pinctrl_data {
>  	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);
> +
> +	u32 drive_mask;
> +	struct spacemit_pin_drv_strength *ds_1v8_tbl;
> +	int ds_1v8_tbl_num;
> +	struct spacemit_pin_drv_strength *ds_3v3_tbl;
> +	int ds_3v3_tbl_num;
>  };
>  
>  struct spacemit_pinctrl_priv {
> @@ -92,12 +111,6 @@ struct spacemit_pin_mux_config {
>  	u32				config;
>  };
>  
> -struct spacemit_pin_drv_strength {
> -	unsigned int	val : 8;
> -	unsigned int	ma : 16;
> -	unsigned int	reserved : 8;
> -};
> -
>  static char pin_name[PINNAME_SIZE];
>  
>  /* External: IO voltage via external source, can be 1.8V or 3.3V */
> @@ -280,35 +293,17 @@ static inline u32 spacemit_get_ds_ma(struct spacemit_pin_drv_strength *tbl,
>  	return 0;
>  }
>  
> -static inline u8 spacemit_get_drive_strength(enum spacemit_pin_io_type type,
> +static inline u8 spacemit_get_drive_strength(struct spacemit_pinctrl_data *data,
> +					     enum spacemit_pin_io_type type,
>  					     u32 ma)
>  {
>  	switch (type) {
>  	case IO_TYPE_1V8:
> -		return spacemit_get_ds_value(spacemit_ds_1v8_tbl,
> -					     ARRAY_SIZE(spacemit_ds_1v8_tbl),
> -					     ma);
> -	case IO_TYPE_3V3:
> -		return spacemit_get_ds_value(spacemit_ds_3v3_tbl,
> -					     ARRAY_SIZE(spacemit_ds_3v3_tbl),
> -					     ma);
> -	default:
> -		return 0;
> -	}
> -}
> -
> -static inline u32 spacemit_get_drive_strength_ma(enum spacemit_pin_io_type type,
> -						 u32 value)
> -{
> -	switch (type) {
> -	case IO_TYPE_1V8:
> -		return spacemit_get_ds_ma(spacemit_ds_1v8_tbl,
> -					  ARRAY_SIZE(spacemit_ds_1v8_tbl),
> -					  value & 0x6);
> +		return spacemit_get_ds_value(data->ds_1v8_tbl,
> +					     data->ds_1v8_tbl_num, ma);
>  	case IO_TYPE_3V3:
> -		return spacemit_get_ds_ma(spacemit_ds_3v3_tbl,
> -					  ARRAY_SIZE(spacemit_ds_3v3_tbl),
> -					  value);
> +		return spacemit_get_ds_value(data->ds_3v3_tbl,
> +					     data->ds_3v3_tbl_num, ma);
>  	default:
>  		return 0;
>  	}
> @@ -552,8 +547,9 @@ static int spacemit_pinconf_set(struct udevice *dev, unsigned int pin_selector,
>  			dev_err(dev, "Invalid IO type (%d)\n", io_type);
>  			return -EINVAL;
>  		}
> -		ds = spacemit_get_drive_strength(io_type, argument);
> -		clrsetbits_le32(addr, PAD_DRIVE, FIELD_PREP(PAD_DRIVE, ds));
> +		ds = spacemit_get_drive_strength(data, io_type, argument);
> +		clrsetbits_le32(addr, data->drive_mask,
> +				field_prep(data->drive_mask, ds));
>  		break;
>  	case PIN_CONFIG_POWER_SOURCE:
>  		return spacemit_set_pin_power_source(dev, pin_selector, argument);
> @@ -707,12 +703,239 @@ static const struct spacemit_pinctrl_data k1_pinctrl_data = {
>  	.get_functions	= k1_get_functions,
>  	.get_io_type	= k1_get_io_type,
>  	.pin_to_io_pd_offset = spacemit_k1_pin_to_io_pd_offset,
> +	.drive_mask	= PAD_DRIVE_K1,
> +	.ds_1v8_tbl	= spacemit_ds_1v8_tbl,
> +	.ds_1v8_tbl_num	= ARRAY_SIZE(spacemit_ds_1v8_tbl),
> +	.ds_3v3_tbl	= spacemit_ds_3v3_tbl,
> +	.ds_3v3_tbl_num	= ARRAY_SIZE(spacemit_ds_3v3_tbl),
> +};
> +
> +static struct spacemit_pin_io k3_io_pins[] = {
> +	{ 0, IO_TYPE_EXTERNAL, 0, },
> +	{ 1, IO_TYPE_EXTERNAL, 0, },
> +	{ 2, IO_TYPE_EXTERNAL, 0, },
> +	{ 3, IO_TYPE_EXTERNAL, 0, },
> +	{ 4, IO_TYPE_EXTERNAL, 0, },
> +	{ 5, IO_TYPE_EXTERNAL, 0, },
> +	{ 6, IO_TYPE_EXTERNAL, 0, },
> +	{ 7, IO_TYPE_EXTERNAL, 0, },
> +	{ 8, IO_TYPE_EXTERNAL, 0, },
> +	{ 9, IO_TYPE_EXTERNAL, 0, },
> +	{ 10, IO_TYPE_EXTERNAL, 0, },
> +	{ 11, IO_TYPE_EXTERNAL, 0, },
> +	{ 12, IO_TYPE_EXTERNAL, 0, },
> +	{ 13, IO_TYPE_EXTERNAL, 0, },
> +	{ 14, IO_TYPE_EXTERNAL, 0, },
> +	{ 15, IO_TYPE_EXTERNAL, 0, },
> +	{ 16, IO_TYPE_EXTERNAL, 0, },
> +	{ 17, IO_TYPE_EXTERNAL, 0, },
> +	{ 18, IO_TYPE_EXTERNAL, 0, },
> +	{ 19, IO_TYPE_EXTERNAL, 0, },
> +	{ 20, IO_TYPE_EXTERNAL, 0, },
> +	{ 21, IO_TYPE_EXTERNAL, 0, },
> +	{ 22, IO_TYPE_EXTERNAL, 0, },
> +	{ 23, IO_TYPE_EXTERNAL, 0, },
> +	{ 24, IO_TYPE_EXTERNAL, 0, },
> +	{ 25, IO_TYPE_EXTERNAL, 0, },
> +	{ 26, IO_TYPE_EXTERNAL, 0, },
> +	{ 27, IO_TYPE_EXTERNAL, 0, },
> +	{ 28, IO_TYPE_EXTERNAL, 0, },
> +	{ 29, IO_TYPE_EXTERNAL, 0, },
> +	{ 30, IO_TYPE_EXTERNAL, 0, },
> +	{ 31, IO_TYPE_EXTERNAL, 0, },
> +	{ 32, IO_TYPE_EXTERNAL, 0, },
> +	{ 33, IO_TYPE_EXTERNAL, 0, },
> +	{ 34, IO_TYPE_EXTERNAL, 0, },
> +	{ 35, IO_TYPE_EXTERNAL, 0, },
> +	{ 36, IO_TYPE_EXTERNAL, 0, },
> +	{ 37, IO_TYPE_EXTERNAL, 0, },
> +	{ 38, IO_TYPE_EXTERNAL, 0, },
> +	{ 39, IO_TYPE_EXTERNAL, 0, },
> +	{ 40, IO_TYPE_EXTERNAL, 0, },
> +	{ 41, IO_TYPE_EXTERNAL, 0, },
> +	{ 76, IO_TYPE_EXTERNAL, 0, },
> +	{ 77, IO_TYPE_EXTERNAL, 0, },
> +	{ 78, IO_TYPE_EXTERNAL, 0, },
> +	{ 79, IO_TYPE_EXTERNAL, 0, },
> +	{ 80, IO_TYPE_EXTERNAL, 0, },
> +	{ 81, IO_TYPE_EXTERNAL, 0, },
> +	{ 82, IO_TYPE_EXTERNAL, 0, },
> +	{ 83, IO_TYPE_EXTERNAL, 0, },
> +	{ 84, IO_TYPE_EXTERNAL, 0, },
> +	{ 85, IO_TYPE_EXTERNAL, 0, },
> +	{ 86, IO_TYPE_EXTERNAL, 0, },
> +	{ 87, IO_TYPE_EXTERNAL, 0, },
> +	{ 88, IO_TYPE_EXTERNAL, 0, },
> +	{ 89, IO_TYPE_EXTERNAL, 0, },
> +	{ 90, IO_TYPE_EXTERNAL, 0, },
> +	{ 91, IO_TYPE_EXTERNAL, 0, },
> +	{ 92, IO_TYPE_EXTERNAL, 0, },
> +	{ 93, IO_TYPE_EXTERNAL, 0, },
> +	{ 94, IO_TYPE_EXTERNAL, 0, },
> +	{ 95, IO_TYPE_EXTERNAL, 0, },
> +	{ 96, IO_TYPE_EXTERNAL, 0, },
> +	{ 97, IO_TYPE_EXTERNAL, 0, },
> +	{ 98, IO_TYPE_EXTERNAL, 0, },
> +	{ 99, IO_TYPE_EXTERNAL, 0, },
> +	{ 100, IO_TYPE_EXTERNAL, 0, },
> +	{ 101, IO_TYPE_EXTERNAL, 0, },
> +	{ 102, IO_TYPE_EXTERNAL, 0, },
> +	{ 103, IO_TYPE_EXTERNAL, 0, },
> +	{ 104, IO_TYPE_EXTERNAL, 0, },
> +	{ 105, IO_TYPE_EXTERNAL, 0, },
> +	{ 106, IO_TYPE_EXTERNAL, 0, },
> +	{ 107, IO_TYPE_EXTERNAL, 0, },
> +	{ 108, IO_TYPE_EXTERNAL, 0, },
> +	{ 109, IO_TYPE_EXTERNAL, 0, },
> +	{ 110, IO_TYPE_EXTERNAL, 0, },
> +	{ 111, IO_TYPE_EXTERNAL, 0, },
> +	{ 112, IO_TYPE_EXTERNAL, 0, },
> +	{ 113, IO_TYPE_EXTERNAL, 0, },
> +	{ 114, IO_TYPE_EXTERNAL, 0, },
> +	{ 115, IO_TYPE_EXTERNAL, 0, },
> +	{ 116, IO_TYPE_EXTERNAL, 0, },
> +	{ 117, IO_TYPE_EXTERNAL, 0, },
> +	{ 118, IO_TYPE_EXTERNAL, 0, },
> +	{ 119, IO_TYPE_EXTERNAL, 0, },
> +	{ 120, IO_TYPE_EXTERNAL, 0, },
> +	{ 121, IO_TYPE_EXTERNAL, 0, },
> +	{ 122, IO_TYPE_EXTERNAL, 0, },
> +	{ 123, IO_TYPE_EXTERNAL, 0, },
> +	{ 124, IO_TYPE_EXTERNAL, 0, },
> +	{ 125, IO_TYPE_EXTERNAL, 0, },
> +	{ 126, IO_TYPE_EXTERNAL, 0, },
> +	{ 127, IO_TYPE_EXTERNAL, 0, },
> +	{ 132, IO_TYPE_EXTERNAL, 0, },
> +	{ 133, IO_TYPE_EXTERNAL, 0, },
> +	{ 134, IO_TYPE_EXTERNAL, 0, },
> +	{ 135, IO_TYPE_EXTERNAL, 0, },
> +	{ 136, IO_TYPE_EXTERNAL, 0, },
> +	{ 137, IO_TYPE_EXTERNAL, 0, },
> +	{ 138, IO_TYPE_EXTERNAL, 0, },
> +	{ 139, IO_TYPE_EXTERNAL, 0, },
> +	{ 140, IO_TYPE_EXTERNAL, 0, },
> +	{ 141, IO_TYPE_EXTERNAL, 0, },
> +	{ 142, IO_TYPE_EXTERNAL, 0, },
> +	{ 143, IO_TYPE_EXTERNAL, 0, },
> +	{ 144, IO_TYPE_EXTERNAL, 0, },
> +};
> +
> +static inline int k3_get_pins(struct udevice *dev)
> +{
> +	return 153;
> +}
> +
> +static inline int k3_get_functions(struct udevice *dev)
> +{
> +	return 7;
> +}
> +
> +static void __iomem *k3_pin_to_reg(struct udevice *dev, unsigned int pin)
> +{
> +	struct spacemit_pinctrl_priv *priv = dev_get_priv(dev);
> +	unsigned int offset = pin > 130 ? (pin + 2) : pin;
> +
> +	if (pin > 152) {
> +		dev_err(dev, "Invalid pin (%u)\n", pin);
> +		return NULL;
> +	}
> +	return priv->regs + (offset << 2);
> +}
> +
> +static int k3_get_gpio_mux(struct udevice *dev, unsigned int selector)
> +{
> +	if (selector > 152) {
> +		dev_err(dev, "Invalid pin (%u)\n", selector);
> +		return -EINVAL;
> +	}
> +	/* SD/MMC1, QSPI, PMIC/JTAG use gpiofunc 1 per Linux pin data */
> +	if (selector >= 132)
> +		return 1;
> +	return 0;
> +}
> +
> +static int k3_get_io_type(struct udevice *dev, unsigned int selector)
> +{
> +	if (selector <= 41)
> +		return IO_TYPE_EXTERNAL;
> +	if (selector <= 75)
> +		return IO_TYPE_1V8;
> +	if (selector <= 127)
> +		return IO_TYPE_EXTERNAL;
> +	if (selector <= 131)
> +		return IO_TYPE_1V8;
> +	if (selector <= 144)
> +		return IO_TYPE_EXTERNAL;
> +	if (selector <= 152)
> +		return IO_TYPE_1V8;
> +	return -EINVAL;
> +}
> +
> +static unsigned int spacemit_k3_pin_to_io_pd_offset(unsigned int pin)
> +{
> +	unsigned int offset = 0;
> +
> +	switch (pin) {
> +	case 0 ... 20:
> +		offset = IO_PWR_DOMAIN_GPIO1_K3;
> +		break;
> +	case 21 ... 41:
> +		offset = IO_PWR_DOMAIN_GPIO2_Kx;
> +		break;
> +	case 76 ... 98:
> +		offset = IO_PWR_DOMAIN_GPIO4_K3;
> +		break;
> +	case 99 ... 127:
> +		offset = IO_PWR_DOMAIN_GPIO5_K3;
> +		break;
> +	case 132 ... 137:
> +		offset = IO_PWR_DOMAIN_MMC_Kx;
> +		break;
> +	case 138 ... 144:
> +		offset = IO_PWR_DOMAIN_QSPI_K3;
> +		break;
> +	}
> +
> +	return offset;
> +}
> +
> +static struct spacemit_pin_drv_strength spacemit_k3_ds_1v8_tbl[16] = {
> +	{ 0,  2 }, { 1,  4 }, { 2,  6 }, { 3,  7 },
> +	{ 4,  9 }, { 5, 11 }, { 6, 13 }, { 7, 14 },
> +	{ 8, 21 }, { 9, 23 }, { 10, 25 }, { 11, 26 },
> +	{ 12, 28 }, { 13, 30 }, { 14, 31 }, { 15, 33 },
> +};
> +
> +static struct spacemit_pin_drv_strength spacemit_k3_ds_3v3_tbl[16] = {
> +	{ 0,  3 }, { 1,  5 }, { 2,  7 }, { 3,  9 },
> +	{ 4, 11 }, { 5, 13 }, { 6, 15 }, { 7, 17 },
> +	{ 8, 25 }, { 9, 27 }, { 10, 29 }, { 11, 31 },
> +	{ 12, 33 }, { 13, 35 }, { 14, 37 }, { 15, 38 },
> +};
> +
> +static const struct spacemit_pinctrl_data k3_pinctrl_data = {
> +	.io_pins	= k3_io_pins,
> +	.nr_io_pins	= ARRAY_SIZE(k3_io_pins),
> +	.pin_to_reg	= k3_pin_to_reg,
> +	.get_gpio_mux	= k3_get_gpio_mux,
> +	.get_pins	= k3_get_pins,
> +	.get_functions	= k3_get_functions,
> +	.get_io_type	= k3_get_io_type,
> +	.pin_to_io_pd_offset = spacemit_k3_pin_to_io_pd_offset,
> +	.drive_mask	= PAD_DRIVE_K3,
> +	.ds_1v8_tbl	= spacemit_k3_ds_1v8_tbl,
> +	.ds_1v8_tbl_num	= ARRAY_SIZE(spacemit_k3_ds_1v8_tbl),
> +	.ds_3v3_tbl	= spacemit_k3_ds_3v3_tbl,
> +	.ds_3v3_tbl_num	= ARRAY_SIZE(spacemit_k3_ds_3v3_tbl),
>  };
>  
>  static const struct udevice_id spacemit_pinctrl_ids[] = {
>  	{
>  		.compatible = "spacemit,k1-pinctrl",
>  		.data = (uintptr_t)&k1_pinctrl_data,
> +	}, {
> +		.compatible = "spacemit,k3-pinctrl",
> +		.data = (uintptr_t)&k3_pinctrl_data,
>  	}, { /* sentinel */ }
>  };
>  
> 

Acked-by: E Shattow <e@freeshell.de>

  reply	other threads:[~2026-10-07  9:15 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-23 13:06 [PATCH v2 0/2] riscv: spacemit: add pinctrl support for K3 SoC Yixun Lan
2026-09-23 13:06 ` [PATCH v2 1/2] pinctrl: spacemit: configure drive strength based on power source Yixun Lan
2026-09-23 13:06 ` [PATCH v2 2/2] pinctrl: spacemit: k3: add K3 pin support Yixun Lan
2026-10-07  9:12   ` E Shattow [this message]
2026-09-29 10:12 ` (subset) [PATCH v2 0/2] riscv: spacemit: add pinctrl support for K3 SoC Yixun Lan
2026-10-09  7:24 ` Yixun Lan

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=5fa4e2df-d0c5-4404-a29d-eded3cb72eb3@freeshell.de \
    --to=e@freeshell.de \
    --cc=dlan@kernel.org \
    --cc=eric.chung@riscstar.com \
    --cc=junhui.liu@pigmoral.tech \
    --cc=raymond.mao@riscstar.com \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.u-boot-project.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox