[PATCH v3 03/17] pinctrl: nxp: add SCMI pin control protocol driver

Marek Vasut marex at denx.de
Sun Jan 5 22:05:28 CET 2025


On 1/3/25 7:45 AM, Alice Guo wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> This patch provides a driver for the SCMI pin control protocol which is
> based on ARM's System Control and Management Interface (SCMI) 3.2.
> Currently, only the PINCTRL_CONFIG_SET command is implemented.

What is the SCMI provider for this platform ?

> diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c
> index 8c907c3b0328095c4b35ba089ed608fcda48b567..5f101f4ede8b585f8c562a42886ea7be4ef09953 100644
> --- a/drivers/firmware/scmi/scmi_agent-uclass.c
> +++ b/drivers/firmware/scmi/scmi_agent-uclass.c
> @@ -97,6 +97,9 @@ struct udevice *scmi_get_protocol(struct udevice *dev,
>   	case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN:
>   		proto = priv->voltagedom_dev;
>   		break;
> +	case SCMI_PROTOCOL_ID_PINCTRL:
> +		proto = priv->pinctrl_dev;
> +		break;
>   	default:
>   		dev_err(dev, "Protocol not supported\n");
>   		proto = NULL;
> @@ -147,6 +150,9 @@ static int scmi_add_protocol(struct udevice *dev,
>   	case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN:
>   		priv->voltagedom_dev = proto;
>   		break;
> +	case SCMI_PROTOCOL_ID_PINCTRL:
> +		priv->pinctrl_dev = proto;
> +		break;
>   	default:
>   		dev_err(dev, "Protocol not supported\n");
>   		return -EPROTO;
> @@ -436,6 +442,11 @@ static int scmi_bind_protocols(struct udevice *dev)
>   				drv = DM_DRIVER_GET(scmi_voltage_domain);
>   			}
>   			break;
> +		case SCMI_PROTOCOL_ID_PINCTRL:
> +			if (IS_ENABLED(CONFIG_PINCTRL_IMX_SCMI) &&
> +			    scmi_protocol_is_supported(dev, protocol_id))
> +				drv = DM_DRIVER_GET(scmi_pinctrl_imx);

Generic code change, should be separate patch.

> +			break;
>   		default:
>   			break;
>   		}

...

> diff --git a/drivers/pinctrl/nxp/Kconfig b/drivers/pinctrl/nxp/Kconfig
> index 06c26f156f6c8f63204604d6065485629cfd9b61..0086f9825837bf568bd7633a21da860e410eeeee 100644
> --- a/drivers/pinctrl/nxp/Kconfig
> +++ b/drivers/pinctrl/nxp/Kconfig
> @@ -1,6 +1,19 @@
>   config PINCTRL_IMX
>   	bool
>   
> +config PINCTRL_IMX_SCMI
> +	bool "IMX pinctrl SCMI driver"
> +	depends on ARCH_IMX9 && PINCTRL_FULL
> +	select PINCTRL_IMX
> +	help
> +	  Say Y here to enable the imx pinctrl scmi driver

Make sure the abbreviations like SCMI are always in capitals.

