diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index e5e6aaded3dd..f627739eca49 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1208,6 +1208,7 @@ config CPU_MIPS32_R2 select CPU_HAS_PREFETCH select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_HIGHMEM + select CPU_SUPPORTS_MSA select HAVE_KVM help Choose this option to build a kernel for release 2 or later of the @@ -1243,6 +1244,7 @@ config CPU_MIPS64_R2 select CPU_SUPPORTS_64BIT_KERNEL select CPU_SUPPORTS_HIGHMEM select CPU_SUPPORTS_HUGEPAGES + select CPU_SUPPORTS_MSA help Choose this option to build a kernel for release 2 or later of the MIPS64 architecture. Many modern embedded systems with a 64-bit @@ -2081,6 +2083,20 @@ config CPU_MICROMIPS When this option is enabled the kernel will be built using the microMIPS ISA +config CPU_HAS_MSA + bool "Support for the MIPS SIMD Architecture" + depends on CPU_SUPPORTS_MSA + default y + help + MIPS SIMD Architecture (MSA) introduces 128 bit wide vector registers + and a set of SIMD instructions to operate on them. When this option + is enabled the kernel will support detection of the MSA ASE. If you + know that your kernel will only be running on CPUs which do not + support MSA then you may wish to say N here to reduce the size of + your kernel. + + If unsure, say Y. + config CPU_HAS_WB bool @@ -2146,6 +2162,9 @@ config SYS_SUPPORTS_SMARTMIPS config SYS_SUPPORTS_MICROMIPS bool +config CPU_SUPPORTS_MSA + bool + config ARCH_FLATMEM_ENABLE def_bool y depends on !NUMA && !CPU_LOONGSON2 diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index 6e70b03b6aab..390795dfa2e9 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h @@ -299,4 +299,10 @@ #define cpu_has_vz (cpu_data[0].ases & MIPS_ASE_VZ) #endif +#if defined(CONFIG_CPU_HAS_MSA) && !defined(cpu_has_msa) +# define cpu_has_msa (cpu_data[0].ases & MIPS_ASE_MSA) +#elif !defined(cpu_has_msa) +# define cpu_has_msa 0 +#endif + #endif /* __ASM_CPU_FEATURES_H */ diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h index 09d7dfc2e697..49953f717334 100644 --- a/arch/mips/include/asm/cpu-info.h +++ b/arch/mips/include/asm/cpu-info.h @@ -49,6 +49,7 @@ struct cpuinfo_mips { unsigned long ases; unsigned int processor_id; unsigned int fpu_id; + unsigned int msa_id; unsigned int cputype; int isa_level; int tlbsize; diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 559c668f7e5c..85e408394336 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -370,5 +370,6 @@ enum cpu_type_enum { #define MIPS_ASE_MIPSMT 0x00000020 /* CPU supports MIPS MT */ #define MIPS_ASE_DSP2P 0x00000040 /* Signal Processing ASE Rev 2 */ #define MIPS_ASE_VZ 0x00000080 /* Virtualization ASE */ +#define MIPS_ASE_MSA 0x00000100 /* MIPS SIMD Architecture */ #endif /* _ASM_CPU_H */ diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index c1ee8b4d2144..420d2fc595d0 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -126,6 +127,20 @@ static inline int __cpu_has_fpu(void) return ((cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE); } +static inline unsigned long cpu_get_msa_id(void) +{ + unsigned long status, conf5, msa_id; + + status = read_c0_status(); + __enable_fpu(FPU_64BIT); + conf5 = read_c0_config5(); + enable_msa(); + msa_id = read_msa_ir(); + write_c0_config5(conf5); + write_c0_status(status); + return msa_id; +} + static inline void cpu_probe_vmbits(struct cpuinfo_mips *c) { #ifdef __NEED_VMBITS_PROBE @@ -301,6 +316,8 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c) c->ases |= MIPS_ASE_VZ; if (config3 & MIPS_CONF3_SC) c->options |= MIPS_CPU_SEGMENTS; + if (config3 & MIPS_CONF3_MSA) + c->ases |= MIPS_ASE_MSA; return config3 & MIPS_CONF_M; } @@ -1178,6 +1195,9 @@ void cpu_probe(void) else c->srsets = 1; + if (cpu_has_msa) + c->msa_id = cpu_get_msa_id(); + cpu_probe_vmbits(c); #ifdef CONFIG_64BIT @@ -1194,4 +1214,6 @@ void cpu_report(void) smp_processor_id(), c->processor_id, cpu_name_string()); if (c->options & MIPS_CPU_FPU) printk(KERN_INFO "FPU revision is: %08x\n", c->fpu_id); + if (cpu_has_msa) + pr_info("MSA revision is: %08x\n", c->msa_id); } diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 00d20974b3e7..ca1d48e5d53f 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -95,6 +95,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) if (cpu_has_mipsmt) seq_printf(m, "%s", " mt"); if (cpu_has_mmips) seq_printf(m, "%s", " micromips"); if (cpu_has_vz) seq_printf(m, "%s", " vz"); + if (cpu_has_msa) seq_printf(m, "%s", " msa"); seq_printf(m, "\n"); if (cpu_has_mmips) {