diff options
Diffstat (limited to 'arch/sh/mm')
-rw-r--r-- | arch/sh/mm/Kconfig | 2 | ||||
-rw-r--r-- | arch/sh/mm/cache-sh4.c | 27 | ||||
-rw-r--r-- | arch/sh/mm/cache.c | 10 |
3 files changed, 25 insertions, 14 deletions
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 64dc1ad59801..7f7b52f9beba 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig | |||
@@ -227,7 +227,7 @@ endchoice | |||
227 | 227 | ||
228 | choice | 228 | choice |
229 | prompt "HugeTLB page size" | 229 | prompt "HugeTLB page size" |
230 | depends on HUGETLB_PAGE && (CPU_SH4 || CPU_SH5) && MMU | 230 | depends on HUGETLB_PAGE |
231 | default HUGETLB_PAGE_SIZE_1MB if PAGE_SIZE_64KB | 231 | default HUGETLB_PAGE_SIZE_1MB if PAGE_SIZE_64KB |
232 | default HUGETLB_PAGE_SIZE_64K | 232 | default HUGETLB_PAGE_SIZE_64K |
233 | 233 | ||
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c index a98c7d8984fa..b7f235c74d66 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #define MAX_DCACHE_PAGES 64 /* XXX: Tune for ways */ | 26 | #define MAX_DCACHE_PAGES 64 /* XXX: Tune for ways */ |
27 | #define MAX_ICACHE_PAGES 32 | 27 | #define MAX_ICACHE_PAGES 32 |
28 | 28 | ||
29 | static void __flush_cache_4096(unsigned long addr, unsigned long phys, | 29 | static void __flush_cache_one(unsigned long addr, unsigned long phys, |
30 | unsigned long exec_offset); | 30 | unsigned long exec_offset); |
31 | 31 | ||
32 | /* | 32 | /* |
@@ -72,6 +72,7 @@ static void __uses_jump_to_uncached sh4_flush_icache_range(void *args) | |||
72 | 72 | ||
73 | for (v = start; v < end; v += L1_CACHE_BYTES) { | 73 | for (v = start; v < end; v += L1_CACHE_BYTES) { |
74 | unsigned long icacheaddr; | 74 | unsigned long icacheaddr; |
75 | int j, n; | ||
75 | 76 | ||
76 | __ocbwb(v); | 77 | __ocbwb(v); |
77 | 78 | ||
@@ -79,8 +80,10 @@ static void __uses_jump_to_uncached sh4_flush_icache_range(void *args) | |||
79 | cpu_data->icache.entry_mask); | 80 | cpu_data->icache.entry_mask); |
80 | 81 | ||
81 | /* Clear i-cache line valid-bit */ | 82 | /* Clear i-cache line valid-bit */ |
83 | n = boot_cpu_data.icache.n_aliases; | ||
82 | for (i = 0; i < cpu_data->icache.ways; i++) { | 84 | for (i = 0; i < cpu_data->icache.ways; i++) { |
83 | __raw_writel(0, icacheaddr); | 85 | for (j = 0; j < n; j++) |
86 | __raw_writel(0, icacheaddr + (j * PAGE_SIZE)); | ||
84 | icacheaddr += cpu_data->icache.way_incr; | 87 | icacheaddr += cpu_data->icache.way_incr; |
85 | } | 88 | } |
86 | } | 89 | } |
@@ -89,8 +92,7 @@ static void __uses_jump_to_uncached sh4_flush_icache_range(void *args) | |||
89 | local_irq_restore(flags); | 92 | local_irq_restore(flags); |
90 | } | 93 | } |
91 | 94 | ||
92 | static inline void flush_cache_4096(unsigned long start, | 95 | static inline void flush_cache_one(unsigned long start, unsigned long phys) |
93 | unsigned long phys) | ||
94 | { | 96 | { |
95 | unsigned long flags, exec_offset = 0; | 97 | unsigned long flags, exec_offset = 0; |
96 | 98 | ||
@@ -103,8 +105,7 @@ static inline void flush_cache_4096(unsigned long start, | |||
103 | exec_offset = 0x20000000; | 105 | exec_offset = 0x20000000; |
104 | 106 | ||
105 | local_irq_save(flags); | 107 | local_irq_save(flags); |
106 | __flush_cache_4096(start | SH_CACHE_ASSOC, | 108 | __flush_cache_one(start | SH_CACHE_ASSOC, P1SEGADDR(phys), exec_offset); |
107 | P1SEGADDR(phys), exec_offset); | ||
108 | local_irq_restore(flags); | 109 | local_irq_restore(flags); |
109 | } | 110 | } |
110 | 111 | ||
@@ -129,8 +130,8 @@ static void sh4_flush_dcache_page(void *arg) | |||
129 | 130 | ||
130 | /* Loop all the D-cache */ | 131 | /* Loop all the D-cache */ |
131 | n = boot_cpu_data.dcache.n_aliases; | 132 | n = boot_cpu_data.dcache.n_aliases; |
132 | for (i = 0; i < n; i++, addr += 4096) | 133 | for (i = 0; i < n; i++, addr += PAGE_SIZE) |
133 | flush_cache_4096(addr, phys); | 134 | flush_cache_one(addr, phys); |
134 | } | 135 | } |
135 | 136 | ||
136 | wmb(); | 137 | wmb(); |
@@ -318,11 +319,11 @@ static void sh4_flush_cache_page(void *args) | |||
318 | /* We only need to flush D-cache when we have alias */ | 319 | /* We only need to flush D-cache when we have alias */ |
319 | if ((address^phys) & alias_mask) { | 320 | if ((address^phys) & alias_mask) { |
320 | /* Loop 4K of the D-cache */ | 321 | /* Loop 4K of the D-cache */ |
321 | flush_cache_4096( | 322 | flush_cache_one( |
322 | CACHE_OC_ADDRESS_ARRAY | (address & alias_mask), | 323 | CACHE_OC_ADDRESS_ARRAY | (address & alias_mask), |
323 | phys); | 324 | phys); |
324 | /* Loop another 4K of the D-cache */ | 325 | /* Loop another 4K of the D-cache */ |
325 | flush_cache_4096( | 326 | flush_cache_one( |
326 | CACHE_OC_ADDRESS_ARRAY | (phys & alias_mask), | 327 | CACHE_OC_ADDRESS_ARRAY | (phys & alias_mask), |
327 | phys); | 328 | phys); |
328 | } | 329 | } |
@@ -337,7 +338,7 @@ static void sh4_flush_cache_page(void *args) | |||
337 | * kernel has never executed the code through its identity | 338 | * kernel has never executed the code through its identity |
338 | * translation. | 339 | * translation. |
339 | */ | 340 | */ |
340 | flush_cache_4096( | 341 | flush_cache_one( |
341 | CACHE_IC_ADDRESS_ARRAY | (address & alias_mask), | 342 | CACHE_IC_ADDRESS_ARRAY | (address & alias_mask), |
342 | phys); | 343 | phys); |
343 | } | 344 | } |
@@ -393,7 +394,7 @@ static void sh4_flush_cache_range(void *args) | |||
393 | } | 394 | } |
394 | 395 | ||
395 | /** | 396 | /** |
396 | * __flush_cache_4096 | 397 | * __flush_cache_one |
397 | * | 398 | * |
398 | * @addr: address in memory mapped cache array | 399 | * @addr: address in memory mapped cache array |
399 | * @phys: P1 address to flush (has to match tags if addr has 'A' bit | 400 | * @phys: P1 address to flush (has to match tags if addr has 'A' bit |
@@ -406,7 +407,7 @@ static void sh4_flush_cache_range(void *args) | |||
406 | * operation (purge/write-back) is selected by the lower 2 bits of | 407 | * operation (purge/write-back) is selected by the lower 2 bits of |
407 | * 'phys'. | 408 | * 'phys'. |
408 | */ | 409 | */ |
409 | static void __flush_cache_4096(unsigned long addr, unsigned long phys, | 410 | static void __flush_cache_one(unsigned long addr, unsigned long phys, |
410 | unsigned long exec_offset) | 411 | unsigned long exec_offset) |
411 | { | 412 | { |
412 | int way_count; | 413 | int way_count; |
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c index 5e1091be9dc4..a2dc7f9ecc51 100644 --- a/arch/sh/mm/cache.c +++ b/arch/sh/mm/cache.c | |||
@@ -265,6 +265,8 @@ static void __init emit_cache_params(void) | |||
265 | 265 | ||
266 | void __init cpu_cache_init(void) | 266 | void __init cpu_cache_init(void) |
267 | { | 267 | { |
268 | unsigned int cache_disabled = !(__raw_readl(CCR) & CCR_CACHE_ENABLE); | ||
269 | |||
268 | compute_alias(&boot_cpu_data.icache); | 270 | compute_alias(&boot_cpu_data.icache); |
269 | compute_alias(&boot_cpu_data.dcache); | 271 | compute_alias(&boot_cpu_data.dcache); |
270 | compute_alias(&boot_cpu_data.scache); | 272 | compute_alias(&boot_cpu_data.scache); |
@@ -273,6 +275,13 @@ void __init cpu_cache_init(void) | |||
273 | __flush_purge_region = noop__flush_region; | 275 | __flush_purge_region = noop__flush_region; |
274 | __flush_invalidate_region = noop__flush_region; | 276 | __flush_invalidate_region = noop__flush_region; |
275 | 277 | ||
278 | /* | ||
279 | * No flushing is necessary in the disabled cache case so we can | ||
280 | * just keep the noop functions in local_flush_..() and __flush_..() | ||
281 | */ | ||
282 | if (unlikely(cache_disabled)) | ||
283 | goto skip; | ||
284 | |||
276 | if (boot_cpu_data.family == CPU_FAMILY_SH2) { | 285 | if (boot_cpu_data.family == CPU_FAMILY_SH2) { |
277 | extern void __weak sh2_cache_init(void); | 286 | extern void __weak sh2_cache_init(void); |
278 | 287 | ||
@@ -312,5 +321,6 @@ void __init cpu_cache_init(void) | |||
312 | sh5_cache_init(); | 321 | sh5_cache_init(); |
313 | } | 322 | } |
314 | 323 | ||
324 | skip: | ||
315 | emit_cache_params(); | 325 | emit_cache_params(); |
316 | } | 326 | } |