diff --git a/drivers/firmware/arm_scmi/pinctrl.c b/drivers/firmware/arm_scmi/pinctrl.c
index 868a2f9821be..93109997614d 100644
--- a/drivers/firmware/arm_scmi/pinctrl.c
+++ b/drivers/firmware/arm_scmi/pinctrl.c
@@ -6,13 +6,14 @@
  */
 
 #include <linux/module.h>
+#include <linux/pinctrl/pinconf-generic.h>
 #include <linux/scmi_protocol.h>
 #include <linux/slab.h>
 
 #include "protocols.h"
 
-#define REG_TYPE_BITS GENMASK(9, 8)
-#define REG_CONFIG GENMASK(7, 0)
+#define REG_TYPE_CONFIG GENMASK(1, 0)
+#define REG_NUM_CONFIG GENMASK(9, 2)
 
 #define GET_GROUPS_NR(x)	le32_get_bits((x), GENMASK(31, 16))
 #define GET_PINS_NR(x)		le32_get_bits((x), GENMASK(15, 0))
@@ -36,10 +37,11 @@ enum scmi_pinctrl_protocol_cmd {
 	PINCTRL_SET_PERMISSIONS = 0xb
 };
 
+#define MAX_CONFIG_ENTRY 10
 struct scmi_msg_conf_set {
 	__le32 identifier;
 	__le32 attributes;
-	__le32 config_value;
+	__le32 config_value[MAX_CONFIG_ENTRY * 2];
 };
 
 struct scmi_msg_conf_get {
@@ -320,9 +322,11 @@ static int scmi_pinctrl_config_get(const struct scmi_protocol_handle *ph,
 
 	tx = t->tx.buf;
 	tx->identifier = cpu_to_le32(selector);
+	/*
 	attributes = FIELD_PREP(REG_TYPE_BITS, type) |
 		FIELD_PREP(REG_CONFIG, config_type);
 	tx->attributes = cpu_to_le32(attributes);
+	*/
 
 	ret = ph->xops->do_xfer(ph, t);
 	if (!ret)
@@ -335,7 +339,7 @@ static int scmi_pinctrl_config_get(const struct scmi_protocol_handle *ph,
 static int scmi_pinctrl_config_set(const struct scmi_protocol_handle *ph,
 				   u32 selector,
 				   enum scmi_pinctrl_selector_type type,
-				   u8 config_type, unsigned long config_value)
+				   unsigned long *configs, unsigned int num_configs)
 {
 	struct scmi_xfer *t;
 	struct scmi_msg_conf_set *tx;
@@ -355,10 +359,14 @@ static int scmi_pinctrl_config_set(const struct scmi_protocol_handle *ph,
 
 	tx = t->tx.buf;
 	tx->identifier = cpu_to_le32(selector);
-	attributes = FIELD_PREP(REG_TYPE_BITS, type) |
-		FIELD_PREP(REG_CONFIG, config_type);
+	for (int i = 0; i < num_configs; i++) {
+		tx->config_value[i * 2] = cpu_to_le32(pinconf_to_config_param(configs[i]));
+		tx->config_value[i * 2 + 1] = cpu_to_le32(pinconf_to_config_argument(configs[i]));
+	}
+
+	attributes = FIELD_PREP(REG_TYPE_CONFIG, type) |
+		FIELD_PREP(REG_NUM_CONFIG, num_configs);
 	tx->attributes = cpu_to_le32(attributes);
-	tx->config_value = cpu_to_le32(config_value);
 
 	ret = ph->xops->do_xfer(ph, t);
 
diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c
index 9bc16943014f..dd0a66a17184 100644
--- a/drivers/pinctrl/freescale/pinctrl-imx.c
+++ b/drivers/pinctrl/freescale/pinctrl-imx.c
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/pinctrl/pinconf-generic.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/seq_file.h>
@@ -33,6 +34,29 @@
 #define IMX_NO_PAD_CTL	0x80000000	/* no pin config need */
 #define IMX_PAD_SION 0x40000000		/* set SION */
 
+/*
+ * Each pin represented in fsl,pins consists of a number of u32 PIN_FUNC_ID
+ * and 1 u32 CONFIG, the total size is PIN_FUNC_ID + CONFIG for each pin.
+ * For generic_pinconf case, there's no extra u32 CONFIG.
+ *
+ * PIN_FUNC_ID format:
+ * Default:
+ *     <mux_reg conf_reg input_reg mux_mode input_val>
+ * SHARE_MUX_CONF_REG:
+ *     <mux_conf_reg input_reg mux_mode input_val>
+ * IMX_USE_SCU:
+ *	<pin_id mux_mode>
+ */
+#define FSL_PIN_SIZE 24
+#define FSL_PIN_SHARE_SIZE 20
+#define FSL_SCU_PIN_SIZE 12
+
+/* SCMI pin control types, aligned with SCMI firmware */
+#define IMX_PIN_TYPE_MUX	192
+#define IMX_PIN_TYPE_CONFIG	193
+#define IMX_PIN_TYPE_DAISY_ID	194
+#define IMX_PIN_TYPE_DAISY_CFG	195
+
 static inline const struct group_desc *imx_pinctrl_find_group_by_name(
 				struct pinctrl_dev *pctldev,
 				const char *name)
@@ -55,6 +79,96 @@ static void imx_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
 	seq_printf(s, "%s", dev_name(pctldev->dev));
 }
 
+#define IMX_SCMI_NUM_CFG 4
+int imx_scmi_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *np,
+			    struct pinctrl_map **map, unsigned *num_maps)
+{
+	struct pinctrl_map *new_map;
+	const __be32 *list;
+	unsigned long *configs = NULL;
+	unsigned long cfg[IMX_SCMI_NUM_CFG];
+	int map_num, size, pin_size, pin_id, num_pins;
+	int mux_reg, conf_reg, input_reg, mux_val, conf_val, input_val;
+	int i, j;
+	uint32_t ncfg;
+	static uint32_t daisy_off;
+
+	if (!daisy_off) {
+		if (of_machine_is_compatible("fsl,imx93"))
+			daisy_off = 0x360;
+		else if (of_machine_is_compatible("fsl,imx95"))
+			daisy_off = 0x408;
+		else
+			dev_err(pctldev->dev, "platform not support scmi pinctrl\n");
+	}
+
+	list = of_get_property(np, "fsl,pins", &size);
+	if (!list) {
+		dev_err(pctldev->dev, "no fsl,pins property in node %pOF\n", np);
+		return -EINVAL;
+	}
+
+	pin_size = FSL_PIN_SIZE;
+
+	if (!size || size % pin_size) {
+		dev_err(pctldev->dev, "Invalid fsl,pins or pins property in node %pOF\n", np);
+		return -EINVAL;
+	}
+
+	num_pins = size / pin_size;
+	map_num = num_pins;
+
+	new_map = kmalloc_array(map_num, sizeof(struct pinctrl_map),
+				GFP_KERNEL);
+	if (!new_map)
+		return -ENOMEM;
+
+	*map = new_map;
+	*num_maps = map_num;
+
+	/* create config map */
+	for (i = 0; i < num_pins; i++) {
+		j = 0;
+		ncfg = IMX_SCMI_NUM_CFG;
+		mux_reg = be32_to_cpu(*list++);
+		conf_reg = be32_to_cpu(*list++);
+		input_reg = be32_to_cpu(*list++);
+		mux_val = be32_to_cpu(*list++);
+		input_val = be32_to_cpu(*list++);
+		conf_val = be32_to_cpu(*list++);
+		if (conf_val & IMX_PAD_SION)
+			mux_val |= IOMUXC_CONFIG_SION;
+
+		pin_id = mux_reg / 4;
+
+		cfg[j++] = pinconf_to_config_packed(IMX_PIN_TYPE_MUX, mux_val);
+
+		if (!conf_reg || (conf_val & IMX_NO_PAD_CTL)) {
+			ncfg--;
+		} else {
+			cfg[j++] = pinconf_to_config_packed(IMX_PIN_TYPE_CONFIG, conf_val);
+		}
+
+		if (!input_reg) {
+			ncfg -= 2;
+		} else {
+			cfg[j++] = pinconf_to_config_packed(IMX_PIN_TYPE_DAISY_ID,
+							    (input_reg - daisy_off) / 4);
+			cfg[j++] = pinconf_to_config_packed(IMX_PIN_TYPE_DAISY_CFG, input_val);
+		}
+
+		configs = kmemdup(cfg, ncfg * sizeof(unsigned long), GFP_KERNEL);
+
+		new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
+		new_map[i].data.configs.group_or_pin = pin_get_name(pctldev, pin_id);
+		new_map[i].data.configs.configs = configs;
+		new_map[i].data.configs.num_configs = ncfg;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(imx_scmi_dt_node_to_map);
+
 static int imx_dt_node_to_map(struct pinctrl_dev *pctldev,
 			struct device_node *np,
 			struct pinctrl_map **map, unsigned *num_maps)
@@ -441,22 +555,6 @@ static const struct pinconf_ops imx_pinconf_ops = {
 	.pin_config_group_dbg_show = imx_pinconf_group_dbg_show,
 };
 
-/*
- * Each pin represented in fsl,pins consists of a number of u32 PIN_FUNC_ID
- * and 1 u32 CONFIG, the total size is PIN_FUNC_ID + CONFIG for each pin.
- *
- * PIN_FUNC_ID format:
- * Default:
- *     <mux_reg conf_reg input_reg mux_mode input_val>
- * SHARE_MUX_CONF_REG:
- *     <mux_conf_reg input_reg mux_mode input_val>
- * IMX_USE_SCU:
- *	<pin_id mux_mode>
- */
-#define FSL_PIN_SIZE 24
-#define FSL_PIN_SHARE_SIZE 20
-#define FSL_SCU_PIN_SIZE 12
-
 static void imx_pinctrl_parse_pin_mmio(struct imx_pinctrl *ipctl,
 				       unsigned int *pin_id, struct imx_pin *pin,
 				       const __be32 **list_p,
diff --git a/drivers/pinctrl/pinctrl-scmi.c b/drivers/pinctrl/pinctrl-scmi.c
index a9304402ddf1..92cf10241aa8 100644
--- a/drivers/pinctrl/pinctrl-scmi.c
+++ b/drivers/pinctrl/pinctrl-scmi.c
@@ -8,6 +8,7 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/seq_file.h>
 #include <linux/scmi_protocol.h>
 #include <linux/slab.h>
@@ -77,13 +78,28 @@ static int pinctrl_scmi_get_group_pins(struct pinctrl_dev *pctldev,
 }
 
 #ifdef CONFIG_OF
+#ifdef CONFIG_PINCTRL_IMX
+extern int imx_scmi_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *np,
+				   struct pinctrl_map **map, unsigned *num_maps);
+#else
+static inline int imx_scmi_dt_node_to_map(struct pinctrl_dev *pctldev,
+					  struct device_node *np,
+					  struct pinctrl_map **map, unsigned *num_maps)
+{
+	return -ENOTSUPP;
+}
+#endif
 static int pinctrl_scmi_dt_node_to_map(struct pinctrl_dev *pctldev,
 				       struct device_node *np_config,
 				       struct pinctrl_map **map,
 				       u32 *num_maps)
 {
+	if ((of_machine_is_compatible("fsl,imx93") || of_machine_is_compatible("fsl,imx95")))
+		return imx_scmi_dt_node_to_map(pctldev, np_config, map, num_maps);
+
 	return pinconf_generic_dt_node_to_map(pctldev, np_config, map, num_maps,
 					      PIN_MAP_TYPE_INVALID);
+
 }
 
 static void pinctrl_scmi_dt_free_map(struct pinctrl_dev *pctldev, struct pinctrl_map *map,
@@ -242,25 +258,15 @@ static int pinctrl_scmi_pinconf_set(struct pinctrl_dev *pctldev,
 				    unsigned long *configs,
 				    unsigned int num_configs)
 {
-	int i, ret;
+	int ret;
 	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
-	enum pin_config_param config_type;
-	unsigned long config_value;
 
 	if (!configs || num_configs == 0)
 		return -EINVAL;
 
-	for (i = 0; i < num_configs; i++) {
-		config_type = pinconf_to_config_param(configs[i]);
-		config_value = pinconf_to_config_argument(configs[i]);
-
-		ret = pinctrl_ops->config_set(pmx->ph, _pin, PIN_TYPE, config_type, config_value);
-		if (ret) {
-			dev_err(pmx->dev, "Error parsing config %ld\n",
-				configs[i]);
-			break;
-		}
-	}
+	ret = pinctrl_ops->config_set(pmx->ph, _pin, PIN_TYPE, configs, num_configs);
+	if (ret)
+		dev_err(pmx->dev, "Error parsing config %d\n", ret);
 
 	return ret;
 }
@@ -270,26 +276,15 @@ static int pinctrl_scmi_pinconf_group_set(struct pinctrl_dev *pctldev,
 					  unsigned long *configs,
 					  unsigned int num_configs)
 {
-	int i, ret;
+	int ret;
 	struct scmi_pinctrl *pmx =  pinctrl_dev_get_drvdata(pctldev);
-	enum pin_config_param config_type;
-	unsigned long config_value;
 
 	if (!configs || num_configs == 0)
 		return -EINVAL;
 
-	for (i = 0; i < num_configs; i++) {
-		config_type = pinconf_to_config_param(configs[i]);
-		config_value = pinconf_to_config_argument(configs[i]);
-
-		ret = pinctrl_ops->config_set(pmx->ph, group, GROUP_TYPE, config_type,
-					      config_value);
-		if (ret) {
-			dev_err(pmx->dev, "Error parsing config = %ld",
-				configs[i]);
-			break;
-		}
-	}
+	ret = pinctrl_ops->config_set(pmx->ph, group, GROUP_TYPE, configs, num_configs);
+	if (ret)
+		dev_err(pmx->dev, "Error parsing config %d", ret);
 
 	return ret;
 };
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 99c1405decd7..e58d207b56b6 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -730,7 +730,7 @@ struct scmi_pinctrl_proto_ops {
 			  u8 config_type, unsigned long *config_value);
 	int (*config_set)(const struct scmi_protocol_handle *ph, u32 selector,
 			  enum scmi_pinctrl_selector_type type,
-			  u8 config_type, unsigned long config_value);
+			  unsigned long *configs, unsigned int num_configs);
 	int (*pin_request)(const struct scmi_protocol_handle *ph, u32 pin);
 	int (*pin_free)(const struct scmi_protocol_handle *ph, u32 pin);
 };
