Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Huacai Chen and committed by
Ralf Baechle
c579d310 152ebb44

+76 -5
+4
arch/mips/include/asm/cpu-type.h
··· 20 20 case CPU_LOONGSON2: 21 21 #endif 22 22 23 + #ifdef CONFIG_SYS_HAS_CPU_LOONGSON3 24 + case CPU_LOONGSON3: 25 + #endif 26 + 23 27 #ifdef CONFIG_SYS_HAS_CPU_LOONGSON1B 24 28 case CPU_LOONGSON1: 25 29 #endif
+9 -3
arch/mips/kernel/cpu-probe.c
··· 735 735 c->tlbsize = 64; 736 736 break; 737 737 case PRID_IMP_LOONGSON_64: /* Loongson-2/3 */ 738 - c->cputype = CPU_LOONGSON2; 739 - __cpu_name[cpu] = "ICT Loongson-2"; 740 - 741 738 switch (c->processor_id & PRID_REV_MASK) { 742 739 case PRID_REV_LOONGSON2E: 740 + c->cputype = CPU_LOONGSON2; 741 + __cpu_name[cpu] = "ICT Loongson-2"; 743 742 set_elf_platform(cpu, "loongson2e"); 744 743 break; 745 744 case PRID_REV_LOONGSON2F: 745 + c->cputype = CPU_LOONGSON2; 746 + __cpu_name[cpu] = "ICT Loongson-2"; 746 747 set_elf_platform(cpu, "loongson2f"); 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"); 747 753 break; 748 754 } 749 755
+59
arch/mips/mm/c-r4k.c
··· 398 398 { 399 399 switch (current_cpu_type()) { 400 400 case CPU_LOONGSON2: 401 + case CPU_LOONGSON3: 401 402 case CPU_R4000SC: 402 403 case CPU_R4000MC: 403 404 case CPU_R4400SC: ··· 1067 1066 c->dcache.waybit = 0; 1068 1067 break; 1069 1068 1069 + case CPU_LOONGSON3: 1070 + config1 = read_c0_config1(); 1071 + lsize = (config1 >> 19) & 7; 1072 + if (lsize) 1073 + c->icache.linesz = 2 << lsize; 1074 + else 1075 + c->icache.linesz = 0; 1076 + c->icache.sets = 64 << ((config1 >> 22) & 7); 1077 + c->icache.ways = 1 + ((config1 >> 16) & 7); 1078 + icache_size = c->icache.sets * 1079 + c->icache.ways * 1080 + c->icache.linesz; 1081 + c->icache.waybit = 0; 1082 + 1083 + lsize = (config1 >> 10) & 7; 1084 + if (lsize) 1085 + c->dcache.linesz = 2 << lsize; 1086 + else 1087 + c->dcache.linesz = 0; 1088 + c->dcache.sets = 64 << ((config1 >> 13) & 7); 1089 + c->dcache.ways = 1 + ((config1 >> 7) & 7); 1090 + dcache_size = c->dcache.sets * 1091 + c->dcache.ways * 1092 + c->dcache.linesz; 1093 + c->dcache.waybit = 0; 1094 + break; 1095 + 1070 1096 default: 1071 1097 if (!(config & MIPS_CONF_M)) 1072 1098 panic("Don't know how to probe P-caches on this cpu."); ··· 1331 1303 c->options |= MIPS_CPU_INCLUSIVE_CACHES; 1332 1304 } 1333 1305 1306 + static void __init loongson3_sc_init(void) 1307 + { 1308 + struct cpuinfo_mips *c = &current_cpu_data; 1309 + unsigned int config2, lsize; 1310 + 1311 + config2 = read_c0_config2(); 1312 + lsize = (config2 >> 4) & 15; 1313 + if (lsize) 1314 + c->scache.linesz = 2 << lsize; 1315 + else 1316 + c->scache.linesz = 0; 1317 + c->scache.sets = 64 << ((config2 >> 8) & 15); 1318 + c->scache.ways = 1 + (config2 & 15); 1319 + 1320 + scache_size = c->scache.sets * 1321 + c->scache.ways * 1322 + c->scache.linesz; 1323 + /* Loongson-3 has 4 cores, 1MB scache for each. scaches are shared */ 1324 + scache_size *= 4; 1325 + c->scache.waybit = 0; 1326 + pr_info("Unified secondary cache %ldkB %s, linesize %d bytes.\n", 1327 + scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); 1328 + if (scache_size) 1329 + c->options |= MIPS_CPU_INCLUSIVE_CACHES; 1330 + return; 1331 + } 1332 + 1334 1333 extern int r5k_sc_init(void); 1335 1334 extern int rm7k_sc_init(void); 1336 1335 extern int mips_sc_init(void); ··· 1408 1353 1409 1354 case CPU_LOONGSON2: 1410 1355 loongson2_sc_init(); 1356 + return; 1357 + 1358 + case CPU_LOONGSON3: 1359 + loongson3_sc_init(); 1411 1360 return; 1412 1361 1413 1362 case CPU_XLP:
+3 -2
arch/mips/mm/tlb-r4k.c
··· 48 48 #endif /* CONFIG_MIPS_MT_SMTC */ 49 49 50 50 /* 51 - * LOONGSON2 has a 4 entry itlb which is a subset of dtlb, 52 - * unfortrunately, itlb is not totally transparent to software. 51 + * LOONGSON2/3 has a 4 entry itlb which is a subset of dtlb, 52 + * unfortunately, itlb is not totally transparent to software. 53 53 */ 54 54 static inline void flush_itlb(void) 55 55 { 56 56 switch (current_cpu_type()) { 57 57 case CPU_LOONGSON2: 58 + case CPU_LOONGSON3: 58 59 write_c0_diag(4); 59 60 break; 60 61 default:
+1
arch/mips/mm/tlbex.c
··· 582 582 case CPU_BMIPS4380: 583 583 case CPU_BMIPS5000: 584 584 case CPU_LOONGSON2: 585 + case CPU_LOONGSON3: 585 586 case CPU_R5500: 586 587 if (m4kc_tlbp_war()) 587 588 uasm_i_nop(p);