|
|
|
@ -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(); |
|
|
|
|
} |
|
|
|
|