diff options
Diffstat (limited to 'arch/arc/lib')
-rw-r--r-- | arch/arc/lib/cache.c | 46 | ||||
-rw-r--r-- | arch/arc/lib/start.S | 4 |
2 files changed, 50 insertions, 0 deletions
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 |