[PATCH 1/2] ARM: mm: Add v7_flush_dcache_by_level() API.
Santosh Shilimkar
santosh.shilimkar at ti.com
Thu Apr 12 07:29:46 EDT 2012
From: R Sricharan <r.sricharan at ti.com>
On ARMv7 based SOC with an integrated L2 cache, there is a need
to have a flush API to operate on each cache level. In few low
power modes, L2 cache is retained where as L1 is lost. The current
v7_flush_dcache_all(), flushes all the levels and it would be quite
expensive.
So introduce v7_flush_dcache_by_level() API which takes a
parameter (cache level), and flush only on that level.
Signed-off-by: Santosh Shilimkar <santosh.shilimkar at ti.com>
Signed-off-by: Sricharan R <r.sricharan at ti.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Russell King <rmk+kernel at arm.linux.org.uk>
---
arch/arm/mm/cache-v7.S | 56 ++++++++++++++++++++++++++++++++++++++---------
1 files changed, 45 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index a655d3d..cbeff42 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -43,12 +43,32 @@ ENDPROC(v7_flush_icache_all)
*/
ENTRY(v7_flush_dcache_all)
dmb @ ensure ordering with previous memory accesses
+ mov r8, lr @ store lr
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq finished @ if loc is 0, then no need to clean
mov r10, #0 @ start clean at cache level 0
loop1:
+ bl v7_flush_dcache_current_level
+skip:
+ add r10, r10, #2 @ increment cache number
+ cmp r3, r10 @
+ bgt loop1
+finished:
+ mov r10, #0 @ swith back to cache level 0
+ mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
+ dsb
+ isb
+ mov pc, r8 @ restore lr
+ENDPROC(v7_flush_dcache_all)
+/*
+ * v7_flush_dcache_current_level()
+ *
+ * Flush the D-cache by specifed level like l1, l2 etc.
+ * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
+ */
+ENTRY(v7_flush_dcache_current_level)
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
@@ -84,17 +104,31 @@ loop3:
bge loop3
subs r7, r7, #1 @ decrement the index
bge loop2
-skip:
- add r10, r10, #2 @ increment cache number
- cmp r3, r10
- bgt loop1
-finished:
+ mov pc, lr
+ENDPROC(v7_flush_dcache_current_level)
+
+/*
+ * v7_flush_dcache_by_level()
+ * r0 - cache level to be flushed
+ *
+ * Flush the D-cache by specifed level like l1, l2 etc.
+ * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
+ */
+ENTRY(v7_flush_dcache_by_level)
+ dmb @ ensure ordering with previous memory accesses
+ mov r8, lr @ store the lr
+ mov r10, r0 @ temp storage
+ sub r10, r10, #1
+ mov r10, r10, lsl #1
+ mrc p15, 1, r0, c0, c0, 1 @ read clidr
+ bl v7_flush_dcache_current_level
+finished1:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
dsb
isb
- mov pc, lr
-ENDPROC(v7_flush_dcache_all)
+ mov pc, r8 @ restore lr
+ENDPROC(v7_flush_dcache_by_level)
/*
* v7_flush_cache_all()
@@ -108,14 +142,14 @@ ENDPROC(v7_flush_dcache_all)
*
*/
ENTRY(v7_flush_kern_cache_all)
- ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} )
- THUMB( stmfd sp!, {r4-r7, r9-r11, lr} )
+ ARM( stmfd sp!, {r4-r5, r7-r11, lr} )
+ THUMB( stmfd sp!, {r4-r11, lr} )
bl v7_flush_dcache_all
mov r0, #0
ALT_SMP(mcr p15, 0, r0, c7, c1, 0) @ invalidate I-cache inner shareable
ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate
- ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} )
- THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} )
+ ARM( ldmfd sp!, {r4-r5, r7-r11, lr} )
+ THUMB( ldmfd sp!, {r4-r11, lr} )
mov pc, lr
ENDPROC(v7_flush_kern_cache_all)
--
1.7.5.4
More information about the linux-arm-kernel
mailing list