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 #ifdef CONFIG_SYS_CACHELINE_SIZE
14 static inline unsigned long icache_line_size(void)
16 return CONFIG_SYS_CACHELINE_SIZE;
19 static inline unsigned long dcache_line_size(void)
21 return CONFIG_SYS_CACHELINE_SIZE;
24 #else /* !CONFIG_SYS_CACHELINE_SIZE */
26 static inline unsigned long icache_line_size(void)
28 unsigned long conf1, il;
29 conf1 = read_c0_config1();
30 il = (conf1 & MIPS_CONF1_IL) >> MIPS_CONF1_IL_SHF;
36 static inline unsigned long dcache_line_size(void)
38 unsigned long conf1, dl;
39 conf1 = read_c0_config1();
40 dl = (conf1 & MIPS_CONF1_DL) >> MIPS_CONF1_DL_SHF;
46 #endif /* !CONFIG_SYS_CACHELINE_SIZE */
48 void flush_cache(ulong start_addr, ulong size)
50 unsigned long ilsize = icache_line_size();
51 unsigned long dlsize = dcache_line_size();
52 const void *addr, *aend;
54 /* aend will be miscalculated when size is zero, so we return here */
58 addr = (const void *)(start_addr & ~(dlsize - 1));
59 aend = (const void *)((start_addr + size - 1) & ~(dlsize - 1));
61 if (ilsize == dlsize) {
62 /* flush I-cache & D-cache simultaneously */
64 mips_cache(HIT_WRITEBACK_INV_D, addr);
65 mips_cache(HIT_INVALIDATE_I, addr);
75 mips_cache(HIT_WRITEBACK_INV_D, addr);
82 addr = (const void *)(start_addr & ~(ilsize - 1));
83 aend = (const void *)((start_addr + size - 1) & ~(ilsize - 1));
85 mips_cache(HIT_INVALIDATE_I, addr);
92 void flush_dcache_range(ulong start_addr, ulong stop)
94 unsigned long lsize = dcache_line_size();
95 const void *addr = (const void *)(start_addr & ~(lsize - 1));
96 const void *aend = (const void *)((stop - 1) & ~(lsize - 1));
98 /* aend will be miscalculated when size is zero, so we return here */
99 if (start_addr == stop)
103 mips_cache(HIT_WRITEBACK_INV_D, addr);
110 void invalidate_dcache_range(ulong start_addr, ulong stop)
112 unsigned long lsize = dcache_line_size();
113 const void *addr = (const void *)(start_addr & ~(lsize - 1));
114 const void *aend = (const void *)((stop - 1) & ~(lsize - 1));
116 /* aend will be miscalculated when size is zero, so we return here */
117 if (start_addr == stop)
121 mips_cache(HIT_INVALIDATE_D, addr);