> +	  This provides a simple pinctrl driver for i.MX SoC which supports
> +	  SCMI. This feature depends on device tree configuration. This driver
> +	  is different from the linux one, this is a simple implementation,
> +	  only parses the 'fsl,pins' property and configure related
> +	  registers.
> +
>   config PINCTRL_IMX_SCU
>   	bool
>   
> diff --git a/drivers/pinctrl/nxp/Makefile b/drivers/pinctrl/nxp/Makefile
> index f10aa6ef188e37583b181bdf9d70ac191e506d75..3ec3e2a9c6fdb875da4ae9bf151df5666256883b 100644
> --- a/drivers/pinctrl/nxp/Makefile
> +++ b/drivers/pinctrl/nxp/Makefile
> @@ -4,6 +4,7 @@ obj-$(CONFIG_PINCTRL_IMX6)		+= pinctrl-imx6.o
>   obj-$(CONFIG_PINCTRL_IMX7)		+= pinctrl-imx7.o
>   obj-$(CONFIG_PINCTRL_IMX7ULP)		+= pinctrl-imx7ulp.o
>   obj-$(CONFIG_PINCTRL_IMX8ULP)		+= pinctrl-imx8ulp.o
> +obj-$(CONFIG_PINCTRL_IMX_SCMI)		+= pinctrl-scmi.o
>   obj-$(CONFIG_PINCTRL_IMX_SCU)		+= pinctrl-scu.o
>   obj-$(CONFIG_PINCTRL_IMX8)		+= pinctrl-imx8.o
>   obj-$(CONFIG_PINCTRL_IMX8M)		+= pinctrl-imx8m.o
> diff --git a/drivers/pinctrl/nxp/pinctrl-imx.c b/drivers/pinctrl/nxp/pinctrl-imx.c
> index b1960c56b512cc113a810304dc3ac3f99b237a7e..3d53d0cd4b60c0685dd4c73c23e61cb712cda0ee 100644
> --- a/drivers/pinctrl/nxp/pinctrl-imx.c
> +++ b/drivers/pinctrl/nxp/pinctrl-imx.c
> @@ -1,6 +1,7 @@
>   // SPDX-License-Identifier: GPL-2.0+
>   /*
>    * Copyright (C) 2016 Peng Fan <van.freenix at gmail.com>
> + * Copyright 2024 NXP
>    */
>   
>   #include <malloc.h>
> @@ -65,7 +66,9 @@ static int imx_pinctrl_set_state(struct udevice *dev, struct udevice *config)
>   
>   	npins = size / pin_size;
>   
> -	if (info->flags & IMX8_USE_SCU) {
> +	if (info->flags & IMX_USE_SCMI) {
> +		return imx_pinctrl_scmi_conf_pins(dev, pin_data, npins);
> +	} else if (info->flags & IMX8_USE_SCU) {
>   		imx_pinctrl_scu_conf_pins(info, pin_data, npins);
>   	} else {
>   		/*
> @@ -216,7 +219,7 @@ int imx_pinctrl_probe(struct udevice *dev,
>   	priv->dev = dev;
>   	priv->info = info;
>   
> -	if (info->flags & IMX8_USE_SCU)
> +	if ((info->flags & IMX8_USE_SCU) || (info->flags & IMX_USE_SCMI))

This works too:
if (info->flags & (IMX8_USE_SCU | IMX_USE_SCMI))

>   		return 0;
>   
>   	addr = ofnode_get_addr_size_index(dev_ofnode(dev), 0, &size);
> diff --git a/drivers/pinctrl/nxp/pinctrl-imx.h b/drivers/pinctrl/nxp/pinctrl-imx.h
> index fa4c084e2fc067fcb4e92c33312d4f430081fffd..b2f8865ded0ae380fc0156baa5eaea505c12f501 100644
> --- a/drivers/pinctrl/nxp/pinctrl-imx.h
> +++ b/drivers/pinctrl/nxp/pinctrl-imx.h
> @@ -1,6 +1,7 @@
>   /* SPDX-License-Identifier: GPL-2.0+ */
>   /*
>    * Copyright (C) 2016 Peng Fan <van.freenix at gmail.com>
> + * Copyright 2024 NXP
>    */
>   
>   #ifndef __DRIVERS_PINCTRL_IMX_H
> @@ -47,6 +48,7 @@ extern const struct pinctrl_ops imx_pinctrl_ops;
>   #define ZERO_OFFSET_VALID	0x2
>   #define CFG_IBE_OBE		0x4
>   #define IMX8_USE_SCU		0x8
> +#define IMX_USE_SCMI		0x10
>   
>   #define IOMUXC_CONFIG_SION	(0x1 << 4)
>   
> @@ -65,4 +67,13 @@ static inline int imx_pinctrl_scu_conf_pins(struct imx_pinctrl_soc_info *info,
>   }
>   #endif
>   
> +#ifdef CONFIG_PINCTRL_IMX_SCMI

Use IS_ENABLED() or CONFIG_IS_ENABLED()

> +int imx_pinctrl_scmi_conf_pins(struct udevice *dev, u32 *pin_data, int npins);
> +#else
> +static inline int imx_pinctrl_scmi_conf_pins(struct udevice *dev, u32 *pin_data, int npins)
> +{
> +	return 0;
> +}
> +#endif
> +
>   #endif /* __DRIVERS_PINCTRL_IMX_H */
> diff --git a/drivers/pinctrl/nxp/pinctrl-scmi.c b/drivers/pinctrl/nxp/pinctrl-scmi.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..19b1b433a5ced0bb85e52f4d19bdeab2825f275e
> --- /dev/null
> +++ b/drivers/pinctrl/nxp/pinctrl-scmi.c
> @@ -0,0 +1,136 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2024 NXP
> + */
> +
> +#include <dm.h>
> +#include <dm/device_compat.h>
> +#include <errno.h>
> +#include <misc.h>
> +#include <scmi_agent.h>
> +#include <scmi_protocols.h>
> +#include <asm/io.h>
> +#include <asm/mach-imx/iomux-v3.h>
> +#include <linux/bitops.h>

Keep the list sorted.

> +#include "pinctrl-imx.h"
> +
> +#if defined(CONFIG_IMX93)

Use IS_ENABLED() or CONFIG_IS_ENABLED()

> +#define DAISY_OFFSET	0x360

Why can this offset information not be queried from the firmware interface ?

> +#endif
> +#if defined(CONFIG_IMX95)
> +#define DAISY_OFFSET	0x408
> +#endif
[...]


More information about the U-Boot mailing list