diff --git a/plat/nvidia/tegra/include/t194/tegra194_private.h b/plat/nvidia/tegra/include/t194/tegra194_private.h index f5de017bc9bc3b77ff46246c449f9b11d57c7168..e519cdccc658cc694eb5fa1c0574ee9daeea4eb8 100644 --- a/plat/nvidia/tegra/include/t194/tegra194_private.h +++ b/plat/nvidia/tegra/include/t194/tegra194_private.h @@ -11,5 +11,6 @@ void tegra194_cpu_reset_handler(void); uint64_t tegra194_get_cpu_reset_handler_base(void); uint64_t tegra194_get_cpu_reset_handler_size(void); uint64_t tegra194_get_smmu_ctx_offset(void); +void tegra194_set_system_suspend_entry(void); #endif /* __TEGRA194_PRIVATE_H__ */ diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c index c25897d56b32a195a84fb73afcf6249d55979218..71a666b803acf6cf654edcf0aa552e59fd1acd2c 100644 --- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c @@ -167,6 +167,9 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) MCE_CORE_SLEEP_TIME_INFINITE, 0U); assert(ret == 0); + + /* set system suspend state for house-keeping */ + tegra194_set_system_suspend_entry(); } } else { ; /* do nothing */ diff --git a/plat/nvidia/tegra/soc/t194/plat_trampoline.S b/plat/nvidia/tegra/soc/t194/plat_trampoline.S index ea8cbef157ea16e0db6d0ca3697b6ca486489025..33c7e6f7897f75fb6fa7c5284401397f5be5dacd 100644 --- a/plat/nvidia/tegra/soc/t194/plat_trampoline.S +++ b/plat/nvidia/tegra/soc/t194/plat_trampoline.S @@ -10,6 +10,8 @@ #include <memctrl_v2.h> #include <tegra_def.h> +#define TEGRA194_STATE_SYSTEM_SUSPEND 0x5C7 +#define TEGRA194_STATE_SYSTEM_RESUME 0x600D #define TEGRA194_SMMU_CTX_SIZE 0x490 .align 4 @@ -17,17 +19,24 @@ /* CPU reset handler routine */ func tegra194_cpu_reset_handler - /* - * The TZRAM loses state during System Suspend. We use this - * information to decide if the reset handler is running after a - * System Suspend. Resume from system suspend requires restoring - * the entire state from TZDRAM to TZRAM. - */ - mov x0, #BL31_BASE - ldr x0, [x0] - cbnz x0, boot_cpu + /* check if we are exiting system suspend state */ + adr x0, __tegra194_system_suspend_state + ldr x1, [x0] + mov x2, #TEGRA194_STATE_SYSTEM_SUSPEND + lsl x2, x2, #16 + add x2, x2, #TEGRA194_STATE_SYSTEM_SUSPEND + cmp x1, x2 + bne boot_cpu + + /* set system resume state */ + mov x1, #TEGRA194_STATE_SYSTEM_RESUME + lsl x1, x1, #16 + mov x2, #TEGRA194_STATE_SYSTEM_RESUME + add x1, x1, x2 + str x1, [x0] + dsb sy - /* resume from system suspend */ + /* prepare to relocate to TZSRAM */ mov x0, #BL31_BASE adr x1, __tegra194_cpu_reset_handler_end adr x2, __tegra194_cpu_reset_handler_data @@ -71,6 +80,10 @@ __tegra194_cpu_reset_handler_data: .quad tegra_secure_entrypoint .quad __BL31_END__ - BL31_BASE + .globl __tegra194_system_suspend_state +__tegra194_system_suspend_state: + .quad 0 + .align 4 __tegra194_smmu_context: .rept TEGRA194_SMMU_CTX_SIZE @@ -86,6 +99,7 @@ __tegra194_cpu_reset_handler_end: .globl tegra194_get_cpu_reset_handler_size .globl tegra194_get_cpu_reset_handler_base .globl tegra194_get_smmu_ctx_offset + .globl tegra194_set_system_suspend_entry /* return size of the CPU reset handler */ func tegra194_get_cpu_reset_handler_size @@ -108,3 +122,23 @@ func tegra194_get_smmu_ctx_offset sub x0, x0, x1 ret endfunc tegra194_get_smmu_ctx_offset + +/* set system suspend state before SC7 entry */ +func tegra194_set_system_suspend_entry + mov x0, #TEGRA_MC_BASE + mov x3, #MC_SECURITY_CFG3_0 + ldr w1, [x0, x3] + lsl x1, x1, #32 + mov x3, #MC_SECURITY_CFG0_0 + ldr w2, [x0, x3] + orr x3, x1, x2 /* TZDRAM base */ + adr x0, __tegra194_system_suspend_state + adr x1, tegra194_cpu_reset_handler + sub x2, x0, x1 /* offset in TZDRAM */ + mov x0, #TEGRA194_STATE_SYSTEM_SUSPEND + lsl x0, x0, #16 + add x0, x0, #TEGRA194_STATE_SYSTEM_SUSPEND + str x0, [x3, x2] /* set value in TZDRAM */ + dsb sy + ret +endfunc tegra194_set_system_suspend_entry