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 #ifndef CONFIG_SYS_CACHE_SIZE_AUTO
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
);