[PATCH 3/4] nxp: imx9{4, 5, 52}_evk: power on mcore according to SM config

ye.li at oss.nxp.com ye.li at oss.nxp.com
Wed Jun 17 16:14:45 CEST 2026


From: Ye Li <ye.li at nxp.com>

When working with SM config mx9{4,5,52}evkrpmsg, mcores are not booted
by ROM. Hence, power on the mcore and initialize TCM ECC in u-boot for
subsequent mcore booting.

Signed-off-by: Ye Li <ye.li at nxp.com>
---
 arch/arm/include/asm/arch-imx9/sys_proto.h |  2 +
 arch/arm/mach-imx/imx9/scmi/soc.c          | 98 ++++++++++++++++++++++
 board/nxp/imx94_evk/imx94_evk.c            |  5 +-
 board/nxp/imx952_evk/imx952_evk.c          |  3 +
 board/nxp/imx95_evk/imx95_evk.c            | 10 ++-
 configs/imx95_evk.config                   |  2 +-
 include/scmi_nxp_protocols.h               | 11 +++
 7 files changed, 128 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/arch-imx9/sys_proto.h b/arch/arm/include/asm/arch-imx9/sys_proto.h
index b5e7d7d6855..5551ebaa68d 100644
--- a/arch/arm/include/asm/arch-imx9/sys_proto.h
+++ b/arch/arm/include/asm/arch-imx9/sys_proto.h
@@ -27,6 +27,8 @@ int scmi_get_boot_device_offset(unsigned long *img_off);
 int scmi_get_boot_stage(u8 *stage);
 u8 scmi_get_imgset_sel(void);
 
+int power_on_mcore(const char *sm_cfgname);
+
 #define is_voltage_mode(mode) (soc_target_voltage_mode() == (mode))
 
 #endif
diff --git a/arch/arm/mach-imx/imx9/scmi/soc.c b/arch/arm/mach-imx/imx9/scmi/soc.c
index 372dfc5518e..c4127349aa3 100644
--- a/arch/arm/mach-imx/imx9/scmi/soc.c
+++ b/arch/arm/mach-imx/imx9/scmi/soc.c
@@ -58,6 +58,43 @@ uint32_t scmi_get_rom_data(rom_passover_t *rom_data)
 	return 0;
 }
 
+int scmi_misc_cfginfo(u32 *msel, char *cfgname)
+{
+	struct scmi_imx_misc_cfg_info_out out = {};
+	struct scmi_msg msg = {
+		.protocol_id = SCMI_PROTOCOL_ID_IMX_MISC,
+		.message_id = SCMI_IMX_MISC_CFG_INFO,
+		.in_msg = (u8 *)NULL,
+		.in_msg_sz = 0,
+		.out_msg = (u8 *)&out,
+		.out_msg_sz = sizeof(out),
+	};
+	int ret;
+	struct udevice *dev;
+
+	if (!msel || !cfgname)
+		return -EINVAL;
+
+	ret = uclass_get_device_by_name(UCLASS_CLK, "protocol at 14", &dev);
+	if (ret)
+		return ret;
+
+	ret = devm_scmi_process_msg(dev, &msg);
+	if (ret)
+		return ret;
+
+	if (out.status) {
+		printf("Failed to get cfg name, scmi_err = %d\n",
+		       out.status);
+		return scmi_to_linux_errno(out.status);
+	}
+
+	*msel = out.msel;
+	strcpy(cfgname, (const char *)out.cfgname);
+
+	return 0;
+}
+
 int scmi_misc_ddrinfo(u32 ddrc_id, struct scmi_ddr_info_out *out)
 {
 	u32 in = ddrc_id;
@@ -746,6 +783,67 @@ int get_reset_reason(bool sys, bool lm)
 	return 0;
 }
 
+int power_on_mcore(const char *sm_cfgname)
+{
+	char cfgname[MISC_MAX_CFGNAME];
+	u32 msel;
+	int ret;
+	struct udevice *dev;
+
+	ret = scmi_misc_cfginfo(&msel, cfgname);
+	if (ret)
+		return ret;
+
+	if (strncmp(cfgname, sm_cfgname, MISC_MAX_CFGNAME))
+		return -EINVAL;
+
+	printf("power on mcore for %s\n", sm_cfgname);
+
+	ret = uclass_get_device_by_name(UCLASS_CLK, "protocol at 14", &dev);
+	if (ret)
+		return ret;
+
+	if (!arch_auxiliary_core_check_up(1)) {
+		/* Power up M7MIX */
+		ret = scmi_pwd_state_set(dev, 0, SCMI_PD(M70), 0);
+		if (ret) {
+			printf("Power M7 failed\n");
+			return -EIO;
+		}
+
+		/* In case OEI not init ECC, do it here */
+		memset_io((void *)0x203c0000, 0, 0x40000);
+		memset_io((void *)0x20400000, 0, 0x40000);
+	}
+
+#if IS_ENABLED(CONFIG_IMX94)
+	if (!arch_auxiliary_core_check_up(7)) {
+		ret = scmi_pwd_state_set(dev, 0, SCMI_PD(M71), 0);
+		if (ret) {
+			printf("Power M71 failed\n");
+			return -EIO;
+		}
+
+		memset_io((void *)0x202c0000, 0, 0x40000);
+		memset_io((void *)0x20300000, 0, 0x40000);
+	}
+
+	if (!arch_auxiliary_core_check_up(8)) {
+		ret = scmi_pwd_state_set(dev, 0, SCMI_PD(NETC), 0);
+		if (ret) {
+			printf("Power M33S failed\n");
+			return -EIO;
+		}
+
+		memset_io((void *)0x209c0000, 0, 0x40000);
+		memset_io((void *)0x20A00000, 0, 0x40000);
+		memset_io((void *)0x20800000, 0, 0xa1000);
+	}
+#endif
+
+	return 0;
+}
+
 void build_info(void)
 {
 	u32 fw_version, sha1, res = 0, status;
diff --git a/board/nxp/imx94_evk/imx94_evk.c b/board/nxp/imx94_evk/imx94_evk.c
index 4731b79b55d..f0edd7d131f 100644
--- a/board/nxp/imx94_evk/imx94_evk.c
+++ b/board/nxp/imx94_evk/imx94_evk.c
@@ -7,10 +7,13 @@
 #include <fdt_support.h>
 #include <asm/gpio.h>
 #include <asm/arch/clock.h>
-#include <asm/mach-imx/sys_proto.h>
+#include <asm/arch/sys_proto.h>
 
 int board_init(void)
 {
+	/* Power on mcores when using rpmsg cfg */
+	power_on_mcore("mx94evkrpmsg");
+
 	return 0;
 }
 
diff --git a/board/nxp/imx952_evk/imx952_evk.c b/board/nxp/imx952_evk/imx952_evk.c
index 2a61817939e..74ef87b50c0 100644
--- a/board/nxp/imx952_evk/imx952_evk.c
+++ b/board/nxp/imx952_evk/imx952_evk.c
@@ -9,6 +9,9 @@
 
 int board_init(void)
 {
+	/* Power on mcores when using rpmsg cfg */
+	power_on_mcore("mx952evkrpmsg");
+
 	return 0;
 }
 
diff --git a/board/nxp/imx95_evk/imx95_evk.c b/board/nxp/imx95_evk/imx95_evk.c
index 99a37e0593f..0de7fbe3f63 100644
--- a/board/nxp/imx95_evk/imx95_evk.c
+++ b/board/nxp/imx95_evk/imx95_evk.c
@@ -5,7 +5,15 @@
 
 #include <asm/gpio.h>
 #include <asm/arch/clock.h>
-#include <asm/mach-imx/sys_proto.h>
+#include <asm/arch/sys_proto.h>
+
+int board_init(void)
+{
+	/* Power on mcores when using rpmsg cfg */
+	power_on_mcore("mx95evkrpmsg");
+
+	return 0;
+}
 
 int board_late_init(void)
 {
diff --git a/configs/imx95_evk.config b/configs/imx95_evk.config
index 743778d9554..7c429fe0bfe 100644
--- a/configs/imx95_evk.config
+++ b/configs/imx95_evk.config
@@ -37,7 +37,7 @@ CONFIG_BOOTCOMMAND="bootflow scan -l; run bsp_bootcmd"
 CONFIG_DEFAULT_FDT_FILE="imx95-19x19-evk.dtb"
 CONFIG_SYS_CBSIZE=2048
 CONFIG_SYS_PBSIZE=2074
-# CONFIG_BOARD_INIT is not set
+CONFIG_BOARD_INIT=y
 CONFIG_BOARD_LATE_INIT=y
 CONFIG_PCI_INIT_R=y
 CONFIG_SPL_MAX_SIZE=0x20000
diff --git a/include/scmi_nxp_protocols.h b/include/scmi_nxp_protocols.h
index c17f3663eba..184dcc1e04b 100644
--- a/include/scmi_nxp_protocols.h
+++ b/include/scmi_nxp_protocols.h
@@ -18,6 +18,7 @@
 #define SCMI_ARRAY(X, Y)	((SCMI_PAYLOAD_LEN - (X)) / sizeof(Y))
 
 #define SCMI_IMX_MISC_RESET_REASON	0xA
+#define SCMI_IMX_MISC_CFG_INFO		0xC
 
 struct scmi_imx_misc_reset_reason_in {
 #define MISC_REASON_FLAG_SYSTEM		BIT(0)
@@ -119,4 +120,14 @@ static inline int scmi_imx_cpu_start(struct udevice *dev, u32 cpuid, bool start)
 	return -EOPNOTSUPP;
 }
 #endif
+
+struct scmi_imx_misc_cfg_info_out {
+	s32 status;
+	/* Mode selector value */
+	u32 msel;
+#define MISC_MAX_CFGNAME	16
+	/* Config (cfg) file basename */
+	char cfgname[MISC_MAX_CFGNAME];
+};
+
 #endif
-- 
2.34.1



More information about the U-Boot mailing list