summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/mips/Kconfig19
-rw-r--r--arch/mips/include/asm/cpu-features.h6
-rw-r--r--arch/mips/include/asm/cpu-info.h1
-rw-r--r--arch/mips/include/asm/cpu.h1
-rw-r--r--arch/mips/kernel/cpu-probe.c22
-rw-r--r--arch/mips/kernel/proc.c1
6 files changed, 50 insertions, 0 deletions
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 <asm/cpu-type.h>
#include <asm/fpu.h>
#include <asm/mipsregs.h>
+#include <asm/msa.h>
#include <asm/watch.h>
#include <asm/elf.h>
#include <asm/spram.h>
@@ -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) {