summaryrefslogtreecommitdiff
path: root/arch/mips
diff options
context:
space:
mode:
authorPaul Burton <paul.burton@imgtec.com>2016-09-21 11:18:55 +0100
committerDaniel Schwierzeck <daniel.schwierzeck@gmail.com>2016-09-21 15:04:04 +0200
commit7953354b07bba8fa9599bf5d212308e6cdf9cbe2 (patch)
treeea7c5e9e3bb9f02a999f0c4c39392fbabb1607d3 /arch/mips
parent4baa0ab67d504f3b4318f999631e3f83d0c52c4a (diff)
MIPS: Join the coherent domain when a CM is present
MIPS Linux expects the bootloader to leave the boot CPU a member of the coherent domain when running on a system with a CM, and we will need to do so if we wish to make use of IOCUs to have cache-coherent DMA in U-Boot (and on some systems there is no choice in that matter). When a CM is present, join the coherent domain after completing cache initialisation. Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/include/asm/cm.h5
-rw-r--r--arch/mips/lib/cache_init.S38
2 files changed, 43 insertions, 0 deletions
diff --git a/arch/mips/include/asm/cm.h b/arch/mips/include/asm/cm.h
index 62ecef20fc..b9ab0c65e6 100644
--- a/arch/mips/include/asm/cm.h
+++ b/arch/mips/include/asm/cm.h
@@ -19,6 +19,7 @@
#define GCR_L2_TAG_STATE_UPPER 0x060c
#define GCR_L2_DATA 0x0610
#define GCR_L2_DATA_UPPER 0x0614
+#define GCR_Cx_COHERENCE 0x2008
/* GCR_REV CM versions */
#define GCR_REV_CM3 0x0800
@@ -32,6 +33,10 @@
#define GCR_L2_CONFIG_SETSZ_BITS 4
#define GCR_L2_CONFIG_BYPASS (1 << 20)
+/* GCR_Cx_COHERENCE */
+#define GCR_Cx_COHERENCE_DOM_EN (0xff << 0)
+#define GCR_Cx_COHERENCE_EN (0x1 << 0)
+
#ifndef __ASSEMBLY__
#include <asm/io.h>
diff --git a/arch/mips/lib/cache_init.S b/arch/mips/lib/cache_init.S
index ecb88e5683..e61432ee9c 100644
--- a/arch/mips/lib/cache_init.S
+++ b/arch/mips/lib/cache_init.S
@@ -378,6 +378,44 @@ l2_unbypass:
ehb
2:
+# ifdef CONFIG_MIPS_CM
+ /* Config3 must exist for a CM to be present */
+ mfc0 t0, CP0_CONFIG, 1
+ bgez t0, 2f
+ mfc0 t0, CP0_CONFIG, 2
+ bgez t0, 2f
+
+ /* Check Config3.CMGCR to determine CM presence */
+ mfc0 t0, CP0_CONFIG, 3
+ and t0, t0, MIPS_CONF3_CMGCR
+ beqz t0, 2f
+
+ /* Change Config.K0 to a coherent CCA */
+ mfc0 t0, CP0_CONFIG
+ li t1, CONF_CM_CACHABLE_COW
+#if __mips_isa_rev >= 2
+ ins t0, t1, 0, 3
+#else
+ ori t0, t0, CONF_CM_CMASK
+ xori t0, t0, CONF_CM_CMASK
+ or t0, t0, t1
+#endif
+ mtc0 t0, CP0_CONFIG
+
+ /*
+ * Join the coherent domain such that the caches of this core are kept
+ * coherent with those of other cores.
+ */
+ PTR_LI t0, CKSEG1ADDR(CONFIG_MIPS_CM_BASE)
+ lw t1, GCR_REV(t0)
+ li t2, GCR_REV_CM3
+ li t3, GCR_Cx_COHERENCE_EN
+ bge t1, t2, 1f
+ li t3, GCR_Cx_COHERENCE_DOM_EN
+1: sw t3, GCR_Cx_COHERENCE(t0)
+ ehb
+2:
+# endif
#endif
return: