summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Johnson <cwj@nvidia.com>2012-08-24 17:27:58 -0700
committerMrutyunjay Sawant <msawant@nvidia.com>2012-09-06 04:12:10 -0700
commit3bdf9371b4e75e3dc9612360ab55924587714155 (patch)
treee7ade21f067a47681c4384e13a90475ee194cda0
parent32b8cc820fc9f3709c23e6b383825d6cdb0a6085 (diff)
arm: tegra: secureos: disable L2 as part of sleep CPU SMC
This is an alternate way to have the L2 disabled available with later TL secureos versions. In this version, the sleep CPU SMC which is the last one issued before entering LP2 on CPU0, will also disable the L2 without a flush of the secureos workspace. Change-Id: I61c3caade6cb6f922b9d9f9ca0739bc6ae4e78cd Signed-off-by: Hyung Taek Ryoo <hryoo@nvidia.com> Reviewed-on: http://git-master/r/128951 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: James Zhao <jamesz@nvidia.com> Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/common.c25
-rw-r--r--arch/arm/mach-tegra/pm.c10
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));