arch: mach-k3: common: Add support to shutdown MCU R5 Core 1
During boot, ROM can bring up the MCU R5F cores in either lockstep or split mode based on X509 certificate flags. If booted in split mode, core 0 will run DM firmware and second core sits in WFI. Add support to shut down core 1 so that other firmwares can later be loaded on them. The shutdown of MCU R5 Core 1 is invoked at A72 SPL init, as by that time Device Manager (DM) is up and running on R5 Core 0. The shutdown request of Core 1 is handled by Device Manager itself. Signed-off-by: Beleswar Padhi <b-padhi@ti.com>
This commit is contained in:
@@ -31,6 +31,11 @@
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <dm/device-internal.h>
|
||||
|
||||
#define PROC_BOOT_CTRL_FLAG_R5_CORE_HALT 0x00000001
|
||||
#define PROC_BOOT_STATUS_FLAG_R5_WFI 0x00000002
|
||||
#define PROC_ID_MCU_R5FSS0_CORE1 0x02
|
||||
#define PROC_BOOT_CFG_FLAG_R5_LOCKSTEP 0x00000100
|
||||
|
||||
#include <asm/arch/k3-qos.h>
|
||||
|
||||
struct ti_sci_handle *get_ti_sci_handle(void)
|
||||
@@ -328,3 +333,67 @@ void setup_qos(void)
|
||||
writel(qos_data[i].val, (uintptr_t)qos_data[i].reg);
|
||||
}
|
||||
#endif
|
||||
|
||||
int __maybe_unused shutdown_mcu_r5_core1(void)
|
||||
{
|
||||
struct ti_sci_handle *ti_sci = get_ti_sci_handle();
|
||||
struct ti_sci_dev_ops *dev_ops = &ti_sci->ops.dev_ops;
|
||||
struct ti_sci_proc_ops *proc_ops = &ti_sci->ops.proc_ops;
|
||||
u32 dev_id_mcu_r5_core1 = put_core_ids[0];
|
||||
u64 boot_vector;
|
||||
u32 cfg, ctrl, sts, halted;
|
||||
int cluster_mode_lockstep, ret;
|
||||
bool r_state = false, c_state = false;
|
||||
|
||||
ret = proc_ops->proc_request(ti_sci, PROC_ID_MCU_R5FSS0_CORE1);
|
||||
if (ret) {
|
||||
printf("Unable to request processor control for MCU1_1 core, %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = dev_ops->is_on(ti_sci, dev_id_mcu_r5_core1, &r_state, &c_state);
|
||||
if (ret) {
|
||||
printf("Unable to get device status for MCU1_1 core, %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = proc_ops->get_proc_boot_status(ti_sci, PROC_ID_MCU_R5FSS0_CORE1,
|
||||
&boot_vector, &cfg, &ctrl, &sts);
|
||||
if (ret) {
|
||||
printf("Unable to get Processor boot status for MCU1_1 core, %d\n",
|
||||
ret);
|
||||
goto release_proc_ctrl;
|
||||
}
|
||||
|
||||
halted = !!(sts & PROC_BOOT_STATUS_FLAG_R5_WFI);
|
||||
cluster_mode_lockstep = !!(cfg & PROC_BOOT_CFG_FLAG_R5_LOCKSTEP);
|
||||
|
||||
/*
|
||||
* Shutdown MCU R5F Core 1 only if:
|
||||
* - cluster is booted in SplitMode
|
||||
* - core is powered on
|
||||
* - core is in WFI (halted)
|
||||
*/
|
||||
if (cluster_mode_lockstep || !c_state || !halted) {
|
||||
ret = -EINVAL;
|
||||
goto release_proc_ctrl;
|
||||
}
|
||||
|
||||
ret = proc_ops->set_proc_boot_ctrl(ti_sci, PROC_ID_MCU_R5FSS0_CORE1,
|
||||
PROC_BOOT_CTRL_FLAG_R5_CORE_HALT, 0);
|
||||
if (ret) {
|
||||
printf("Unable to Halt MCU1_1 core, %d\n", ret);
|
||||
goto release_proc_ctrl;
|
||||
}
|
||||
|
||||
ret = dev_ops->put_device(ti_sci, dev_id_mcu_r5_core1);
|
||||
if (ret) {
|
||||
printf("Unable to assert reset on MCU1_1 core, %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
release_proc_ctrl:
|
||||
proc_ops->proc_release(ti_sci, PROC_ID_MCU_R5FSS0_CORE1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ enum k3_device_type get_device_type(void);
|
||||
struct ti_sci_handle *get_ti_sci_handle(void);
|
||||
void do_board_detect(void);
|
||||
void ti_secure_image_check_binary(void **p_image, size_t *p_size);
|
||||
int shutdown_mcu_r5_core1(void);
|
||||
|
||||
#if (IS_ENABLED(CONFIG_K3_QOS))
|
||||
void setup_qos(void);
|
||||
|
||||
@@ -296,9 +296,9 @@ void do_dt_magic(void)
|
||||
|
||||
void board_init_f(ulong dummy)
|
||||
{
|
||||
int ret;
|
||||
#if defined(CONFIG_K3_J721E_DDRSS) || defined(CONFIG_K3_LOAD_SYSFW)
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
#endif
|
||||
/*
|
||||
* Cannot delay this further as there is a chance that
|
||||
@@ -371,6 +371,13 @@ void board_init_f(ulong dummy)
|
||||
preloader_console_init();
|
||||
#endif
|
||||
|
||||
/* Shutdown MCU_R5 Core 1 in Split mode at A72 SPL Stage */
|
||||
if (IS_ENABLED(CONFIG_ARM64)) {
|
||||
ret = shutdown_mcu_r5_core1();
|
||||
if (ret)
|
||||
printf("Unable to shutdown MCU R5 core 1, %d\n", ret);
|
||||
}
|
||||
|
||||
/* Output System Firmware version info */
|
||||
k3_sysfw_print_ver();
|
||||
|
||||
|
||||
@@ -230,6 +230,13 @@ void k3_spl_init(void)
|
||||
remove_fwl_configs(navss_cbass0_fwls, ARRAY_SIZE(navss_cbass0_fwls));
|
||||
}
|
||||
|
||||
/* Shutdown MCU_R5 Core 1 in Split mode at A72 SPL Stage */
|
||||
if (IS_ENABLED(CONFIG_ARM64)) {
|
||||
ret = shutdown_mcu_r5_core1();
|
||||
if (ret)
|
||||
printf("Unable to shutdown MCU R5 core 1, %d\n", ret);
|
||||
}
|
||||
|
||||
/* Output System Firmware version info */
|
||||
k3_sysfw_print_ver();
|
||||
}
|
||||
|
||||
@@ -206,6 +206,13 @@ void k3_spl_init(void)
|
||||
|
||||
writel(AUDIO_REFCLK1_DEFAULT, (uintptr_t)CTRL_MMR_CFG0_AUDIO_REFCLK1_CTRL);
|
||||
|
||||
/* Shutdown MCU_R5 Core 1 in Split mode at A72 SPL Stage */
|
||||
if (IS_ENABLED(CONFIG_ARM64)) {
|
||||
ret = shutdown_mcu_r5_core1();
|
||||
if (ret)
|
||||
printf("Unable to shutdown MCU R5 core 1, %d\n", ret);
|
||||
}
|
||||
|
||||
/* Output System Firmware version info */
|
||||
k3_sysfw_print_ver();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user