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

MIPS: Add CPU support for Loongson1B

Loongson 1B is a 32-bit SoC designed by Institute of Computing Technology
(ICT) and the Chinese Academy of Sciences (CAS), which implements the
MIPS32 release 2 instruction set.

[ralf@linux-mips.org: But which is not strictly a MIPS32 compliant device
which also is why it identifies itself with the Legacy Vendor ID in the
PrID register. When applying the patch I shoveled some code around to
keep things in alphabetical order and avoid forward declarations.]

Signed-off-by: Kelvin Cheung <keguang.zhang@gmail.com>
Cc: To: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Cc: wuzhangjin@gmail.com
Cc: zhzhl555@gmail.com
Cc: Kelvin Cheung <keguang.zhang@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/3976/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Kelvin Cheung and committed by
Ralf Baechle
2fa36399 28a33cbc

+171 -144
+2 -1
arch/mips/include/asm/cpu.h
··· 197 197 #define PRID_REV_VR4181A 0x0070 /* Same as VR4122 */ 198 198 #define PRID_REV_VR4130 0x0080 199 199 #define PRID_REV_34K_V1_0_2 0x0022 200 + #define PRID_REV_LOONGSON1B 0x0020 200 201 #define PRID_REV_LOONGSON2E 0x0002 201 202 #define PRID_REV_LOONGSON2F 0x0003 202 203 ··· 262 261 */ 263 262 CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K, 264 263 CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350, 265 - CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_M14KC, 264 + CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC, 266 265 267 266 /* 268 267 * MIPS64 class processors
+2
arch/mips/include/asm/module.h
··· 117 117 #define MODULE_PROC_FAMILY "RM9000 " 118 118 #elif defined CONFIG_CPU_SB1 119 119 #define MODULE_PROC_FAMILY "SB1 " 120 + #elif defined CONFIG_CPU_LOONGSON1 121 + #define MODULE_PROC_FAMILY "LOONGSON1 " 120 122 #elif defined CONFIG_CPU_LOONGSON2 121 123 #define MODULE_PROC_FAMILY "LOONGSON2 " 122 124 #elif defined CONFIG_CPU_CAVIUM_OCTEON
+156 -143
arch/mips/kernel/cpu-probe.c
··· 190 190 case CPU_CAVIUM_OCTEON_PLUS: 191 191 case CPU_CAVIUM_OCTEON2: 192 192 case CPU_JZRISC: 193 + case CPU_LOONGSON1: 193 194 case CPU_XLR: 194 195 case CPU_XLP: 195 196 cpu_wait = r4k_wait; ··· 329 328 back_to_back_c0_hazard(); 330 329 c->vmbits = fls64(read_c0_entryhi() & 0x3fffffffffffe000ULL); 331 330 #endif 331 + } 332 + 333 + static char unknown_isa[] __cpuinitdata = KERN_ERR \ 334 + "Unsupported ISA type, c0.config0: %d."; 335 + 336 + static inline unsigned int decode_config0(struct cpuinfo_mips *c) 337 + { 338 + unsigned int config0; 339 + int isa; 340 + 341 + config0 = read_c0_config(); 342 + 343 + if (((config0 & MIPS_CONF_MT) >> 7) == 1) 344 + c->options |= MIPS_CPU_TLB; 345 + isa = (config0 & MIPS_CONF_AT) >> 13; 346 + switch (isa) { 347 + case 0: 348 + switch ((config0 & MIPS_CONF_AR) >> 10) { 349 + case 0: 350 + c->isa_level = MIPS_CPU_ISA_M32R1; 351 + break; 352 + case 1: 353 + c->isa_level = MIPS_CPU_ISA_M32R2; 354 + break; 355 + default: 356 + goto unknown; 357 + } 358 + break; 359 + case 2: 360 + switch ((config0 & MIPS_CONF_AR) >> 10) { 361 + case 0: 362 + c->isa_level = MIPS_CPU_ISA_M64R1; 363 + break; 364 + case 1: 365 + c->isa_level = MIPS_CPU_ISA_M64R2; 366 + break; 367 + default: 368 + goto unknown; 369 + } 370 + break; 371 + default: 372 + goto unknown; 373 + } 374 + 375 + return config0 & MIPS_CONF_M; 376 + 377 + unknown: 378 + panic(unknown_isa, config0); 379 + } 380 + 381 + static inline unsigned int decode_config1(struct cpuinfo_mips *c) 382 + { 383 + unsigned int config1; 384 + 385 + config1 = read_c0_config1(); 386 + 387 + if (config1 & MIPS_CONF1_MD) 388 + c->ases |= MIPS_ASE_MDMX; 389 + if (config1 & MIPS_CONF1_WR) 390 + c->options |= MIPS_CPU_WATCH; 391 + if (config1 & MIPS_CONF1_CA) 392 + c->ases |= MIPS_ASE_MIPS16; 393 + if (config1 & MIPS_CONF1_EP) 394 + c->options |= MIPS_CPU_EJTAG; 395 + if (config1 & MIPS_CONF1_FP) { 396 + c->options |= MIPS_CPU_FPU; 397 + c->options |= MIPS_CPU_32FPR; 398 + } 399 + if (cpu_has_tlb) 400 + c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1; 401 + 402 + return config1 & MIPS_CONF_M; 403 + } 404 + 405 + static inline unsigned int decode_config2(struct cpuinfo_mips *c) 406 + { 407 + unsigned int config2; 408 + 409 + config2 = read_c0_config2(); 410 + 411 + if (config2 & MIPS_CONF2_SL) 412 + c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; 413 + 414 + return config2 & MIPS_CONF_M; 415 + } 416 + 417 + static inline unsigned int decode_config3(struct cpuinfo_mips *c) 418 + { 419 + unsigned int config3; 420 + 421 + config3 = read_c0_config3(); 422 + 423 + if (config3 & MIPS_CONF3_SM) 424 + c->ases |= MIPS_ASE_SMARTMIPS; 425 + if (config3 & MIPS_CONF3_DSP) 426 + c->ases |= MIPS_ASE_DSP; 427 + if (config3 & MIPS_CONF3_VINT) 428 + c->options |= MIPS_CPU_VINT; 429 + if (config3 & MIPS_CONF3_VEIC) 430 + c->options |= MIPS_CPU_VEIC; 431 + if (config3 & MIPS_CONF3_MT) 432 + c->ases |= MIPS_ASE_MIPSMT; 433 + if (config3 & MIPS_CONF3_ULRI) 434 + c->options |= MIPS_CPU_ULRI; 435 + 436 + return config3 & MIPS_CONF_M; 437 + } 438 + 439 + static inline unsigned int decode_config4(struct cpuinfo_mips *c) 440 + { 441 + unsigned int config4; 442 + 443 + config4 = read_c0_config4(); 444 + 445 + if ((config4 & MIPS_CONF4_MMUEXTDEF) == MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT 446 + && cpu_has_tlb) 447 + c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40; 448 + 449 + c->kscratch_mask = (config4 >> 16) & 0xff; 450 + 451 + return config4 & MIPS_CONF_M; 452 + } 453 + 454 + static void __cpuinit decode_configs(struct cpuinfo_mips *c) 455 + { 456 + int ok; 457 + 458 + /* MIPS32 or MIPS64 compliant CPU. */ 459 + c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER | 460 + MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK; 461 + 462 + c->scache.flags = MIPS_CACHE_NOT_PRESENT; 463 + 464 + ok = decode_config0(c); /* Read Config registers. */ 465 + BUG_ON(!ok); /* Arch spec violation! */ 466 + if (ok) 467 + ok = decode_config1(c); 468 + if (ok) 469 + ok = decode_config2(c); 470 + if (ok) 471 + ok = decode_config3(c); 472 + if (ok) 473 + ok = decode_config4(c); 474 + 475 + mips_probe_watch_registers(c); 476 + 477 + if (cpu_has_mips_r2) 478 + c->core = read_c0_ebase() & 0x3ff; 332 479 } 333 480 334 481 #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \ ··· 787 638 MIPS_CPU_32FPR; 788 639 c->tlbsize = 64; 789 640 break; 790 - } 791 - } 641 + case PRID_IMP_LOONGSON1: 642 + decode_configs(c); 792 643 793 - static char unknown_isa[] __cpuinitdata = KERN_ERR \ 794 - "Unsupported ISA type, c0.config0: %d."; 644 + c->cputype = CPU_LOONGSON1; 795 645 796 - static inline unsigned int decode_config0(struct cpuinfo_mips *c) 797 - { 798 - unsigned int config0; 799 - int isa; 800 - 801 - config0 = read_c0_config(); 802 - 803 - if (((config0 & MIPS_CONF_MT) >> 7) == 1) 804 - c->options |= MIPS_CPU_TLB; 805 - isa = (config0 & MIPS_CONF_AT) >> 13; 806 - switch (isa) { 807 - case 0: 808 - switch ((config0 & MIPS_CONF_AR) >> 10) { 809 - case 0: 810 - c->isa_level = MIPS_CPU_ISA_M32R1; 646 + switch (c->processor_id & PRID_REV_MASK) { 647 + case PRID_REV_LOONGSON1B: 648 + __cpu_name[cpu] = "Loongson 1B"; 811 649 break; 812 - case 1: 813 - c->isa_level = MIPS_CPU_ISA_M32R2; 814 - break; 815 - default: 816 - goto unknown; 817 650 } 651 + 818 652 break; 819 - case 2: 820 - switch ((config0 & MIPS_CONF_AR) >> 10) { 821 - case 0: 822 - c->isa_level = MIPS_CPU_ISA_M64R1; 823 - break; 824 - case 1: 825 - c->isa_level = MIPS_CPU_ISA_M64R2; 826 - break; 827 - default: 828 - goto unknown; 829 - } 830 - break; 831 - default: 832 - goto unknown; 833 653 } 834 - 835 - return config0 & MIPS_CONF_M; 836 - 837 - unknown: 838 - panic(unknown_isa, config0); 839 - } 840 - 841 - static inline unsigned int decode_config1(struct cpuinfo_mips *c) 842 - { 843 - unsigned int config1; 844 - 845 - config1 = read_c0_config1(); 846 - 847 - if (config1 & MIPS_CONF1_MD) 848 - c->ases |= MIPS_ASE_MDMX; 849 - if (config1 & MIPS_CONF1_WR) 850 - c->options |= MIPS_CPU_WATCH; 851 - if (config1 & MIPS_CONF1_CA) 852 - c->ases |= MIPS_ASE_MIPS16; 853 - if (config1 & MIPS_CONF1_EP) 854 - c->options |= MIPS_CPU_EJTAG; 855 - if (config1 & MIPS_CONF1_FP) { 856 - c->options |= MIPS_CPU_FPU; 857 - c->options |= MIPS_CPU_32FPR; 858 - } 859 - if (cpu_has_tlb) 860 - c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1; 861 - 862 - return config1 & MIPS_CONF_M; 863 - } 864 - 865 - static inline unsigned int decode_config2(struct cpuinfo_mips *c) 866 - { 867 - unsigned int config2; 868 - 869 - config2 = read_c0_config2(); 870 - 871 - if (config2 & MIPS_CONF2_SL) 872 - c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; 873 - 874 - return config2 & MIPS_CONF_M; 875 - } 876 - 877 - static inline unsigned int decode_config3(struct cpuinfo_mips *c) 878 - { 879 - unsigned int config3; 880 - 881 - config3 = read_c0_config3(); 882 - 883 - if (config3 & MIPS_CONF3_SM) 884 - c->ases |= MIPS_ASE_SMARTMIPS; 885 - if (config3 & MIPS_CONF3_DSP) 886 - c->ases |= MIPS_ASE_DSP; 887 - if (config3 & MIPS_CONF3_VINT) 888 - c->options |= MIPS_CPU_VINT; 889 - if (config3 & MIPS_CONF3_VEIC) 890 - c->options |= MIPS_CPU_VEIC; 891 - if (config3 & MIPS_CONF3_MT) 892 - c->ases |= MIPS_ASE_MIPSMT; 893 - if (config3 & MIPS_CONF3_ULRI) 894 - c->options |= MIPS_CPU_ULRI; 895 - 896 - return config3 & MIPS_CONF_M; 897 - } 898 - 899 - static inline unsigned int decode_config4(struct cpuinfo_mips *c) 900 - { 901 - unsigned int config4; 902 - 903 - config4 = read_c0_config4(); 904 - 905 - if ((config4 & MIPS_CONF4_MMUEXTDEF) == MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT 906 - && cpu_has_tlb) 907 - c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40; 908 - 909 - c->kscratch_mask = (config4 >> 16) & 0xff; 910 - 911 - return config4 & MIPS_CONF_M; 912 - } 913 - 914 - static void __cpuinit decode_configs(struct cpuinfo_mips *c) 915 - { 916 - int ok; 917 - 918 - /* MIPS32 or MIPS64 compliant CPU. */ 919 - c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER | 920 - MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK; 921 - 922 - c->scache.flags = MIPS_CACHE_NOT_PRESENT; 923 - 924 - ok = decode_config0(c); /* Read Config registers. */ 925 - BUG_ON(!ok); /* Arch spec violation! */ 926 - if (ok) 927 - ok = decode_config1(c); 928 - if (ok) 929 - ok = decode_config2(c); 930 - if (ok) 931 - ok = decode_config3(c); 932 - if (ok) 933 - ok = decode_config4(c); 934 - 935 - mips_probe_watch_registers(c); 936 - 937 - if (cpu_has_mips_r2) 938 - c->core = read_c0_ebase() & 0x3ff; 939 654 } 940 655 941 656 static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
+5
arch/mips/kernel/perf_event_mipsxx.c
··· 1559 1559 mipspmu.general_event_map = &mipsxxcore_event_map; 1560 1560 mipspmu.cache_event_map = &mipsxxcore_cache_map; 1561 1561 break; 1562 + case CPU_LOONGSON1: 1563 + mipspmu.name = "mips/loongson1"; 1564 + mipspmu.general_event_map = &mipsxxcore_event_map; 1565 + mipspmu.cache_event_map = &mipsxxcore_cache_map; 1566 + break; 1562 1567 case CPU_CAVIUM_OCTEON: 1563 1568 case CPU_CAVIUM_OCTEON_PLUS: 1564 1569 case CPU_CAVIUM_OCTEON2:
+1
arch/mips/kernel/traps.c
··· 1253 1253 1254 1254 case CPU_5KC: 1255 1255 case CPU_5KE: 1256 + case CPU_LOONGSON1: 1256 1257 write_c0_ecc(0x80000000); 1257 1258 back_to_back_c0_hazard(); 1258 1259 /* Set the PE bit (bit 31) in the c0_errctl register. */
+1
arch/mips/oprofile/common.c
··· 85 85 case CPU_34K: 86 86 case CPU_1004K: 87 87 case CPU_74K: 88 + case CPU_LOONGSON1: 88 89 case CPU_SB1: 89 90 case CPU_SB1A: 90 91 case CPU_R10000:
+4
arch/mips/oprofile/op_model_mipsxx.c
··· 374 374 op_model_mipsxx_ops.cpu_type = "mips/sb1"; 375 375 break; 376 376 377 + case CPU_LOONGSON1: 378 + op_model_mipsxx_ops.cpu_type = "mips/loongson1"; 379 + break; 380 + 377 381 default: 378 382 printk(KERN_ERR "Profiling unsupported for this CPU\n"); 379 383