aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm
diff options
context:
space:
mode:
authorHuacai Chen <chenhc@lemote.com>2014-03-21 06:44:00 -0400
committerRalf Baechle <ralf@linux-mips.org>2014-03-31 12:17:12 -0400
commitc579d310b9b22b4b9fedcdd720c8ac58c901e1e9 (patch)
tree2899124d69cd72f44ecf3006d561c7093120a3c4 /arch/mips/mm
parent152ebb44eff3c2dae0fb7d5b19c3f65e7c8d3493 (diff)
MIPS: Loongson: Add basic Loongson-3 CPU support
Basic Loongson-3 CPU support include CPU probing and TLB/cache initializing. Signed-off-by: Huacai Chen <chenhc@lemote.com> Signed-off-by: Hongliang Tao <taohl@lemote.com> Signed-off-by: Hua Yan <yanh@lemote.com> Tested-by: Alex Smith <alex.smith@imgtec.com> Reviewed-by: Alex Smith <alex.smith@imgtec.com> Cc: John Crispin <john@phrozen.org> Cc: Steven J. Hill <Steven.Hill@imgtec.com> Cc: Aurelien Jarno <aurelien@aurel32.net> Cc: linux-mips@linux-mips.org Cc: Fuxin Zhang <zhangfx@lemote.com> Cc: Zhangjin Wu <wuzhangjin@gmail.com> Patchwork: https://patchwork.linux-mips.org/patch/6630 Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mm')
-rw-r--r--arch/mips/mm/c-r4k.c59
-rw-r--r--arch/mips/mm/tlb-r4k.c5
-rw-r--r--arch/mips/mm/tlbex.c1
3 files changed, 63 insertions, 2 deletions
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 3e53f1b065d6..1c74a6ad072a 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -398,6 +398,7 @@ static inline void local_r4k___flush_cache_all(void * args)
398{ 398{
399 switch (current_cpu_type()) { 399 switch (current_cpu_type()) {
400 case CPU_LOONGSON2: 400 case CPU_LOONGSON2:
401 case CPU_LOONGSON3:
401 case CPU_R4000SC: 402 case CPU_R4000SC:
402 case CPU_R4000MC: 403 case CPU_R4000MC:
403 case CPU_R4400SC: 404 case CPU_R4400SC:
@@ -1066,6 +1067,33 @@ static void probe_pcache(void)
1066 c->dcache.waybit = 0; 1067 c->dcache.waybit = 0;
1067 break; 1068 break;
1068 1069
1070 case CPU_LOONGSON3:
1071 config1 = read_c0_config1();
1072 lsize = (config1 >> 19) & 7;
1073 if (lsize)
1074 c->icache.linesz = 2 << lsize;
1075 else
1076 c->icache.linesz = 0;
1077 c->icache.sets = 64 << ((config1 >> 22) & 7);
1078 c->icache.ways = 1 + ((config1 >> 16) & 7);
1079 icache_size = c->icache.sets *
1080 c->icache.ways *
1081 c->icache.linesz;
1082 c->icache.waybit = 0;
1083
1084 lsize = (config1 >> 10) & 7;
1085 if (lsize)
1086 c->dcache.linesz = 2 << lsize;
1087 else
1088 c->dcache.linesz = 0;
1089 c->dcache.sets = 64 << ((config1 >> 13) & 7);
1090 c->dcache.ways = 1 + ((config1 >> 7) & 7);
1091 dcache_size = c->dcache.sets *
1092 c->dcache.ways *
1093 c->dcache.linesz;
1094 c->dcache.waybit = 0;
1095 break;
1096
1069 default: 1097 default:
1070 if (!(config & MIPS_CONF_M)) 1098 if (!(config & MIPS_CONF_M))
1071 panic("Don't know how to probe P-caches on this cpu."); 1099 panic("Don't know how to probe P-caches on this cpu.");
@@ -1303,6 +1331,33 @@ static void __init loongson2_sc_init(void)
1303 c->options |= MIPS_CPU_INCLUSIVE_CACHES; 1331 c->options |= MIPS_CPU_INCLUSIVE_CACHES;
1304} 1332}
1305 1333
1334static void __init loongson3_sc_init(void)
1335{
1336 struct cpuinfo_mips *c = &current_cpu_data;
1337 unsigned int config2, lsize;
1338
1339 config2 = read_c0_config2();
1340 lsize = (config2 >> 4) & 15;
1341 if (lsize)
1342 c->scache.linesz = 2 << lsize;
1343 else
1344 c->scache.linesz = 0;
1345 c->scache.sets = 64 << ((config2 >> 8) & 15);
1346 c->scache.ways = 1 + (config2 & 15);
1347
1348 scache_size = c->scache.sets *
1349 c->scache.ways *
1350 c->scache.linesz;
1351 /* Loongson-3 has 4 cores, 1MB scache for each. scaches are shared */
1352 scache_size *= 4;
1353 c->scache.waybit = 0;
1354 pr_info("Unified secondary cache %ldkB %s, linesize %d bytes.\n",
1355 scache_size >> 10, way_string[c->scache.ways], c->scache.linesz);
1356 if (scache_size)
1357 c->options |= MIPS_CPU_INCLUSIVE_CACHES;
1358 return;
1359}
1360
1306extern int r5k_sc_init(void); 1361extern int r5k_sc_init(void);
1307extern int rm7k_sc_init(void); 1362extern int rm7k_sc_init(void);
1308extern int mips_sc_init(void); 1363extern int mips_sc_init(void);
@@ -1355,6 +1410,10 @@ static void setup_scache(void)
1355 loongson2_sc_init(); 1410 loongson2_sc_init();
1356 return; 1411 return;
1357 1412
1413 case CPU_LOONGSON3:
1414 loongson3_sc_init();
1415 return;
1416
1358 case CPU_XLP: 1417 case CPU_XLP:
1359 /* don't need to worry about L2, fully coherent */ 1418 /* don't need to worry about L2, fully coherent */
1360 return; 1419 return;
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index ae4ca2450707..eeaf50f5df2b 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -48,13 +48,14 @@ extern void build_tlb_refill_handler(void);
48#endif /* CONFIG_MIPS_MT_SMTC */ 48#endif /* CONFIG_MIPS_MT_SMTC */
49 49
50/* 50/*
51 * LOONGSON2 has a 4 entry itlb which is a subset of dtlb, 51 * LOONGSON2/3 has a 4 entry itlb which is a subset of dtlb,
52 * unfortrunately, itlb is not totally transparent to software. 52 * unfortunately, itlb is not totally transparent to software.
53 */ 53 */
54static inline void flush_itlb(void) 54static inline void flush_itlb(void)
55{ 55{
56 switch (current_cpu_type()) { 56 switch (current_cpu_type()) {
57 case CPU_LOONGSON2: 57 case CPU_LOONGSON2:
58 case CPU_LOONGSON3:
58 write_c0_diag(4); 59 write_c0_diag(4);
59 break; 60 break;
60 default: 61 default:
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 6e5c9fda72c9..ee88367ab3ad 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -582,6 +582,7 @@ static void build_tlb_write_entry(u32 **p, struct uasm_label **l,
582 case CPU_BMIPS4380: 582 case CPU_BMIPS4380:
583 case CPU_BMIPS5000: 583 case CPU_BMIPS5000:
584 case CPU_LOONGSON2: 584 case CPU_LOONGSON2:
585 case CPU_LOONGSON3:
585 case CPU_R5500: 586 case CPU_R5500:
586 if (m4kc_tlbp_war()) 587 if (m4kc_tlbp_war())
587 uasm_i_nop(p); 588 uasm_i_nop(p);