diff options
-rw-r--r-- | arch/arm/mach-tegra/common.c | 25 | ||||
-rw-r--r-- | arch/arm/mach-tegra/pm.c | 10 |
2 files changed, 21 insertions, 14 deletions
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index c5401e65426f..8364589e1ff6 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c @@ -227,8 +227,6 @@ static __initdata struct tegra_clk_init_table common_clk_init_table[] = { }; #ifdef CONFIG_TRUSTED_FOUNDATIONS -#define CACHE_LINE_SIZE 32 - static inline void tegra_l2x0_disable_tz(void) { static u32 l2x0_way_mask; @@ -244,20 +242,19 @@ static inline void tegra_l2x0_disable_tz(void) l2x0_way_mask = (1 << ways) - 1; } #ifdef CONFIG_ARCH_TEGRA_2x_SOC - /* flush all ways on disable */ + /* flush all ways on any disable */ tegra_generic_smc_uncached(0xFFFFF100, 0x00000002, l2x0_way_mask); #elif defined(CONFIG_ARCH_TEGRA_3x_SOC) - if (tegra_is_cpu_in_lp2(0)) { - register unsigned long sp asm ("sp"); - - /* flush only the stack, if entering LP2 */ - __cpuc_flush_dcache_area((void *)sp, (CACHE_LINE_SIZE * 2)); - outer_flush_range(__pa(sp), __pa(sp) + (CACHE_LINE_SIZE * 2)); - - /* pass zero arg, so secureos flushes only its workspace */ - tegra_generic_smc_uncached(0xFFFFF100, 0x00000002, 0x0); - } else { - /* flush all ways on disable, if entering LP0/LP1 */ + if (tegra_is_cpu_in_lp2(0) == false) { + /* + * If entering LP0/LP1, ask secureos to fully flush and + * disable the L2. + * + * If entering LP2, L2 disable is handled by the secureos + * as part of the tegra_sleep_cpu() SMC. This SMC indicates + * no more secureos tasks will be scheduled, allowing it + * to optimize out L2 flushes on its side. + */ tegra_generic_smc_uncached(0xFFFFF100, 0x00000002, l2x0_way_mask); } diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c index 2cdfdfe6f43d..b20b51245d50 100644 --- a/arch/arm/mach-tegra/pm.c +++ b/arch/arm/mach-tegra/pm.c @@ -579,6 +579,16 @@ static void tegra_sleep_core(enum tegra_suspend_mode mode, static inline void tegra_sleep_cpu(unsigned long v2p) { #ifdef CONFIG_TRUSTED_FOUNDATIONS + if (tegra_is_cpu_in_lp2(0)) { + struct thread_info *thread; + + /* flush thread state (sleep SMC will also disable L2) */ + thread = current_thread_info(); + BUG_ON(!thread); + + __cpuc_flush_dcache_area(thread, THREAD_SIZE); + outer_flush_range(__pa(thread), __pa(thread) + THREAD_SIZE); + } tegra_generic_smc_uncached(0xFFFFFFFC, 0xFFFFFFE4, (TEGRA_RESET_HANDLER_BASE + tegra_cpu_reset_handler_offset)); |