summary refs log tree commit diff
path: root/arch/mips/kernel
diff options
context:
space:
mode:
authorSerge Semin <Sergey.Semin@baikalelectronics.ru>2020-05-21 17:07:17 +0300
committerThomas Bogendoerfer <tsbogend@alpha.franken.de>2020-05-22 09:11:45 +0200
commit742318ad5eeecace49e95da5d3cf4571b0b26b36 (patch)
treecf0d468687673e54bb62194fe3895a931061420f /arch/mips/kernel
parenta2ac81c6ef4018ea49c034ce165bb9ea1cf99f3e (diff)
downloadlinux-742318ad5eeecace49e95da5d3cf4571b0b26b36.tar.gz
mips: Add CP0 Write Merge config support
CP0 config register may indicate whether write-through merging
is allowed. Currently there are two types of the merging available:
SysAD Valid and Full modes. Whether each of them are supported by
the core is implementation dependent. Moreover whether the ability
to change the mode also depends on the chip family instance. Taking
into account all of this we created a dedicated mm_config() method
to detect and enable merging if it's supported. It is called for
MIPS-type processors at CPU-probe stage and attempts to detect whether
the write merging is available. If it's known to be supported and
switchable, then switch on the full mode. Otherwise just perform the
CP0.Config.MM field analysis.

In addition there are platforms like InterAptiv/ProAptiv, which do have
the MM bit field set by default, but having write-through cacheing
unsupported makes write-merging also unsupported. In this case we just
ignore the MM field value.

Co-developed-by: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
Signed-off-by: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Paul Burton <paulburton@kernel.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/cpu-probe.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index da2820991e21..b8ec35737606 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -672,6 +672,52 @@ static int set_ftlb_enable(struct cpuinfo_mips *c, enum ftlb_flags flags)
 	return 0;
 }
 
+static int mm_config(struct cpuinfo_mips *c)
+{
+	unsigned int config0, update, mm;
+
+	config0 = read_c0_config();
+	mm = config0 & MIPS_CONF_MM;
+
+	/*
+	 * It's implementation dependent what type of write-merge is supported
+	 * and whether it can be enabled/disabled. If it is settable lets make
+	 * the merging allowed by default. Some platforms might have
+	 * write-through caching unsupported. In this case just ignore the
+	 * CP0.Config.MM bit field value.
+	 */
+	switch (c->cputype) {
+	case CPU_24K:
+	case CPU_34K:
+	case CPU_74K:
+	case CPU_P5600:
+	case CPU_P6600:
+		c->options |= MIPS_CPU_MM_FULL;
+		update = MIPS_CONF_MM_FULL;
+		break;
+	case CPU_1004K:
+	case CPU_1074K:
+	case CPU_INTERAPTIV:
+	case CPU_PROAPTIV:
+		mm = 0;
+		fallthrough;
+	default:
+		update = 0;
+		break;
+	}
+
+	if (update) {
+		config0 = (config0 & ~MIPS_CONF_MM) | update;
+		write_c0_config(config0);
+	} else if (mm == MIPS_CONF_MM_SYSAD) {
+		c->options |= MIPS_CPU_MM_SYSAD;
+	} else if (mm == MIPS_CONF_MM_FULL) {
+		c->options |= MIPS_CPU_MM_FULL;
+	}
+
+	return 0;
+}
+
 static inline unsigned int decode_config0(struct cpuinfo_mips *c)
 {
 	unsigned int config0;
@@ -1763,6 +1809,8 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
 
 	spram_config();
 
+	mm_config(c);
+
 	switch (__get_cpu_type(c->cputype)) {
 	case CPU_M5150:
 	case CPU_P5600: