From 6eb15e50f48927c65a67371555b5afc24b3c7d21 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Mon, 30 Mar 2015 13:36:04 +0300 Subject: 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 --- arch/arc/lib/cache.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ arch/arc/lib/start.S | 4 ++++ 2 files changed, 50 insertions(+) (limited to 'arch/arc/lib') 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 -- cgit v1.1