aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm')
-rw-r--r--arch/arm/mm/Kconfig8
-rw-r--r--arch/arm/mm/cache-feroceon-l2.c42
-rw-r--r--arch/arm/mm/proc-feroceon.S12
3 files changed, 41 insertions, 21 deletions
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index ed15f876c725..330814d1ee25 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -735,6 +735,14 @@ config CACHE_FEROCEON_L2
735 help 735 help
736 This option enables the Feroceon L2 cache controller. 736 This option enables the Feroceon L2 cache controller.
737 737
738config CACHE_FEROCEON_L2_WRITETHROUGH
739 bool "Force Feroceon L2 cache write through"
740 depends on CACHE_FEROCEON_L2
741 default n
742 help
743 Say Y here to use the Feroceon L2 cache in writethrough mode.
744 Unless you specifically require this, say N for writeback mode.
745
738config CACHE_L2X0 746config CACHE_L2X0
739 bool "Enable the L2x0 outer cache controller" 747 bool "Enable the L2x0 outer cache controller"
740 depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 748 depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176
diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
index 7b5a25d81576..13cdae8b0d44 100644
--- a/arch/arm/mm/cache-feroceon-l2.c
+++ b/arch/arm/mm/cache-feroceon-l2.c
@@ -48,11 +48,12 @@ static inline void l2_clean_mva_range(unsigned long start, unsigned long end)
48 * L2 is PIPT and range operations only do a TLB lookup on 48 * L2 is PIPT and range operations only do a TLB lookup on
49 * the start address. 49 * the start address.
50 */ 50 */
51 BUG_ON((start ^ end) & ~(PAGE_SIZE - 1)); 51 BUG_ON((start ^ end) >> PAGE_SHIFT);
52 52
53 raw_local_irq_save(flags); 53 raw_local_irq_save(flags);
54 __asm__("mcr p15, 1, %0, c15, c9, 4" : : "r" (start)); 54 __asm__("mcr p15, 1, %0, c15, c9, 4\n\t"
55 __asm__("mcr p15, 1, %0, c15, c9, 5" : : "r" (end)); 55 "mcr p15, 1, %1, c15, c9, 5"
56 : : "r" (start), "r" (end));
56 raw_local_irq_restore(flags); 57 raw_local_irq_restore(flags);
57} 58}
58 59
@@ -80,11 +81,12 @@ static inline void l2_inv_mva_range(unsigned long start, unsigned long end)
80 * L2 is PIPT and range operations only do a TLB lookup on 81 * L2 is PIPT and range operations only do a TLB lookup on
81 * the start address. 82 * the start address.
82 */ 83 */
83 BUG_ON((start ^ end) & ~(PAGE_SIZE - 1)); 84 BUG_ON((start ^ end) >> PAGE_SHIFT);
84 85
85 raw_local_irq_save(flags); 86 raw_local_irq_save(flags);
86 __asm__("mcr p15, 1, %0, c15, c11, 4" : : "r" (start)); 87 __asm__("mcr p15, 1, %0, c15, c11, 4\n\t"
87 __asm__("mcr p15, 1, %0, c15, c11, 5" : : "r" (end)); 88 "mcr p15, 1, %1, c15, c11, 5"
89 : : "r" (start), "r" (end));
88 raw_local_irq_restore(flags); 90 raw_local_irq_restore(flags);
89} 91}
90 92
@@ -205,7 +207,7 @@ static void feroceon_l2_flush_range(unsigned long start, unsigned long end)
205 * time. These are necessary because the L2 cache can only be enabled 207 * time. These are necessary because the L2 cache can only be enabled
206 * or disabled while the L1 Dcache and Icache are both disabled. 208 * or disabled while the L1 Dcache and Icache are both disabled.
207 */ 209 */
208static void __init invalidate_and_disable_dcache(void) 210static int __init flush_and_disable_dcache(void)
209{ 211{
210 u32 cr; 212 u32 cr;
211 213
@@ -217,7 +219,9 @@ static void __init invalidate_and_disable_dcache(void)
217 flush_cache_all(); 219 flush_cache_all();
218 set_cr(cr & ~CR_C); 220 set_cr(cr & ~CR_C);
219 raw_local_irq_restore(flags); 221 raw_local_irq_restore(flags);
222 return 1;
220 } 223 }
224 return 0;
221} 225}
222 226
223static void __init enable_dcache(void) 227static void __init enable_dcache(void)
@@ -225,18 +229,17 @@ static void __init enable_dcache(void)
225 u32 cr; 229 u32 cr;
226 230
227 cr = get_cr(); 231 cr = get_cr();
228 if (!(cr & CR_C)) 232 set_cr(cr | CR_C);
229 set_cr(cr | CR_C);
230} 233}
231 234
232static void __init __invalidate_icache(void) 235static void __init __invalidate_icache(void)
233{ 236{
234 int dummy; 237 int dummy;
235 238
236 __asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0\n" : "=r" (dummy)); 239 __asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0" : "=r" (dummy));
237} 240}
238 241
239static void __init invalidate_and_disable_icache(void) 242static int __init invalidate_and_disable_icache(void)
240{ 243{
241 u32 cr; 244 u32 cr;
242 245
@@ -244,7 +247,9 @@ static void __init invalidate_and_disable_icache(void)
244 if (cr & CR_I) { 247 if (cr & CR_I) {
245 set_cr(cr & ~CR_I); 248 set_cr(cr & ~CR_I);
246 __invalidate_icache(); 249 __invalidate_icache();
250 return 1;
247 } 251 }
252 return 0;
248} 253}
249 254
250static void __init enable_icache(void) 255static void __init enable_icache(void)
@@ -252,8 +257,7 @@ static void __init enable_icache(void)
252 u32 cr; 257 u32 cr;
253 258
254 cr = get_cr(); 259 cr = get_cr();
255 if (!(cr & CR_I)) 260 set_cr(cr | CR_I);
256 set_cr(cr | CR_I);
257} 261}
258 262
259static inline u32 read_extra_features(void) 263static inline u32 read_extra_features(void)
@@ -291,13 +295,17 @@ static void __init enable_l2(void)
291 295
292 u = read_extra_features(); 296 u = read_extra_features();
293 if (!(u & 0x00400000)) { 297 if (!(u & 0x00400000)) {
298 int i, d;
299
294 printk(KERN_INFO "Feroceon L2: Enabling L2\n"); 300 printk(KERN_INFO "Feroceon L2: Enabling L2\n");
295 301
296 invalidate_and_disable_dcache(); 302 d = flush_and_disable_dcache();
297 invalidate_and_disable_icache(); 303 i = invalidate_and_disable_icache();
298 write_extra_features(u | 0x00400000); 304 write_extra_features(u | 0x00400000);
299 enable_icache(); 305 if (i)
300 enable_dcache(); 306 enable_icache();
307 if (d)
308 enable_dcache();
301 } 309 }
302} 310}
303 311
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index 2b8bb383755e..0fe1f8fc3488 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -80,7 +80,8 @@ ENTRY(cpu_feroceon_proc_fin)
80 msr cpsr_c, ip 80 msr cpsr_c, ip
81 bl feroceon_flush_kern_cache_all 81 bl feroceon_flush_kern_cache_all
82 82
83#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH) 83#if defined(CONFIG_CACHE_FEROCEON_L2) && \
84 !defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
84 mov r0, #0 85 mov r0, #0
85 mcr p15, 1, r0, c15, c9, 0 @ clean L2 86 mcr p15, 1, r0, c15, c9, 0 @ clean L2
86 mcr p15, 0, r0, c7, c10, 4 @ drain WB 87 mcr p15, 0, r0, c7, c10, 4 @ drain WB
@@ -389,7 +390,8 @@ ENTRY(feroceon_range_cache_fns)
389 390
390 .align 5 391 .align 5
391ENTRY(cpu_feroceon_dcache_clean_area) 392ENTRY(cpu_feroceon_dcache_clean_area)
392#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH) 393#if defined(CONFIG_CACHE_FEROCEON_L2) && \
394 !defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
393 mov r2, r0 395 mov r2, r0
394 mov r3, r1 396 mov r3, r1
395#endif 397#endif
@@ -397,7 +399,8 @@ ENTRY(cpu_feroceon_dcache_clean_area)
397 add r0, r0, #CACHE_DLINESIZE 399 add r0, r0, #CACHE_DLINESIZE
398 subs r1, r1, #CACHE_DLINESIZE 400 subs r1, r1, #CACHE_DLINESIZE
399 bhi 1b 401 bhi 1b
400#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH) 402#if defined(CONFIG_CACHE_FEROCEON_L2) && \
403 !defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
4011: mcr p15, 1, r2, c15, c9, 1 @ clean L2 entry 4041: mcr p15, 1, r2, c15, c9, 1 @ clean L2 entry
402 add r2, r2, #CACHE_DLINESIZE 405 add r2, r2, #CACHE_DLINESIZE
403 subs r3, r3, #CACHE_DLINESIZE 406 subs r3, r3, #CACHE_DLINESIZE
@@ -449,7 +452,8 @@ ENTRY(cpu_feroceon_set_pte_ext)
449 armv3_set_pte_ext wc_disable=0 452 armv3_set_pte_ext wc_disable=0
450 mov r0, r0 453 mov r0, r0
451 mcr p15, 0, r0, c7, c10, 1 @ clean D entry 454 mcr p15, 0, r0, c7, c10, 1 @ clean D entry
452#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH) 455#if defined(CONFIG_CACHE_FEROCEON_L2) && \
456 !defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
453 mcr p15, 1, r0, c15, c9, 1 @ clean L2 entry 457 mcr p15, 1, r0, c15, c9, 1 @ clean L2 entry
454#endif 458#endif
455 mcr p15, 0, r0, c7, c10, 4 @ drain WB 459 mcr p15, 0, r0, c7, c10, 4 @ drain WB