[U-Boot] [PATCH] arc: add support for SLC (System Level Cache, AKA L2-cache)

Alexey Brodkin Alexey.Brodkin at synopsys.com
Tue Mar 31 12:25:12 CEST 2015


ARCv2 cores may have built-in SLC (System Level Cache, AKA L2-cache).
This change adds functions required for controlling SLC:
 * slc_enable/disable
 * slc_flush/invalidate

For now we just disable SLC to escape DMA coherency issues until either:
 * SLC flush/invalidate is supported in DMA APIin U-Boot
 * hardware DMA coherency is implemented (that might be board specific
   so probably we'll need to have a separate Kconfig option for
   controlling SLC explicitly)

Signed-off-by: Alexey Brodkin <abrodkin at synopsys.com>
---
 arch/arc/include/asm/arcregs.h |  4 ++++
 arch/arc/include/asm/cache.h   | 11 ++++++++++
 arch/arc/lib/cache.c           | 46 ++++++++++++++++++++++++++++++++++++++++++
 arch/arc/lib/start.S           |  4 ++++
 4 files changed, 65 insertions(+)

diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index 6a36a81..0e11dcc 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -46,6 +46,10 @@
 #define ARC_AUX_DC_PTAG		0x5C
 #endif
 #define ARC_BCR_DC_BUILD	0x72
+#define ARC_BCR_SLC		0xce
+#define ARC_AUX_SLC_CONTROL	0x903
+#define ARC_AUX_SLC_FLUSH	0x904
+#define ARC_AUX_SLC_INVALIDATE	0x905
 
 #ifndef __ASSEMBLY__
 /* Accessors for auxiliary registers */
diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h
index 8a77cd9..0b3ebd9 100644
--- a/arch/arc/include/asm/cache.h
+++ b/arch/arc/include/asm/cache.h
@@ -27,4 +27,15 @@
 #define CONFIG_ARC_MMU_VER 4
 #endif
 
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_ISA_ARCV2
+void slc_enable(void);
+void slc_disable(void);
+void slc_flush(void);
+void slc_invalidate(void);
+#endif
+
+#endif /* __ASSEMBLY__ */
+
 #endif /* __ASM_ARC_CACHE_H */
diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c
index 30f045a..e369e5a 100644
--- a/arch/arc/lib/cache.c
+++ b/arch/arc/lib/cache.c
@@ -16,6 +16,7 @@
 #define DC_CTRL_INV_MODE_FLUSH	(1 << 6)
 #define DC_CTRL_FLUSH_STATUS	(1 << 8)
 #define CACHE_VER_NUM_MASK	0xF
+#define SLC_CTRL_SB		(1 << 2)
 
 int icache_status(void)
 {
@@ -170,3 +171,48 @@ void flush_cache(unsigned long start, unsigned long size)
 {
 	flush_dcache_range(start, start + size);
 }
+
+#ifdef CONFIG_ISA_ARCV2
+void slc_enable(void)
+{
+	/* If SLC ver = 0, no SLC present in CPU */
+	if (!(read_aux_reg(ARC_BCR_SLC) & 0xff))
+		return;
+
+	write_aux_reg(ARC_AUX_SLC_CONTROL,
+		      read_aux_reg(ARC_AUX_SLC_CONTROL) & ~1);
+}
+
+void slc_disable(void)
+{
+	/* If SLC ver = 0, no SLC present in CPU */
+	if (!(read_aux_reg(ARC_BCR_SLC) & 0xff))
+		return;
+
+	write_aux_reg(ARC_AUX_SLC_CONTROL,
+		      read_aux_reg(ARC_AUX_SLC_CONTROL) | 1);
+}
+
+void slc_flush(void)
+{
+	/* If SLC ver = 0, no SLC present in CPU */
+	if (!(read_aux_reg(ARC_BCR_SLC) & 0xff))
+		return;
+
+	write_aux_reg(ARC_AUX_SLC_FLUSH, 1);
+
+	/* Wait flush end */
+	while (read_aux_reg(ARC_AUX_SLC_CONTROL) & SLC_CTRL_SB)
+		;
+}
+
+void slc_invalidate(void)
+{
+	/* If SLC ver = 0, no SLC present in CPU */
+	if (!(read_aux_reg(ARC_BCR_SLC) & 0xff))
+		return;
+
+	write_aux_reg(ARC_AUX_SLC_INVALIDATE, 1);
+}
+
+#endif /* CONFIG_ISA_ARCV2 */
diff --git a/arch/arc/lib/start.S b/arch/arc/lib/start.S
index 48ee86e..e1ef19c 100644
--- a/arch/arc/lib/start.S
+++ b/arch/arc/lib/start.S
@@ -18,6 +18,10 @@ ENTRY(_start)
 	mov	%fp, %sp
 
 	/* Unconditionally disable caches */
+#ifdef CONFIG_ISA_ARCV2
+	bl	slc_flush
+	bl	slc_disable
+#endif
 	bl	flush_dcache_all
 	bl	dcache_disable
 	bl	icache_disable
-- 
2.1.0



More information about the U-Boot mailing list