From: Ye Li <[email protected]> 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 <[email protected]> --- 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@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@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

