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 | |
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')
-rw-r--r-- | arch/mips/include/asm/cpu-type.h | 4 | ||||
-rw-r--r-- | arch/mips/kernel/cpu-probe.c | 12 | ||||
-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 |
5 files changed, 76 insertions, 5 deletions
diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h index 760c9cf0f135..721906130a57 100644 --- a/arch/mips/include/asm/cpu-type.h +++ b/arch/mips/include/asm/cpu-type.h | |||
@@ -20,6 +20,10 @@ static inline int __pure __get_cpu_type(const int cpu_type) | |||
20 | case CPU_LOONGSON2: | 20 | case CPU_LOONGSON2: |
21 | #endif | 21 | #endif |
22 | 22 | ||
23 | #ifdef CONFIG_SYS_HAS_CPU_LOONGSON3 | ||
24 | case CPU_LOONGSON3: | ||
25 | #endif | ||
26 | |||
23 | #ifdef CONFIG_SYS_HAS_CPU_LOONGSON1B | 27 | #ifdef CONFIG_SYS_HAS_CPU_LOONGSON1B |
24 | case CPU_LOONGSON1: | 28 | case CPU_LOONGSON1: |
25 | #endif | 29 | #endif |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 34df5afa2d6f..bd712c91f48b 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -735,16 +735,22 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
735 | c->tlbsize = 64; | 735 | c->tlbsize = 64; |
736 | break; | 736 | break; |
737 | case PRID_IMP_LOONGSON_64: /* Loongson-2/3 */ | 737 | case PRID_IMP_LOONGSON_64: /* Loongson-2/3 */ |
738 | c->cputype = CPU_LOONGSON2; | ||
739 | __cpu_name[cpu] = "ICT Loongson-2"; | ||
740 | |||
741 | switch (c->processor_id & PRID_REV_MASK) { | 738 | switch (c->processor_id & PRID_REV_MASK) { |
742 | case PRID_REV_LOONGSON2E: | 739 | case PRID_REV_LOONGSON2E: |
740 | c->cputype = CPU_LOONGSON2; | ||
741 | __cpu_name[cpu] = "ICT Loongson-2"; | ||
743 | set_elf_platform(cpu, "loongson2e"); | 742 | set_elf_platform(cpu, "loongson2e"); |
744 | break; | 743 | break; |
745 | case PRID_REV_LOONGSON2F: | 744 | case PRID_REV_LOONGSON2F: |
745 | c->cputype = CPU_LOONGSON2; | ||
746 | __cpu_name[cpu] = "ICT Loongson-2"; | ||
746 | set_elf_platform(cpu, "loongson2f"); | 747 | set_elf_platform(cpu, "loongson2f"); |
747 | break; | 748 | break; |
749 | case PRID_REV_LOONGSON3A: | ||
750 | c->cputype = CPU_LOONGSON3; | ||
751 | __cpu_name[cpu] = "ICT Loongson-3"; | ||
752 | set_elf_platform(cpu, "loongson3a"); | ||
753 | break; | ||
748 | } | 754 | } |
749 | 755 | ||
750 | set_isa(c, MIPS_CPU_ISA_III); | 756 | set_isa(c, MIPS_CPU_ISA_III); |
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); |