diff options
author | Mike Frysinger <vapier@gentoo.org> | 2008-08-07 15:33:09 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2009-03-23 15:14:53 -0400 |
commit | 1c7a79a04eb916f685f7275520b5eea6968a1559 (patch) | |
tree | b0829990cf0958f317be53ef6268f9dade1365c4 /lib_blackfin/cache.c | |
parent | c06f2b13022703611bc3e512bd34f9014a46f448 (diff) | |
download | u-boot-imx-1c7a79a04eb916f685f7275520b5eea6968a1559.zip u-boot-imx-1c7a79a04eb916f685f7275520b5eea6968a1559.tar.gz u-boot-imx-1c7a79a04eb916f685f7275520b5eea6968a1559.tar.bz2 |
Blackfin: safely flush data caches when in writeback mode
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'lib_blackfin/cache.c')
-rw-r--r-- | lib_blackfin/cache.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/lib_blackfin/cache.c b/lib_blackfin/cache.c index 1557864..0a321a4 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(); } |