1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2012 Andes Technology Corporation
10 #if !(CONFIG_IS_ENABLED(SYS_ICACHE_OFF) && CONFIG_IS_ENABLED(SYS_DCACHE_OFF))
11 #include <asm/cache.h>
12 static inline unsigned long CACHE_SET(unsigned char cache)
15 return 64 << ((GET_ICM_CFG() & ICM_CFG_MSK_ISET) \
18 return 64 << ((GET_DCM_CFG() & DCM_CFG_MSK_DSET) \
22 static inline unsigned long CACHE_WAY(unsigned char cache)
25 return 1 + ((GET_ICM_CFG() & ICM_CFG_MSK_IWAY) \
28 return 1 + ((GET_DCM_CFG() & DCM_CFG_MSK_DWAY) \
32 static inline unsigned long CACHE_LINE_SIZE(enum cache_t cache)
35 return 8 << (((GET_ICM_CFG() & ICM_CFG_MSK_ISZ) \
36 >> ICM_CFG_OFF_ISZ) - 1);
38 return 8 << (((GET_DCM_CFG() & DCM_CFG_MSK_DSZ) \
39 >> DCM_CFG_OFF_DSZ) - 1);
43 #if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
44 void invalidate_icache_all(void)
46 unsigned long end, line_size;
47 line_size = CACHE_LINE_SIZE(ICACHE);
48 end = line_size * CACHE_WAY(ICACHE) * CACHE_SET(ICACHE);
51 __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end));
54 __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end));
57 __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end));
59 __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end));
63 void invalidate_icache_range(unsigned long start, unsigned long end)
65 unsigned long line_size;
67 line_size = CACHE_LINE_SIZE(ICACHE);
70 "\n\tcctl %0, L1I_VA_INVAL"
78 void icache_enable(void)
82 "ori $p0, $p0, 0x01\n\t"
88 void icache_disable(void)
93 "and $p0, $p0, $p1\n\t"
99 int icache_status(void)
105 "andi %0, $p0, 0x01\n\t"
115 void invalidate_icache_all(void)
119 void invalidate_icache_range(unsigned long start, unsigned long end)
123 void icache_enable(void)
127 void icache_disable(void)
131 int icache_status(void)
138 #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
139 void dcache_wbinval_all(void)
141 unsigned long end, line_size;
142 line_size = CACHE_LINE_SIZE(DCACHE);
143 end = line_size * CACHE_WAY(DCACHE) * CACHE_SET(DCACHE);
146 __asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end));
147 __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end));
149 __asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end));
150 __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end));
152 __asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end));
153 __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end));
155 __asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end));
156 __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end));
161 void flush_dcache_range(unsigned long start, unsigned long end)
163 unsigned long line_size;
165 line_size = CACHE_LINE_SIZE(DCACHE);
167 while (end > start) {
169 "\n\tcctl %0, L1D_VA_WB"
170 "\n\tcctl %0, L1D_VA_INVAL" : : "r" (start)
176 void invalidate_dcache_range(unsigned long start, unsigned long end)
178 unsigned long line_size;
180 line_size = CACHE_LINE_SIZE(DCACHE);
181 while (end > start) {
183 "\n\tcctl %0, L1D_VA_INVAL" : : "r"(start)
189 void dcache_enable(void)
193 "ori $p0, $p0, 0x02\n\t"
199 void dcache_disable(void)
204 "and $p0, $p0, $p1\n\t"
210 int dcache_status(void)
215 "andi %0, $p0, 0x02\n\t"
224 void dcache_wbinval_all(void)
228 void flush_dcache_range(unsigned long start, unsigned long end)
232 void invalidate_dcache_range(unsigned long start, unsigned long end)
236 void dcache_enable(void)
240 void dcache_disable(void)
244 int dcache_status(void)
252 void flush_dcache_all(void)
254 dcache_wbinval_all();
257 void cache_flush(void)
260 invalidate_icache_all();
264 void flush_cache(unsigned long addr, unsigned long size)
266 flush_dcache_range(addr, addr + size);
267 invalidate_icache_range(addr, addr + size);