diff options
Diffstat (limited to 'arch/arc/lib/cache.c')
-rw-r--r-- | arch/arc/lib/cache.c | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c index a2277231ba..e369e5a856 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) { @@ -49,10 +50,12 @@ void icache_disable(void) void invalidate_icache_all(void) { -#ifndef CONFIG_SYS_ICACHE_OFF + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK)) + return; + /* Any write to IC_IVIC register triggers invalidation of entire I$ */ write_aux_reg(ARC_AUX_IC_IVIC, 1); -#endif /* CONFIG_SYS_ICACHE_OFF */ } int dcache_status(void) @@ -156,13 +159,60 @@ void invalidate_dcache_range(unsigned long start, unsigned long end) void invalidate_dcache_all(void) { -#ifndef CONFIG_SYS_DCACHE_OFF + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)) + return; + /* Write 1 to DC_IVDC register triggers invalidation of entire D$ */ write_aux_reg(ARC_AUX_DC_IVDC, 1); -#endif /* CONFIG_SYS_DCACHE_OFF */ } 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 */ |