3 * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
5 * SPDX-License-Identifier: GPL-2.0+
9 #include <asm/cacheops.h>
10 #include <asm/mipsregs.h>
12 static inline unsigned long icache_line_size(void)
14 unsigned long conf1, il;
16 if (!config_enabled(CONFIG_SYS_CACHE_SIZE_AUTO))
17 return CONFIG_SYS_ICACHE_LINE_SIZE;
19 conf1 = read_c0_config1();
20 il = (conf1 & MIPS_CONF1_IL) >> MIPS_CONF1_IL_SHF;
26 static inline unsigned long dcache_line_size(void)
28 unsigned long conf1, dl;
30 if (!config_enabled(CONFIG_SYS_CACHE_SIZE_AUTO))
31 return CONFIG_SYS_DCACHE_LINE_SIZE;
33 conf1 = read_c0_config1();
34 dl = (conf1 & MIPS_CONF1_DL) >> MIPS_CONF1_DL_SHF;
40 void flush_cache(ulong start_addr, ulong size)
42 unsigned long ilsize = icache_line_size();
43 unsigned long dlsize = dcache_line_size();
44 const void *addr, *aend;
46 /* aend will be miscalculated when size is zero, so we return here */
50 addr = (const void *)(start_addr & ~(dlsize - 1));
51 aend = (const void *)((start_addr + size - 1) & ~(dlsize - 1));
53 if (ilsize == dlsize) {
54 /* flush I-cache & D-cache simultaneously */
56 mips_cache(HIT_WRITEBACK_INV_D, addr);
57 mips_cache(HIT_INVALIDATE_I, addr);
67 mips_cache(HIT_WRITEBACK_INV_D, addr);
74 addr = (const void *)(start_addr & ~(ilsize - 1));
75 aend = (const void *)((start_addr + size - 1) & ~(ilsize - 1));
77 mips_cache(HIT_INVALIDATE_I, addr);
84 void flush_dcache_range(ulong start_addr, ulong stop)
86 unsigned long lsize = dcache_line_size();
87 const void *addr = (const void *)(start_addr & ~(lsize - 1));
88 const void *aend = (const void *)((stop - 1) & ~(lsize - 1));
90 /* aend will be miscalculated when size is zero, so we return here */
91 if (start_addr == stop)
95 mips_cache(HIT_WRITEBACK_INV_D, addr);
102 void invalidate_dcache_range(ulong start_addr, ulong stop)
104 unsigned long lsize = dcache_line_size();
105 const void *addr = (const void *)(start_addr & ~(lsize - 1));
106 const void *aend = (const void *)((stop - 1) & ~(lsize - 1));
108 /* aend will be miscalculated when size is zero, so we return here */
109 if (start_addr == stop)
113 mips_cache(HIT_INVALIDATE_D, addr);