diff options
author | Huacai Chen <chenhc@lemote.com> | 2014-03-21 06:44:00 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2014-03-31 12:17:12 -0400 |
commit | c579d310b9b22b4b9fedcdd720c8ac58c901e1e9 (patch) | |
tree | 2899124d69cd72f44ecf3006d561c7093120a3c4 /arch/mips/mm | |
parent | 152ebb44eff3c2dae0fb7d5b19c3f65e7c8d3493 (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.c | 59 | ||||
-rw-r--r-- | arch/mips/mm/tlb-r4k.c | 5 | ||||
-rw-r--r-- | arch/mips/mm/tlbex.c | 1 |
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 | ||
1334 | static void __init loongson3_sc_init(void) | ||
1335 | { | ||
1336 | struct cpuinfo_mips *c = ¤t_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 | |||
1306 | extern int r5k_sc_init(void); | 1361 | extern int r5k_sc_init(void); |
1307 | extern int rm7k_sc_init(void); | 1362 | extern int rm7k_sc_init(void); |
1308 | extern int mips_sc_init(void); | 1363 | extern 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 | */ |
54 | static inline void flush_itlb(void) | 54 | static 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); |