aboutsummaryrefslogtreecommitdiff
path: root/arch/arc
diff options
context:
space:
mode:
authorAlexey Brodkin2015-03-30 13:36:04 +0300
committerAlexey Brodkin2015-04-03 09:47:50 +0300
commit6eb15e50f48927c65a67371555b5afc24b3c7d21 (patch)
tree0e6f7a560fece41ed04cfdd3fad6591433c56e19 /arch/arc
parent09424d11192cffd4793b7bc922c5b47d4fe88a4d (diff)
arc: add support for SLC (System Level Cache, AKA L2-cache)
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@synopsys.com>
Diffstat (limited to 'arch/arc')
-rw-r--r--arch/arc/include/asm/arcregs.h4
-rw-r--r--arch/arc/include/asm/cache.h11
-rw-r--r--arch/arc/lib/cache.c46
-rw-r--r--arch/arc/lib/start.S4
4 files changed, 65 insertions, 0 deletions
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index 6a36a81c0f1..0e11dcced5c 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 8a77cd93af2..0b3ebd9f585 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 30f045a864b..e369e5a8569 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 48ee86e54ad..e1ef19cb889 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