summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorChris Johnson <cwj@nvidia.com>2011-10-03 17:08:36 -0700
committerRyan Wong <ryanw@nvidia.com>2011-10-04 15:47:36 -0700
commit89df4a6ca6435388ea7f3bd5d7aab1e98e27ac34 (patch)
treeae61de692311bc312b866038f3d4df021a6ec59b /arch
parentebd5224ed3b97c2f4eb8e6135121d873950facd7 (diff)
arm: tegra: secureos: restore L2 AUX_CTRL during LP0 resume
In the previous code, we relied on l2x0_restart to reenable the L2. But this interface doesn't allow the AUX_CTRL to be specified, so is unable to pass it through to the SMC. We now, just make the same underlying SMC call to restart the L2, passing our saved AUX_CTRL setting. Bug 868056 Change-Id: Ic2024bcb8df3167f00d04bba446b59696e376306 Reviewed-on: http://git-master/r/55845 Reviewed-by: Ryan Wong <ryanw@nvidia.com> Tested-by: Ryan Wong <ryanw@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/cortex-a9.S54
-rw-r--r--arch/arm/mach-tegra/power.h1
-rw-r--r--arch/arm/mach-tegra/suspend.c2
3 files changed, 56 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/cortex-a9.S b/arch/arm/mach-tegra/cortex-a9.S
index da571910ca06..30d4ec9a30c7 100644
--- a/arch/arm/mach-tegra/cortex-a9.S
+++ b/arch/arm/mach-tegra/cortex-a9.S
@@ -715,6 +715,60 @@ l2_done:
b __cortex_a9_restore
+/*
+ * __cortex_a9_l2x0_reenable(void)
+ *
+ * This reenables L2 after a power event. It is called from
+ * tegra_suspend_dram (and differs between default and secureos
+ * environments).
+ *
+ * In a default build, __cortex_a9_l2x0_restart is able to
+ * restore all the full L2 config from saved state. Note: at
+ * the time it was saved the L2X0_CTRL would've been disabled,
+ * but since all the other state had been restored, calling
+ * l2x0_restart is sufficient.
+ *
+ * In a secureos build, __cortex_a9_l2x0_restart is non-secure
+ * so it can't restore any registers. Like the default path,
+ * L2X0_CTRL was saved as disabled (and we can't/don't make
+ * the SMC to have it reenabled).
+ *
+ * The problem with just calling l2x0_restart like the default
+ * build is it doesn't support an update of the AUX_CTRL, so
+ * would leave it at the POR value. Instead, we make the same
+ * SMC as l2x0_restart would, but supplying our saved AUX_CTRL.
+ */
+ .align L1_CACHE_SHIFT
+ENTRY(__cortex_a9_l2x0_reenable)
+#ifndef CONFIG_TRUSTED_FOUNDATIONS
+ b l2x0_restart
+#else
+ /* nothing to do, if already enabled */
+ mov32 r0, (TEGRA_ARM_PL310_BASE-IO_CPU_PHYS+IO_CPU_VIRT)
+ ldr r1, [r0, #L2X0_CTRL]
+ cmp r1, #0
+ bne reenable_done
+
+ stmfd sp!, {r3-r4}
+
+ ctx_ptr r4, r3
+ add r3, r4, #CTX_L2_AUX
+ ldr r4, [r3]
+
+ ldr r0, =0xFFFFF100
+ mov r1, #1 @ restart opcode
+ mov r2, r4 @ AUX register
+ ldr r3, =0x00000000
+ ldr r4, =0x00000000
+ smc 0
+
+ ldmfd sp!, {r3-r4}
+reenable_done:
+ bx lr
+#endif
+ENDPROC(__cortex_a9_l2x0_reenable)
+
+
.align L1_CACHE_SHIFT
ENTRY(__shut_off_mmu)
mrc p15, 0, r3, c1, c0, 0
diff --git a/arch/arm/mach-tegra/power.h b/arch/arm/mach-tegra/power.h
index 5e462aceef50..40fb76733c69 100644
--- a/arch/arm/mach-tegra/power.h
+++ b/arch/arm/mach-tegra/power.h
@@ -130,6 +130,7 @@ void tegra_lp2_in_idle(bool enable);
unsigned long tegra_lp2_timer_remain(void);
void __cortex_a9_save(unsigned int mode);
void __cortex_a9_restore(void);
+void __cortex_a9_l2x0_reenable(void);
void __shut_off_mmu(void);
void tegra_secondary_startup(void);
void tegra_lp2_startup(void);
diff --git a/arch/arm/mach-tegra/suspend.c b/arch/arm/mach-tegra/suspend.c
index 933c9b3e3611..921be57346af 100644
--- a/arch/arm/mach-tegra/suspend.c
+++ b/arch/arm/mach-tegra/suspend.c
@@ -734,7 +734,7 @@ void tegra_suspend_dram(bool do_lp0)
restore_cpu_complex();
#ifdef CONFIG_CACHE_L2X0
- l2x0_restart();
+ __cortex_a9_l2x0_reenable();
#endif
if (!do_lp0) {