diff options
Diffstat (limited to 'arch/mips/mm/c-r4k.c')
-rw-r--r-- | arch/mips/mm/c-r4k.c | 99 |
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 | */ |
63 | static void no_sc_noop(void) {} | 63 | static void cache_noop(void) {} |
64 | 64 | ||
65 | static struct bcache_ops no_sc_ops = { | 65 | static 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 | ||
72 | struct bcache_ops *bcops = &no_sc_ops; | 72 | struct 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 | ||
1093 | extern int r5k_sc_init(void); | 1115 | extern int r5k_sc_init(void); |
1094 | extern int rm7k_sc_init(void); | 1116 | extern int rm7k_sc_init(void); |
1117 | extern int mips_sc_init(void); | ||
1095 | 1118 | ||
1096 | static void __init setup_scache(void) | 1119 | static 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; |