On 1/3/25 7:45 AM, Alice Guo wrote:
From: Peng Fan <[email protected]>
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 <[email protected]>
+ * 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 <[email protected]>
+ * 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
[...]