aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm/c-r4k.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/mm/c-r4k.c')
-rw-r--r--arch/mips/mm/c-r4k.c99
1 files changed, 68 insertions, 31 deletions
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 4a43924cd4fc..75d887e89739 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -60,13 +60,13 @@ static unsigned long scache_size __read_mostly;
60/* 60/*
61 * Dummy cache handling routines for machines without boardcaches 61 * Dummy cache handling routines for machines without boardcaches
62 */ 62 */
63static void no_sc_noop(void) {} 63static void cache_noop(void) {}
64 64
65static struct bcache_ops no_sc_ops = { 65static struct bcache_ops no_sc_ops = {
66 .bc_enable = (void *)no_sc_noop, 66 .bc_enable = (void *)cache_noop,
67 .bc_disable = (void *)no_sc_noop, 67 .bc_disable = (void *)cache_noop,
68 .bc_wback_inv = (void *)no_sc_noop, 68 .bc_wback_inv = (void *)cache_noop,
69 .bc_inv = (void *)no_sc_noop 69 .bc_inv = (void *)cache_noop
70}; 70};
71 71
72struct bcache_ops *bcops = &no_sc_ops; 72struct bcache_ops *bcops = &no_sc_ops;
@@ -94,7 +94,9 @@ static inline void r4k_blast_dcache_page_setup(void)
94{ 94{
95 unsigned long dc_lsize = cpu_dcache_line_size(); 95 unsigned long dc_lsize = cpu_dcache_line_size();
96 96
97 if (dc_lsize == 16) 97 if (dc_lsize == 0)
98 r4k_blast_dcache_page = (void *)cache_noop;
99 else if (dc_lsize == 16)
98 r4k_blast_dcache_page = blast_dcache16_page; 100 r4k_blast_dcache_page = blast_dcache16_page;
99 else if (dc_lsize == 32) 101 else if (dc_lsize == 32)
100 r4k_blast_dcache_page = r4k_blast_dcache_page_dc32; 102 r4k_blast_dcache_page = r4k_blast_dcache_page_dc32;
@@ -106,7 +108,9 @@ static inline void r4k_blast_dcache_page_indexed_setup(void)
106{ 108{
107 unsigned long dc_lsize = cpu_dcache_line_size(); 109 unsigned long dc_lsize = cpu_dcache_line_size();
108 110
109 if (dc_lsize == 16) 111 if (dc_lsize == 0)
112 r4k_blast_dcache_page_indexed = (void *)cache_noop;
113 else if (dc_lsize == 16)
110 r4k_blast_dcache_page_indexed = blast_dcache16_page_indexed; 114 r4k_blast_dcache_page_indexed = blast_dcache16_page_indexed;
111 else if (dc_lsize == 32) 115 else if (dc_lsize == 32)
112 r4k_blast_dcache_page_indexed = blast_dcache32_page_indexed; 116 r4k_blast_dcache_page_indexed = blast_dcache32_page_indexed;
@@ -118,7 +122,9 @@ static inline void r4k_blast_dcache_setup(void)
118{ 122{
119 unsigned long dc_lsize = cpu_dcache_line_size(); 123 unsigned long dc_lsize = cpu_dcache_line_size();
120 124
121 if (dc_lsize == 16) 125 if (dc_lsize == 0)
126 r4k_blast_dcache = (void *)cache_noop;
127 else if (dc_lsize == 16)
122 r4k_blast_dcache = blast_dcache16; 128 r4k_blast_dcache = blast_dcache16;
123 else if (dc_lsize == 32) 129 else if (dc_lsize == 32)
124 r4k_blast_dcache = blast_dcache32; 130 r4k_blast_dcache = blast_dcache32;
@@ -201,7 +207,9 @@ static inline void r4k_blast_icache_page_setup(void)
201{ 207{
202 unsigned long ic_lsize = cpu_icache_line_size(); 208 unsigned long ic_lsize = cpu_icache_line_size();
203 209
204 if (ic_lsize == 16) 210 if (ic_lsize == 0)
211 r4k_blast_icache_page = (void *)cache_noop;
212 else if (ic_lsize == 16)
205 r4k_blast_icache_page = blast_icache16_page; 213 r4k_blast_icache_page = blast_icache16_page;
206 else if (ic_lsize == 32) 214 else if (ic_lsize == 32)
207 r4k_blast_icache_page = blast_icache32_page; 215 r4k_blast_icache_page = blast_icache32_page;
@@ -216,7 +224,9 @@ static inline void r4k_blast_icache_page_indexed_setup(void)
216{ 224{
217 unsigned long ic_lsize = cpu_icache_line_size(); 225 unsigned long ic_lsize = cpu_icache_line_size();
218 226
219 if (ic_lsize == 16) 227 if (ic_lsize == 0)
228 r4k_blast_icache_page_indexed = (void *)cache_noop;
229 else if (ic_lsize == 16)
220 r4k_blast_icache_page_indexed = blast_icache16_page_indexed; 230 r4k_blast_icache_page_indexed = blast_icache16_page_indexed;
221 else if (ic_lsize == 32) { 231 else if (ic_lsize == 32) {
222 if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x()) 232 if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
@@ -238,7 +248,9 @@ static inline void r4k_blast_icache_setup(void)
238{ 248{
239 unsigned long ic_lsize = cpu_icache_line_size(); 249 unsigned long ic_lsize = cpu_icache_line_size();
240 250
241 if (ic_lsize == 16) 251 if (ic_lsize == 0)
252 r4k_blast_icache = (void *)cache_noop;
253 else if (ic_lsize == 16)
242 r4k_blast_icache = blast_icache16; 254 r4k_blast_icache = blast_icache16;
243 else if (ic_lsize == 32) { 255 else if (ic_lsize == 32) {
244 if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x()) 256 if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
@@ -258,7 +270,7 @@ static inline void r4k_blast_scache_page_setup(void)
258 unsigned long sc_lsize = cpu_scache_line_size(); 270 unsigned long sc_lsize = cpu_scache_line_size();
259 271
260 if (scache_size == 0) 272 if (scache_size == 0)
261 r4k_blast_scache_page = (void *)no_sc_noop; 273 r4k_blast_scache_page = (void *)cache_noop;
262 else if (sc_lsize == 16) 274 else if (sc_lsize == 16)
263 r4k_blast_scache_page = blast_scache16_page; 275 r4k_blast_scache_page = blast_scache16_page;
264 else if (sc_lsize == 32) 276 else if (sc_lsize == 32)
@@ -276,7 +288,7 @@ static inline void r4k_blast_scache_page_indexed_setup(void)
276 unsigned long sc_lsize = cpu_scache_line_size(); 288 unsigned long sc_lsize = cpu_scache_line_size();
277 289
278 if (scache_size == 0) 290 if (scache_size == 0)
279 r4k_blast_scache_page_indexed = (void *)no_sc_noop; 291 r4k_blast_scache_page_indexed = (void *)cache_noop;
280 else if (sc_lsize == 16) 292 else if (sc_lsize == 16)
281 r4k_blast_scache_page_indexed = blast_scache16_page_indexed; 293 r4k_blast_scache_page_indexed = blast_scache16_page_indexed;
282 else if (sc_lsize == 32) 294 else if (sc_lsize == 32)
@@ -294,7 +306,7 @@ static inline void r4k_blast_scache_setup(void)
294 unsigned long sc_lsize = cpu_scache_line_size(); 306 unsigned long sc_lsize = cpu_scache_line_size();
295 307
296 if (scache_size == 0) 308 if (scache_size == 0)
297 r4k_blast_scache = (void *)no_sc_noop; 309 r4k_blast_scache = (void *)cache_noop;
298 else if (sc_lsize == 16) 310 else if (sc_lsize == 16)
299 r4k_blast_scache = blast_scache16; 311 r4k_blast_scache = blast_scache16;
300 else if (sc_lsize == 32) 312 else if (sc_lsize == 32)
@@ -508,7 +520,7 @@ static inline void local_r4k_flush_icache_range(void *args)
508 unsigned long end = fir_args->end; 520 unsigned long end = fir_args->end;
509 521
510 if (!cpu_has_ic_fills_f_dc) { 522 if (!cpu_has_ic_fills_f_dc) {
511 if (end - start > dcache_size) { 523 if (end - start >= dcache_size) {
512 r4k_blast_dcache(); 524 r4k_blast_dcache();
513 } else { 525 } else {
514 R4600_HIT_CACHEOP_WAR_IMPL; 526 R4600_HIT_CACHEOP_WAR_IMPL;
@@ -683,10 +695,12 @@ static void local_r4k_flush_cache_sigtramp(void * arg)
683 unsigned long addr = (unsigned long) arg; 695 unsigned long addr = (unsigned long) arg;
684 696
685 R4600_HIT_CACHEOP_WAR_IMPL; 697 R4600_HIT_CACHEOP_WAR_IMPL;
686 protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); 698 if (dc_lsize)
699 protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
687 if (!cpu_icache_snoops_remote_store && scache_size) 700 if (!cpu_icache_snoops_remote_store && scache_size)
688 protected_writeback_scache_line(addr & ~(sc_lsize - 1)); 701 protected_writeback_scache_line(addr & ~(sc_lsize - 1));
689 protected_flush_icache_line(addr & ~(ic_lsize - 1)); 702 if (ic_lsize)
703 protected_flush_icache_line(addr & ~(ic_lsize - 1));
690 if (MIPS4K_ICACHE_REFILL_WAR) { 704 if (MIPS4K_ICACHE_REFILL_WAR) {
691 __asm__ __volatile__ ( 705 __asm__ __volatile__ (
692 ".set push\n\t" 706 ".set push\n\t"
@@ -973,8 +987,10 @@ static void __init probe_pcache(void)
973 c->icache.waysize = icache_size / c->icache.ways; 987 c->icache.waysize = icache_size / c->icache.ways;
974 c->dcache.waysize = dcache_size / c->dcache.ways; 988 c->dcache.waysize = dcache_size / c->dcache.ways;
975 989
976 c->icache.sets = icache_size / (c->icache.linesz * c->icache.ways); 990 c->icache.sets = c->icache.linesz ?
977 c->dcache.sets = dcache_size / (c->dcache.linesz * c->dcache.ways); 991 icache_size / (c->icache.linesz * c->icache.ways) : 0;
992 c->dcache.sets = c->dcache.linesz ?
993 dcache_size / (c->dcache.linesz * c->dcache.ways) : 0;
978 994
979 /* 995 /*
980 * R10000 and R12000 P-caches are odd in a positive way. They're 32kB 996 * R10000 and R12000 P-caches are odd in a positive way. They're 32kB
@@ -993,10 +1009,16 @@ static void __init probe_pcache(void)
993 break; 1009 break;
994 case CPU_24K: 1010 case CPU_24K:
995 case CPU_34K: 1011 case CPU_34K:
996 if (!(read_c0_config7() & (1 << 16))) 1012 case CPU_74K:
1013 if ((read_c0_config7() & (1 << 16))) {
1014 /* effectively physically indexed dcache,
1015 thus no virtual aliases. */
1016 c->dcache.flags |= MIPS_CACHE_PINDEX;
1017 break;
1018 }
997 default: 1019 default:
998 if (c->dcache.waysize > PAGE_SIZE) 1020 if (c->dcache.waysize > PAGE_SIZE)
999 c->dcache.flags |= MIPS_CACHE_ALIASES; 1021 c->dcache.flags |= MIPS_CACHE_ALIASES;
1000 } 1022 }
1001 1023
1002 switch (c->cputype) { 1024 switch (c->cputype) {
@@ -1092,6 +1114,7 @@ static int __init probe_scache(void)
1092 1114
1093extern int r5k_sc_init(void); 1115extern int r5k_sc_init(void);
1094extern int rm7k_sc_init(void); 1116extern int rm7k_sc_init(void);
1117extern int mips_sc_init(void);
1095 1118
1096static void __init setup_scache(void) 1119static void __init setup_scache(void)
1097{ 1120{
@@ -1139,17 +1162,29 @@ static void __init setup_scache(void)
1139 return; 1162 return;
1140 1163
1141 default: 1164 default:
1165 if (c->isa_level == MIPS_CPU_ISA_M32R1 ||
1166 c->isa_level == MIPS_CPU_ISA_M32R2 ||
1167 c->isa_level == MIPS_CPU_ISA_M64R1 ||
1168 c->isa_level == MIPS_CPU_ISA_M64R2) {
1169#ifdef CONFIG_MIPS_CPU_SCACHE
1170 if (mips_sc_init ()) {
1171 scache_size = c->scache.ways * c->scache.sets * c->scache.linesz;
1172 printk("MIPS secondary cache %ldkB, %s, linesize %d bytes.\n",
1173 scache_size >> 10,
1174 way_string[c->scache.ways], c->scache.linesz);
1175 }
1176#else
1177 if (!(c->scache.flags & MIPS_CACHE_NOT_PRESENT))
1178 panic("Dunno how to handle MIPS32 / MIPS64 second level cache");
1179#endif
1180 return;
1181 }
1142 sc_present = 0; 1182 sc_present = 0;
1143 } 1183 }
1144 1184
1145 if (!sc_present) 1185 if (!sc_present)
1146 return; 1186 return;
1147 1187
1148 if ((c->isa_level == MIPS_CPU_ISA_M32R1 ||
1149 c->isa_level == MIPS_CPU_ISA_M64R1) &&
1150 !(c->scache.flags & MIPS_CACHE_NOT_PRESENT))
1151 panic("Dunno how to handle MIPS32 / MIPS64 second level cache");
1152
1153 /* compute a couple of other cache variables */ 1188 /* compute a couple of other cache variables */
1154 c->scache.waysize = scache_size / c->scache.ways; 1189 c->scache.waysize = scache_size / c->scache.ways;
1155 1190
@@ -1246,10 +1281,12 @@ void __init r4k_cache_init(void)
1246 * This code supports virtually indexed processors and will be 1281 * This code supports virtually indexed processors and will be
1247 * unnecessarily inefficient on physically indexed processors. 1282 * unnecessarily inefficient on physically indexed processors.
1248 */ 1283 */
1249 shm_align_mask = max_t( unsigned long, 1284 if (c->dcache.linesz)
1250 c->dcache.sets * c->dcache.linesz - 1, 1285 shm_align_mask = max_t( unsigned long,
1251 PAGE_SIZE - 1); 1286 c->dcache.sets * c->dcache.linesz - 1,
1252 1287 PAGE_SIZE - 1);
1288 else
1289 shm_align_mask = PAGE_SIZE-1;
1253 flush_cache_all = r4k_flush_cache_all; 1290 flush_cache_all = r4k_flush_cache_all;
1254 __flush_cache_all = r4k___flush_cache_all; 1291 __flush_cache_all = r4k___flush_cache_all;
1255 flush_cache_mm = r4k_flush_cache_mm; 1292 flush_cache_mm = r4k_flush_cache_mm;