diff options
author | Santosh Shilimkar <santosh.shilimkar@ti.com> | 2011-01-23 20:21:09 +0300 |
---|---|---|
committer | Kevin Hilman <khilman@ti.com> | 2011-03-10 23:23:13 +0300 |
commit | 9062511097683b4422f023d181b4a8b2db1a7a72 (patch) | |
tree | 9e46fb8c0491a26bb25464d90b6cd4caf92edf5b /arch/arm/mach-omap2 | |
parent | 46f557cb453b9f3b6dc36b8179c2c36932a2ea64 (diff) | |
download | linux-9062511097683b4422f023d181b4a8b2db1a7a72.tar.xz |
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')
-rw-r--r-- | arch/arm/mach-omap2/sleep34xx.S | 27 |
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 == |