summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/sleep34xx.S
diff options
context:
space:
mode:
authorSantosh Shilimkar <santosh.shilimkar@ti.com>2011-01-23 18:21:09 +0100
committerKevin Hilman <khilman@ti.com>2011-03-10 21:23:13 +0100
commit9062511097683b4422f023d181b4a8b2db1a7a72 (patch)
tree9e46fb8c0491a26bb25464d90b6cd4caf92edf5b /arch/arm/mach-omap2/sleep34xx.S
parentOMAP3: PM: Remove un-necessary cp15 registers form low power cpu context (diff)
downloadlinux-9062511097683b4422f023d181b4a8b2db1a7a72.tar.xz
linux-9062511097683b4422f023d181b4a8b2db1a7a72.zip
OMAP3: PM: Clear the SCTLR C bit in asm code to prevent data cache allocation
On the newer ARM processors like CortexA8, CortexA9, the caches can be speculatively loaded while they are getting flushed. Clear the SCTLR C bit to prevent further data cache allocation as part of cache clean routine Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Signed-off-by: Kevin Hilman <khilman@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2/sleep34xx.S')
-rw-r--r--arch/arm/mach-omap2/sleep34xx.S27
1 files changed, 27 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index 99e43cc5a503..e60ac1f71bd4 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -246,6 +246,27 @@ clean_caches:
* - it executes in a cached space so is faster than refetch per-block
* - should be faster and will change with kernel
* - 'might' have to copy address, load and jump to it
+ * Flush all data from the L1 data cache before disabling
+ * SCTLR.C bit.
+ */
+ ldr r1, kernel_flush
+ mov lr, pc
+ bx r1
+
+ /*
+ * Clear the SCTLR.C bit to prevent further data cache
+ * allocation. Clearing SCTLR.C would make all the data accesses
+ * strongly ordered and would not hit the cache.
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #(1 << 2) @ Disable the C bit
+ mcr p15, 0, r0, c1, c0, 0
+ isb
+
+ /*
+ * Invalidate L1 data cache. Even though only invalidate is
+ * necessary exported flush API is used here. Doing clean
+ * on already clean cache would be almost NOP.
*/
ldr r1, kernel_flush
blx r1
@@ -295,6 +316,12 @@ omap3_do_wfi:
nop
bl wait_sdrc_ok
+ mrc p15, 0, r0, c1, c0, 0
+ tst r0, #(1 << 2) @ Check C bit enabled?
+ orreq r0, r0, #(1 << 2) @ Enable the C bit if cleared
+ mcreq p15, 0, r0, c1, c0, 0
+ isb
+
/*
* ===================================
* == Exit point from non-OFF modes ==