aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm/c-r4k.c
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2008-05-06 10:57:55 -0400
committerJiri Kosina <jkosina@suse.cz>2008-05-06 10:57:55 -0400
commit7022b15e2a9f878fd5184586064c63352c3dd225 (patch)
tree5365c2f5bc82ae1946636ee8d5cd5d3b7e804f1b /arch/mips/mm/c-r4k.c
parentaaad2b0c757f3e6e02552cb0bdcd91a5ec0d6305 (diff)
parenta15306365a16380f3bafee9e181ba01231d4acd7 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'arch/mips/mm/c-r4k.c')
-rw-r--r--arch/mips/mm/c-r4k.c62
1 files changed, 55 insertions, 7 deletions
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 77aefb4ebedd..643c8bcffff3 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -14,6 +14,7 @@
14#include <linux/linkage.h> 14#include <linux/linkage.h>
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/mm.h> 16#include <linux/mm.h>
17#include <linux/module.h>
17#include <linux/bitops.h> 18#include <linux/bitops.h>
18 19
19#include <asm/bcache.h> 20#include <asm/bcache.h>
@@ -53,6 +54,12 @@ static inline void r4k_on_each_cpu(void (*func) (void *info), void *info,
53 preempt_enable(); 54 preempt_enable();
54} 55}
55 56
57#if defined(CONFIG_MIPS_CMP)
58#define cpu_has_safe_index_cacheops 0
59#else
60#define cpu_has_safe_index_cacheops 1
61#endif
62
56/* 63/*
57 * Must die. 64 * Must die.
58 */ 65 */
@@ -481,6 +488,8 @@ static inline void local_r4k_flush_cache_page(void *args)
481 488
482 if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { 489 if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
483 r4k_blast_dcache_page(addr); 490 r4k_blast_dcache_page(addr);
491 if (exec && !cpu_icache_snoops_remote_store)
492 r4k_blast_scache_page(addr);
484 } 493 }
485 if (exec) { 494 if (exec) {
486 if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) { 495 if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) {
@@ -583,7 +592,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
583 * subset property so we have to flush the primary caches 592 * subset property so we have to flush the primary caches
584 * explicitly 593 * explicitly
585 */ 594 */
586 if (size >= dcache_size) { 595 if (cpu_has_safe_index_cacheops && size >= dcache_size) {
587 r4k_blast_dcache(); 596 r4k_blast_dcache();
588 } else { 597 } else {
589 R4600_HIT_CACHEOP_WAR_IMPL; 598 R4600_HIT_CACHEOP_WAR_IMPL;
@@ -606,7 +615,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
606 return; 615 return;
607 } 616 }
608 617
609 if (size >= dcache_size) { 618 if (cpu_has_safe_index_cacheops && size >= dcache_size) {
610 r4k_blast_dcache(); 619 r4k_blast_dcache();
611 } else { 620 } else {
612 R4600_HIT_CACHEOP_WAR_IMPL; 621 R4600_HIT_CACHEOP_WAR_IMPL;
@@ -968,6 +977,7 @@ static void __cpuinit probe_pcache(void)
968 case CPU_24K: 977 case CPU_24K:
969 case CPU_34K: 978 case CPU_34K:
970 case CPU_74K: 979 case CPU_74K:
980 case CPU_1004K:
971 if ((read_c0_config7() & (1 << 16))) { 981 if ((read_c0_config7() & (1 << 16))) {
972 /* effectively physically indexed dcache, 982 /* effectively physically indexed dcache,
973 thus no virtual aliases. */ 983 thus no virtual aliases. */
@@ -1216,9 +1226,25 @@ void au1x00_fixup_config_od(void)
1216 } 1226 }
1217} 1227}
1218 1228
1229static int __cpuinitdata cca = -1;
1230
1231static int __init cca_setup(char *str)
1232{
1233 get_option(&str, &cca);
1234
1235 return 1;
1236}
1237
1238__setup("cca=", cca_setup);
1239
1219static void __cpuinit coherency_setup(void) 1240static void __cpuinit coherency_setup(void)
1220{ 1241{
1221 change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); 1242 if (cca < 0 || cca > 7)
1243 cca = read_c0_config() & CONF_CM_CMASK;
1244 _page_cachable_default = cca << _CACHE_SHIFT;
1245
1246 pr_debug("Using cache attribute %d\n", cca);
1247 change_c0_config(CONF_CM_CMASK, cca);
1222 1248
1223 /* 1249 /*
1224 * c0_status.cu=0 specifies that updates by the sc instruction use 1250 * c0_status.cu=0 specifies that updates by the sc instruction use
@@ -1248,6 +1274,20 @@ static void __cpuinit coherency_setup(void)
1248 } 1274 }
1249} 1275}
1250 1276
1277#if defined(CONFIG_DMA_NONCOHERENT)
1278
1279static int __cpuinitdata coherentio;
1280
1281static int __init setcoherentio(char *str)
1282{
1283 coherentio = 1;
1284
1285 return 1;
1286}
1287
1288__setup("coherentio", setcoherentio);
1289#endif
1290
1251void __cpuinit r4k_cache_init(void) 1291void __cpuinit r4k_cache_init(void)
1252{ 1292{
1253 extern void build_clear_page(void); 1293 extern void build_clear_page(void);
@@ -1307,14 +1347,22 @@ void __cpuinit r4k_cache_init(void)
1307 flush_data_cache_page = r4k_flush_data_cache_page; 1347 flush_data_cache_page = r4k_flush_data_cache_page;
1308 flush_icache_range = r4k_flush_icache_range; 1348 flush_icache_range = r4k_flush_icache_range;
1309 1349
1310#ifdef CONFIG_DMA_NONCOHERENT 1350#if defined(CONFIG_DMA_NONCOHERENT)
1311 _dma_cache_wback_inv = r4k_dma_cache_wback_inv; 1351 if (coherentio) {
1312 _dma_cache_wback = r4k_dma_cache_wback_inv; 1352 _dma_cache_wback_inv = (void *)cache_noop;
1313 _dma_cache_inv = r4k_dma_cache_inv; 1353 _dma_cache_wback = (void *)cache_noop;
1354 _dma_cache_inv = (void *)cache_noop;
1355 } else {
1356 _dma_cache_wback_inv = r4k_dma_cache_wback_inv;
1357 _dma_cache_wback = r4k_dma_cache_wback_inv;
1358 _dma_cache_inv = r4k_dma_cache_inv;
1359 }
1314#endif 1360#endif
1315 1361
1316 build_clear_page(); 1362 build_clear_page();
1317 build_copy_page(); 1363 build_copy_page();
1364#if !defined(CONFIG_MIPS_CMP)
1318 local_r4k___flush_cache_all(NULL); 1365 local_r4k___flush_cache_all(NULL);
1366#endif
1319 coherency_setup(); 1367 coherency_setup();
1320} 1368}