MIPS: Loongson64: Probe CPU features via CPUCFG
authorJiaxun Yang <jiaxun.yang@flygoat.com>
Thu, 30 Apr 2020 03:18:35 +0000 (11:18 +0800)
committerThomas Bogendoerfer <tsbogend@alpha.franken.de>
Thu, 30 Apr 2020 14:37:03 +0000 (16:37 +0200)
CPUCFG is a Loongson self-defined instruction used to mark CPU
features for Loongson processors started from Loongson-3A4000.

Slightly adjust cpu_probe_loongson function as well. Remove features
that already probed via decode_configs in processor's PRID case
and add a comment about TLBINV.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
arch/mips/kernel/cpu-probe.c

index 6de14b5..1736c17 100644 (file)
@@ -1932,8 +1932,35 @@ platform:
        }
 }
 
+#ifdef CONFIG_CPU_LOONGSON64
+#include <loongson_regs.h>
+
+static inline void decode_cpucfg(struct cpuinfo_mips *c)
+{
+       u32 cfg1 = read_cpucfg(LOONGSON_CFG1);
+       u32 cfg2 = read_cpucfg(LOONGSON_CFG2);
+       u32 cfg3 = read_cpucfg(LOONGSON_CFG3);
+
+       if (cfg1 & LOONGSON_CFG1_MMI)
+               c->ases |= MIPS_ASE_LOONGSON_MMI;
+
+       if (cfg2 & LOONGSON_CFG2_LEXT1)
+               c->ases |= MIPS_ASE_LOONGSON_EXT;
+
+       if (cfg2 & LOONGSON_CFG2_LEXT2)
+               c->ases |= MIPS_ASE_LOONGSON_EXT2;
+
+       if (cfg2 & LOONGSON_CFG2_LSPW)
+               c->options |= MIPS_CPU_LDPTE;
+
+       if (cfg3 & LOONGSON_CFG3_LCAMP)
+               c->ases |= MIPS_ASE_LOONGSON_CAM;
+}
+
 static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
 {
+       decode_configs(c);
+
        switch (c->processor_id & PRID_IMP_MASK) {
        case PRID_IMP_LOONGSON_64R: /* Loongson-64 Reduced */
                switch (c->processor_id & PRID_REV_MASK) {
@@ -1947,7 +1974,6 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
                        set_isa(c, MIPS_CPU_ISA_M64R2);
                        break;
                }
-               decode_configs(c);
                c->writecombine = _CACHE_UNCACHED_ACCELERATED;
                c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_EXT |
                                MIPS_ASE_LOONGSON_EXT2);
@@ -1969,9 +1995,12 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
                        set_isa(c, MIPS_CPU_ISA_M64R2);
                        break;
                }
-
-               decode_configs(c);
-               c->options |= MIPS_CPU_FTLB | MIPS_CPU_TLBINV | MIPS_CPU_LDPTE;
+               /*
+                * Loongson-3 Classic did not implement MIPS standard TLBINV
+                * but implemented TLBINVF and EHINV. As currently we're only
+                * using these two features, enable MIPS_CPU_TLBINV as well.
+                */
+               c->options |= MIPS_CPU_TLBINV | MIPS_CPU_LDPTE;
                c->writecombine = _CACHE_UNCACHED_ACCELERATED;
                c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM |
                        MIPS_ASE_LOONGSON_EXT | MIPS_ASE_LOONGSON_EXT2);
@@ -1981,17 +2010,17 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
                __cpu_name[cpu] = "ICT Loongson-3";
                set_elf_platform(cpu, "loongson3a");
                set_isa(c, MIPS_CPU_ISA_M64R2);
-               decode_configs(c);
-               c->options |= MIPS_CPU_FTLB | MIPS_CPU_TLBINV | MIPS_CPU_LDPTE;
+               decode_cpucfg(c);
                c->writecombine = _CACHE_UNCACHED_ACCELERATED;
-               c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM |
-                       MIPS_ASE_LOONGSON_EXT | MIPS_ASE_LOONGSON_EXT2);
                break;
        default:
                panic("Unknown Loongson Processor ID!");
                break;
        }
 }
+#else
+static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) { }
+#endif
 
 static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
 {