summaryrefslogtreecommitdiff
path: root/arch/arm/mm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm')
-rw-r--r--arch/arm/mm/cache-fa.S18
-rw-r--r--arch/arm/mm/cache-l2x0.c13
-rw-r--r--arch/arm/mm/cache-v3.S18
-rw-r--r--arch/arm/mm/cache-v4.S18
-rw-r--r--arch/arm/mm/cache-v4wb.S18
-rw-r--r--arch/arm/mm/cache-v4wt.S18
-rw-r--r--arch/arm/mm/cache-v6.S18
-rw-r--r--arch/arm/mm/cache-v7.S94
-rw-r--r--arch/arm/mm/mmu.c14
-rw-r--r--arch/arm/mm/proc-macros.S2
-rw-r--r--arch/arm/mm/proc-v7.S2
11 files changed, 223 insertions, 10 deletions
diff --git a/arch/arm/mm/cache-fa.S b/arch/arm/mm/cache-fa.S
index 07201637109..226f8736152 100644
--- a/arch/arm/mm/cache-fa.S
+++ b/arch/arm/mm/cache-fa.S
@@ -240,6 +240,24 @@ ENTRY(fa_dma_unmap_area)
mov pc, lr
ENDPROC(fa_dma_unmap_area)
+/*
+ * clean_dcache_all()
+ *
+ * Clean the whole D-cache.
+ */
+ENTRY(fa_clean_dcache_all)
+ mov pc, lr
+ENDPROC(fa_clean_dcache_all)
+
+/*
+ * flush_dcache_all()
+ *
+ * Flush the whole D-cache.
+ */
+ENTRY(fa_flush_dcache_all)
+ mov pc, lr
+ENDPROC(fa_flush_dcache_all)
+
__INITDATA
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 2a8e380501e..1768e4038fc 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -319,9 +319,6 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
- aux &= aux_mask;
- aux |= aux_val;
-
/* Determine the number of ways */
switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
case L2X0_CACHE_ID_PART_L310:
@@ -335,6 +332,13 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
sync_reg_offset = L2X0_DUMMY_REG;
#endif
outer_cache.set_debug = pl310_set_debug;
+
+ /*
+ * Set bit 22 in the auxiliary control register. If this bit
+ * is cleared, PL310 treats Normal Shared Non-cacheable
+ * accesses as Cacheable no-allocate.
+ */
+ aux_val |= 1 << 22;
break;
case L2X0_CACHE_ID_PART_L210:
ways = (aux >> 13) & 0xf;
@@ -362,6 +366,9 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
* accessing the below registers will fault.
*/
if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) {
+ aux &= aux_mask;
+ aux |= aux_val;
+
/* Make sure that I&D is not locked down when starting */
l2x0_unlock(cache_id);
diff --git a/arch/arm/mm/cache-v3.S b/arch/arm/mm/cache-v3.S
index c2301f22610..ab5bf508a2a 100644
--- a/arch/arm/mm/cache-v3.S
+++ b/arch/arm/mm/cache-v3.S
@@ -127,6 +127,24 @@ ENTRY(v3_dma_map_area)
ENDPROC(v3_dma_unmap_area)
ENDPROC(v3_dma_map_area)
+/*
+ * clean_dcache_all()
+ *
+ * Clean the whole D-cache.
+ */
+ENTRY(v3_clean_dcache_all)
+ mov pc, lr
+ENDPROC(v3_clean_dcache_all)
+
+/*
+ * flush_dcache_all()
+ *
+ * Flush the whole D-cache.
+ */
+ENTRY(v3_flush_dcache_all)
+ mov pc, lr
+ENDPROC(v3_flush_dcache_all)
+
__INITDATA
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S
index fd9bb7addc8..9d3a055127e 100644
--- a/arch/arm/mm/cache-v4.S
+++ b/arch/arm/mm/cache-v4.S
@@ -139,6 +139,24 @@ ENTRY(v4_dma_map_area)
ENDPROC(v4_dma_unmap_area)
ENDPROC(v4_dma_map_area)
+/*
+ * clean_dcache_all()
+ *
+ * Clean the whole D-cache.
+ */
+ENTRY(v4_clean_dcache_all)
+ mov pc, lr
+ENDPROC(v4_clean_dcache_all)
+
+/*
+ * flush_dcache_all()
+ *
+ * Flush the whole D-cache.
+ */
+ENTRY(v4_flush_dcache_all)
+ mov pc, lr
+ENDPROC(v4_flush_dcache_all)
+
__INITDATA
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S
index 4f2c14151cc..54d3cda4a89 100644
--- a/arch/arm/mm/cache-v4wb.S
+++ b/arch/arm/mm/cache-v4wb.S
@@ -251,6 +251,24 @@ ENTRY(v4wb_dma_unmap_area)
mov pc, lr
ENDPROC(v4wb_dma_unmap_area)
+/*
+ * clean_dcache_all()
+ *
+ * Clean the whole D-cache.
+ */
+ENTRY(v4wb_clean_dcache_all)
+ mov pc, lr
+ENDPROC(v4wb_clean_dcache_all)
+
+/*
+ * flush_dcache_all()
+ *
+ * Flush the whole D-cache.
+ */
+ENTRY(v4wb_flush_dcache_all)
+ mov pc, lr
+ENDPROC(v4wb_flush_dcache_all)
+
__INITDATA
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
diff --git a/arch/arm/mm/cache-v4wt.S b/arch/arm/mm/cache-v4wt.S
index 4d7b467631c..40f7dba11f5 100644
--- a/arch/arm/mm/cache-v4wt.S
+++ b/arch/arm/mm/cache-v4wt.S
@@ -195,6 +195,24 @@ ENTRY(v4wt_dma_map_area)
ENDPROC(v4wt_dma_unmap_area)
ENDPROC(v4wt_dma_map_area)
+/*
+ * clean_dcache_all()
+ *
+ * Clean the whole D-cache.
+ */
+ENTRY(v4wt_clean_dcache_all)
+ mov pc, lr
+ENDPROC(v4wt_clean_dcache_all)
+
+/*
+ * flush_dcache_all()
+ *
+ * Flush the whole D-cache.
+ */
+ENTRY(v4wt_flush_dcache_all)
+ mov pc, lr
+ENDPROC(v4wt_flush_dcache_all)
+
__INITDATA
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S
index 74c2e5a33a4..b88dd4ab038 100644
--- a/arch/arm/mm/cache-v6.S
+++ b/arch/arm/mm/cache-v6.S
@@ -328,6 +328,24 @@ ENTRY(v6_dma_unmap_area)
mov pc, lr
ENDPROC(v6_dma_unmap_area)
+/*
+ * clean_dcache_all()
+ *
+ * Clean the whole D-cache.
+ */
+ENTRY(v6_clean_dcache_all)
+ mov pc, lr
+ENDPROC(v6_clean_dcache_all)
+
+/*
+ * flush_dcache_all()
+ *
+ * Flush the whole D-cache.
+ */
+ENTRY(v6_flush_dcache_all)
+ mov pc, lr
+ENDPROC(v6_flush_dcache_all)
+
__INITDATA
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index a655d3da386..70744d6a066 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -33,7 +33,7 @@ ENTRY(v7_flush_icache_all)
ENDPROC(v7_flush_icache_all)
/*
- * v7_flush_dcache_all()
+ * __v7_flush_dcache_all()
*
* Flush the whole D-cache.
*
@@ -41,7 +41,7 @@ ENDPROC(v7_flush_icache_all)
*
* - mm - mm_struct describing address space
*/
-ENTRY(v7_flush_dcache_all)
+ENTRY(__v7_flush_dcache_all)
dmb @ ensure ordering with previous memory accesses
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
@@ -94,9 +94,93 @@ finished:
dsb
isb
mov pc, lr
+ENDPROC(__v7_flush_dcache_all)
+
+/*
+ * __v7_clean_dcache_all()
+ *
+ * Clean the whole D-cache.
+ *
+ * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
+ */
+ENTRY(__v7_clean_dcache_all)
+ dmb @ ensure ordering with previous memory accesses
+ 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 finished1 @ if loc is 0, then no need to clean
+ mov r10, #0 @ start clean at cache level 0
+loop21:
+ 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
+ cmp r1, #2 @ see what cache we have at this level
+ blt skip1 @ skip if no cache, or just i-cache
+ mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
+ isb @ isb to sych the new cssr&csidr
+ mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
+ and r2, r1, #7 @ extract the length of the cache lines
+ add r2, r2, #4 @ add 4 (line length offset)
+ ldr r4, =0x3ff
+ ands r4, r4, r1, lsr #3 @ find maximum number on the way size
+ clz r5, r4 @ find bit position of way size increment
+ ldr r7, =0x7fff
+ ands r7, r7, r1, lsr #13 @ extract max number of the index size
+loop22:
+ mov r9, r4 @ create working copy of max way size
+loop23:
+ ARM( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
+ THUMB( lsl r6, r9, r5 )
+ THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
+ ARM( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
+ THUMB( lsl r6, r7, r2 )
+ THUMB( orr r11, r11, r6 ) @ factor index number into r11
+ mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
+ subs r9, r9, #1 @ decrement the way
+ bge loop23
+ subs r7, r7, #1 @ decrement the index
+ bge loop22
+skip1:
+ add r10, r10, #2 @ increment cache number
+ cmp r3, r10
+ bgt loop21
+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_clean_dcache_all)
+
+/*
+ * v7_flush_dcache_all()
+ *
+ * Flush the whole D-cache.
+ */
+ENTRY(v7_flush_dcache_all)
+ ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} )
+ THUMB( stmfd sp!, {r4-r7, r9-r11, lr} )
+ bl __v7_flush_dcache_all
+ ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} )
+ THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} )
+ mov pc, lr
ENDPROC(v7_flush_dcache_all)
/*
+ * v7_clean_dcache_all()
+ *
+ * Clean the whole D-cache.
+ */
+ENTRY(v7_clean_dcache_all)
+ ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} )
+ THUMB( stmfd sp!, {r4-r7, r9-r11, lr} )
+ bl __v7_clean_dcache_all
+ ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} )
+ THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} )
+ mov pc, lr
+ENDPROC(v7_clean_dcache_all)
+
+/*
* v7_flush_cache_all()
*
* Flush the entire cache system.
@@ -108,14 +192,12 @@ 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} )
+ stmfd sp!, {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} )
+ ldmfd sp!, {lr}
mov pc, lr
ENDPROC(v7_flush_kern_cache_all)
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index aa78de8bfdd..4ecd1f8bbb5 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -288,6 +288,20 @@ static struct mem_type mem_types[] = {
PMD_SECT_UNCACHED | PMD_SECT_XN,
.domain = DOMAIN_KERNEL,
},
+ /* NOTE : this is only a temporary hack!!!
+ * The U8500 ED/V1.0 cuts require such a
+ * memory type for deep sleep resume.
+ * This is expected to be solved in cut v2.0
+ * and we clean this up then. for more details
+ * look @ the commit message please
+ */
+ [MT_BACKUP_RAM] = {
+ .prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_SHARED |
+ L_PTE_SHARED,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PROT_SECT_DEVICE | PMD_SECT_S,
+ .domain = DOMAIN_IO,
+ },
};
const struct mem_type *get_mem_type(unsigned int type)
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 2d8ff3ad86d..518ab10fea5 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -304,6 +304,8 @@ ENTRY(\name\()_cache_fns)
.long \name\()_coherent_kern_range
.long \name\()_coherent_user_range
.long \name\()_flush_kern_dcache_area
+ .long \name\()_clean_dcache_all
+ .long \name\()_flush_dcache_all
.long \name\()_dma_map_area
.long \name\()_dma_unmap_area
.long \name\()_dma_flush_range
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index c2e2b66f72b..d1c42ead765 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -172,7 +172,7 @@ __v7_ca15mp_setup:
__v7_setup:
adr r12, __v7_setup_stack @ the local stack
stmia r12, {r0-r5, r7, r9, r11, lr}
- bl v7_flush_dcache_all
+ bl __v7_flush_dcache_all
ldmia r12, {r0-r5, r7, r9, r11, lr}
mrc p15, 0, r0, c0, c0, 0 @ read main ID register