From 1c7a79a04eb916f685f7275520b5eea6968a1559 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 7 Aug 2008 15:33:09 -0400 Subject: Blackfin: safely flush data caches when in writeback mode Signed-off-by: Mike Frysinger --- lib_blackfin/cache.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'lib_blackfin') diff --git a/lib_blackfin/cache.c b/lib_blackfin/cache.c index 1557864f9..0a321a448 100644 --- a/lib_blackfin/cache.c +++ b/lib_blackfin/cache.c @@ -36,6 +36,44 @@ void flush_cache(unsigned long addr, unsigned long size) blackfin_dcache_flush_range(start_addr, end_addr); } +#ifdef CONFIG_DCACHE_WB +static void flushinv_all_dcache(void) +{ + u32 way, bank, subbank, set; + u32 status, addr; + u32 dmem_ctl = bfin_read_DMEM_CONTROL(); + + for (bank = 0; bank < 2; ++bank) { + if (!(dmem_ctl & (1 << (DMC1_P - bank)))) + continue; + + for (way = 0; way < 2; ++way) + for (subbank = 0; subbank < 4; ++subbank) + for (set = 0; set < 64; ++set) { + + bfin_write_DTEST_COMMAND( + way << 26 | + bank << 23 | + subbank << 16 | + set << 5 + ); + CSYNC(); + status = bfin_read_DTEST_DATA0(); + + /* only worry about valid/dirty entries */ + if ((status & 0x3) != 0x3) + continue; + + /* construct the address using the tag */ + addr = (status & 0xFFFFC800) | (subbank << 12) | (set << 5); + + /* flush it */ + __asm__ __volatile__("FLUSHINV[%0];" : : "a"(addr)); + } + } +} +#endif + void icache_enable(void) { bfin_write_IMEM_CONTROL(IMC | ENICPLB); @@ -61,6 +99,10 @@ void dcache_enable(void) void dcache_disable(void) { +#ifdef CONFIG_DCACHE_WB + bfin_write_DMEM_CONTROL(bfin_read_DMEM_CONTROL() & ~(ENDCPLB)); + flushinv_all_dcache(); +#endif bfin_write_DMEM_CONTROL(0); SSYNC(); } -- cgit v1.2.3