xref: /openbmc/u-boot/arch/arc/lib/cache.c (revision ef639e6f)
1660d5f0dSAlexey Brodkin /*
2660d5f0dSAlexey Brodkin  * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
3660d5f0dSAlexey Brodkin  *
4660d5f0dSAlexey Brodkin  * SPDX-License-Identifier:	GPL-2.0+
5660d5f0dSAlexey Brodkin  */
6660d5f0dSAlexey Brodkin 
7660d5f0dSAlexey Brodkin #include <config.h>
8*ef639e6fSAlexey Brodkin #include <linux/compiler.h>
9*ef639e6fSAlexey Brodkin #include <linux/kernel.h>
10660d5f0dSAlexey Brodkin #include <asm/arcregs.h>
11205e7a7bSAlexey Brodkin #include <asm/cache.h>
12660d5f0dSAlexey Brodkin 
13*ef639e6fSAlexey Brodkin #define CACHE_LINE_MASK		(~(CONFIG_SYS_CACHELINE_SIZE - 1))
14*ef639e6fSAlexey Brodkin 
15660d5f0dSAlexey Brodkin /* Bit values in IC_CTRL */
16660d5f0dSAlexey Brodkin #define IC_CTRL_CACHE_DISABLE	(1 << 0)
17660d5f0dSAlexey Brodkin 
18660d5f0dSAlexey Brodkin /* Bit values in DC_CTRL */
19660d5f0dSAlexey Brodkin #define DC_CTRL_CACHE_DISABLE	(1 << 0)
20660d5f0dSAlexey Brodkin #define DC_CTRL_INV_MODE_FLUSH	(1 << 6)
21660d5f0dSAlexey Brodkin #define DC_CTRL_FLUSH_STATUS	(1 << 8)
22660d5f0dSAlexey Brodkin #define CACHE_VER_NUM_MASK	0xF
236eb15e50SAlexey Brodkin #define SLC_CTRL_SB		(1 << 2)
24660d5f0dSAlexey Brodkin 
25*ef639e6fSAlexey Brodkin #define OP_INV		0x1
26*ef639e6fSAlexey Brodkin #define OP_FLUSH	0x2
27*ef639e6fSAlexey Brodkin #define OP_INV_IC	0x3
28*ef639e6fSAlexey Brodkin 
29*ef639e6fSAlexey Brodkin #ifdef CONFIG_ISA_ARCV2
30*ef639e6fSAlexey Brodkin /*
31*ef639e6fSAlexey Brodkin  * By default that variable will fall into .bss section.
32*ef639e6fSAlexey Brodkin  * But .bss section is not relocated and so it will be initilized before
33*ef639e6fSAlexey Brodkin  * relocation but will be used after being zeroed.
34*ef639e6fSAlexey Brodkin  */
35*ef639e6fSAlexey Brodkin int slc_line_sz __section(".data");
36*ef639e6fSAlexey Brodkin int slc_exists __section(".data");
37*ef639e6fSAlexey Brodkin 
38*ef639e6fSAlexey Brodkin static unsigned int __before_slc_op(const int op)
39*ef639e6fSAlexey Brodkin {
40*ef639e6fSAlexey Brodkin 	unsigned int reg = reg;
41*ef639e6fSAlexey Brodkin 
42*ef639e6fSAlexey Brodkin 	if (op == OP_INV) {
43*ef639e6fSAlexey Brodkin 		/*
44*ef639e6fSAlexey Brodkin 		 * IM is set by default and implies Flush-n-inv
45*ef639e6fSAlexey Brodkin 		 * Clear it here for vanilla inv
46*ef639e6fSAlexey Brodkin 		 */
47*ef639e6fSAlexey Brodkin 		reg = read_aux_reg(ARC_AUX_SLC_CTRL);
48*ef639e6fSAlexey Brodkin 		write_aux_reg(ARC_AUX_SLC_CTRL, reg & ~DC_CTRL_INV_MODE_FLUSH);
49*ef639e6fSAlexey Brodkin 	}
50*ef639e6fSAlexey Brodkin 
51*ef639e6fSAlexey Brodkin 	return reg;
52*ef639e6fSAlexey Brodkin }
53*ef639e6fSAlexey Brodkin 
54*ef639e6fSAlexey Brodkin static void __after_slc_op(const int op, unsigned int reg)
55*ef639e6fSAlexey Brodkin {
56*ef639e6fSAlexey Brodkin 	if (op & OP_FLUSH)	/* flush / flush-n-inv both wait */
57*ef639e6fSAlexey Brodkin 		while (read_aux_reg(ARC_AUX_SLC_CTRL) &
58*ef639e6fSAlexey Brodkin 		       DC_CTRL_FLUSH_STATUS)
59*ef639e6fSAlexey Brodkin 			;
60*ef639e6fSAlexey Brodkin 
61*ef639e6fSAlexey Brodkin 	/* Switch back to default Invalidate mode */
62*ef639e6fSAlexey Brodkin 	if (op == OP_INV)
63*ef639e6fSAlexey Brodkin 		write_aux_reg(ARC_AUX_SLC_CTRL, reg | DC_CTRL_INV_MODE_FLUSH);
64*ef639e6fSAlexey Brodkin }
65*ef639e6fSAlexey Brodkin 
66*ef639e6fSAlexey Brodkin static inline void __slc_line_loop(unsigned long paddr, unsigned long sz,
67*ef639e6fSAlexey Brodkin 				   const int op)
68*ef639e6fSAlexey Brodkin {
69*ef639e6fSAlexey Brodkin 	unsigned int aux_cmd;
70*ef639e6fSAlexey Brodkin 	int num_lines;
71*ef639e6fSAlexey Brodkin 
72*ef639e6fSAlexey Brodkin #define SLC_LINE_MASK	(~(slc_line_sz - 1))
73*ef639e6fSAlexey Brodkin 
74*ef639e6fSAlexey Brodkin 	aux_cmd = op & OP_INV ? ARC_AUX_SLC_IVDL : ARC_AUX_SLC_FLDL;
75*ef639e6fSAlexey Brodkin 
76*ef639e6fSAlexey Brodkin 	sz += paddr & ~SLC_LINE_MASK;
77*ef639e6fSAlexey Brodkin 	paddr &= SLC_LINE_MASK;
78*ef639e6fSAlexey Brodkin 
79*ef639e6fSAlexey Brodkin 	num_lines = DIV_ROUND_UP(sz, slc_line_sz);
80*ef639e6fSAlexey Brodkin 
81*ef639e6fSAlexey Brodkin 	while (num_lines-- > 0) {
82*ef639e6fSAlexey Brodkin 		write_aux_reg(aux_cmd, paddr);
83*ef639e6fSAlexey Brodkin 		paddr += slc_line_sz;
84*ef639e6fSAlexey Brodkin 	}
85*ef639e6fSAlexey Brodkin }
86*ef639e6fSAlexey Brodkin 
87*ef639e6fSAlexey Brodkin static inline void __slc_entire_op(const int cacheop)
88*ef639e6fSAlexey Brodkin {
89*ef639e6fSAlexey Brodkin 	int aux;
90*ef639e6fSAlexey Brodkin 	unsigned int ctrl_reg = __before_slc_op(cacheop);
91*ef639e6fSAlexey Brodkin 
92*ef639e6fSAlexey Brodkin 	if (cacheop & OP_INV)	/* Inv or flush-n-inv use same cmd reg */
93*ef639e6fSAlexey Brodkin 		aux = ARC_AUX_SLC_INVALIDATE;
94*ef639e6fSAlexey Brodkin 	else
95*ef639e6fSAlexey Brodkin 		aux = ARC_AUX_SLC_FLUSH;
96*ef639e6fSAlexey Brodkin 
97*ef639e6fSAlexey Brodkin 	write_aux_reg(aux, 0x1);
98*ef639e6fSAlexey Brodkin 
99*ef639e6fSAlexey Brodkin 	__after_slc_op(cacheop, ctrl_reg);
100*ef639e6fSAlexey Brodkin }
101*ef639e6fSAlexey Brodkin 
102*ef639e6fSAlexey Brodkin static inline void __slc_line_op(unsigned long paddr, unsigned long sz,
103*ef639e6fSAlexey Brodkin 				 const int cacheop)
104*ef639e6fSAlexey Brodkin {
105*ef639e6fSAlexey Brodkin 	unsigned int ctrl_reg = __before_slc_op(cacheop);
106*ef639e6fSAlexey Brodkin 	__slc_line_loop(paddr, sz, cacheop);
107*ef639e6fSAlexey Brodkin 	__after_slc_op(cacheop, ctrl_reg);
108*ef639e6fSAlexey Brodkin }
109*ef639e6fSAlexey Brodkin #else
110*ef639e6fSAlexey Brodkin #define __slc_entire_op(cacheop)
111*ef639e6fSAlexey Brodkin #define __slc_line_op(paddr, sz, cacheop)
112*ef639e6fSAlexey Brodkin #endif
113*ef639e6fSAlexey Brodkin 
114*ef639e6fSAlexey Brodkin static inline int icache_exists(void)
115*ef639e6fSAlexey Brodkin {
116*ef639e6fSAlexey Brodkin 	/* Check if Instruction Cache is available */
117*ef639e6fSAlexey Brodkin 	if (read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK)
118*ef639e6fSAlexey Brodkin 		return 1;
119*ef639e6fSAlexey Brodkin 	else
120*ef639e6fSAlexey Brodkin 		return 0;
121*ef639e6fSAlexey Brodkin }
122*ef639e6fSAlexey Brodkin 
123*ef639e6fSAlexey Brodkin static inline int dcache_exists(void)
124*ef639e6fSAlexey Brodkin {
125*ef639e6fSAlexey Brodkin 	/* Check if Data Cache is available */
126*ef639e6fSAlexey Brodkin 	if (read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)
127*ef639e6fSAlexey Brodkin 		return 1;
128*ef639e6fSAlexey Brodkin 	else
129*ef639e6fSAlexey Brodkin 		return 0;
130*ef639e6fSAlexey Brodkin }
131*ef639e6fSAlexey Brodkin 
132*ef639e6fSAlexey Brodkin void cache_init(void)
133*ef639e6fSAlexey Brodkin {
134*ef639e6fSAlexey Brodkin #ifdef CONFIG_ISA_ARCV2
135*ef639e6fSAlexey Brodkin 	/* Check if System-Level Cache (SLC) is available */
136*ef639e6fSAlexey Brodkin 	if (read_aux_reg(ARC_BCR_SLC) & CACHE_VER_NUM_MASK) {
137*ef639e6fSAlexey Brodkin #define LSIZE_OFFSET	4
138*ef639e6fSAlexey Brodkin #define LSIZE_MASK	3
139*ef639e6fSAlexey Brodkin 		if (read_aux_reg(ARC_AUX_SLC_CONFIG) &
140*ef639e6fSAlexey Brodkin 		    (LSIZE_MASK << LSIZE_OFFSET))
141*ef639e6fSAlexey Brodkin 			slc_line_sz = 64;
142*ef639e6fSAlexey Brodkin 		else
143*ef639e6fSAlexey Brodkin 			slc_line_sz = 128;
144*ef639e6fSAlexey Brodkin 		slc_exists = 1;
145*ef639e6fSAlexey Brodkin 	} else {
146*ef639e6fSAlexey Brodkin 		slc_exists = 0;
147*ef639e6fSAlexey Brodkin 	}
148*ef639e6fSAlexey Brodkin #endif
149*ef639e6fSAlexey Brodkin }
150*ef639e6fSAlexey Brodkin 
151660d5f0dSAlexey Brodkin int icache_status(void)
152660d5f0dSAlexey Brodkin {
153*ef639e6fSAlexey Brodkin 	if (!icache_exists())
154660d5f0dSAlexey Brodkin 		return 0;
155660d5f0dSAlexey Brodkin 
156*ef639e6fSAlexey Brodkin 	if (read_aux_reg(ARC_AUX_IC_CTRL) & IC_CTRL_CACHE_DISABLE)
157*ef639e6fSAlexey Brodkin 		return 0;
158*ef639e6fSAlexey Brodkin 	else
159*ef639e6fSAlexey Brodkin 		return 1;
160660d5f0dSAlexey Brodkin }
161660d5f0dSAlexey Brodkin 
162660d5f0dSAlexey Brodkin void icache_enable(void)
163660d5f0dSAlexey Brodkin {
164*ef639e6fSAlexey Brodkin 	if (icache_exists())
165660d5f0dSAlexey Brodkin 		write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) &
166660d5f0dSAlexey Brodkin 			      ~IC_CTRL_CACHE_DISABLE);
167660d5f0dSAlexey Brodkin }
168660d5f0dSAlexey Brodkin 
169660d5f0dSAlexey Brodkin void icache_disable(void)
170660d5f0dSAlexey Brodkin {
171*ef639e6fSAlexey Brodkin 	if (icache_exists())
172660d5f0dSAlexey Brodkin 		write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) |
173660d5f0dSAlexey Brodkin 			      IC_CTRL_CACHE_DISABLE);
174660d5f0dSAlexey Brodkin }
175660d5f0dSAlexey Brodkin 
176*ef639e6fSAlexey Brodkin #ifndef CONFIG_SYS_DCACHE_OFF
177660d5f0dSAlexey Brodkin void invalidate_icache_all(void)
178660d5f0dSAlexey Brodkin {
179660d5f0dSAlexey Brodkin 	/* Any write to IC_IVIC register triggers invalidation of entire I$ */
180*ef639e6fSAlexey Brodkin 	if (icache_status()) {
181660d5f0dSAlexey Brodkin 		write_aux_reg(ARC_AUX_IC_IVIC, 1);
182*ef639e6fSAlexey Brodkin 		read_aux_reg(ARC_AUX_IC_CTRL);	/* blocks */
183660d5f0dSAlexey Brodkin 	}
184*ef639e6fSAlexey Brodkin }
185*ef639e6fSAlexey Brodkin #else
186*ef639e6fSAlexey Brodkin void invalidate_icache_all(void)
187*ef639e6fSAlexey Brodkin {
188*ef639e6fSAlexey Brodkin }
189*ef639e6fSAlexey Brodkin #endif
190660d5f0dSAlexey Brodkin 
191660d5f0dSAlexey Brodkin int dcache_status(void)
192660d5f0dSAlexey Brodkin {
193*ef639e6fSAlexey Brodkin 	if (!dcache_exists())
194660d5f0dSAlexey Brodkin 		return 0;
195660d5f0dSAlexey Brodkin 
196*ef639e6fSAlexey Brodkin 	if (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_CACHE_DISABLE)
197*ef639e6fSAlexey Brodkin 		return 0;
198*ef639e6fSAlexey Brodkin 	else
199*ef639e6fSAlexey Brodkin 		return 1;
200660d5f0dSAlexey Brodkin }
201660d5f0dSAlexey Brodkin 
202660d5f0dSAlexey Brodkin void dcache_enable(void)
203660d5f0dSAlexey Brodkin {
204*ef639e6fSAlexey Brodkin 	if (!dcache_exists())
205660d5f0dSAlexey Brodkin 		return;
206660d5f0dSAlexey Brodkin 
207660d5f0dSAlexey Brodkin 	write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) &
208660d5f0dSAlexey Brodkin 		      ~(DC_CTRL_INV_MODE_FLUSH | DC_CTRL_CACHE_DISABLE));
209660d5f0dSAlexey Brodkin }
210660d5f0dSAlexey Brodkin 
211660d5f0dSAlexey Brodkin void dcache_disable(void)
212660d5f0dSAlexey Brodkin {
213*ef639e6fSAlexey Brodkin 	if (!dcache_exists())
214660d5f0dSAlexey Brodkin 		return;
215660d5f0dSAlexey Brodkin 
216660d5f0dSAlexey Brodkin 	write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) |
217660d5f0dSAlexey Brodkin 		      DC_CTRL_CACHE_DISABLE);
218660d5f0dSAlexey Brodkin }
219660d5f0dSAlexey Brodkin 
220660d5f0dSAlexey Brodkin #ifndef CONFIG_SYS_DCACHE_OFF
221660d5f0dSAlexey Brodkin /*
222*ef639e6fSAlexey Brodkin  * Common Helper for Line Operations on {I,D}-Cache
223660d5f0dSAlexey Brodkin  */
224*ef639e6fSAlexey Brodkin static inline void __cache_line_loop(unsigned long paddr, unsigned long sz,
225*ef639e6fSAlexey Brodkin 				     const int cacheop)
226660d5f0dSAlexey Brodkin {
227*ef639e6fSAlexey Brodkin 	unsigned int aux_cmd;
228*ef639e6fSAlexey Brodkin #if (CONFIG_ARC_MMU_VER == 3)
229*ef639e6fSAlexey Brodkin 	unsigned int aux_tag;
230*ef639e6fSAlexey Brodkin #endif
231*ef639e6fSAlexey Brodkin 	int num_lines;
232660d5f0dSAlexey Brodkin 
233*ef639e6fSAlexey Brodkin 	if (cacheop == OP_INV_IC) {
234*ef639e6fSAlexey Brodkin 		aux_cmd = ARC_AUX_IC_IVIL;
235*ef639e6fSAlexey Brodkin #if (CONFIG_ARC_MMU_VER == 3)
236*ef639e6fSAlexey Brodkin 		aux_tag = ARC_AUX_IC_PTAG;
237*ef639e6fSAlexey Brodkin #endif
238*ef639e6fSAlexey Brodkin 	} else {
239*ef639e6fSAlexey Brodkin 		/* d$ cmd: INV (discard or wback-n-discard) OR FLUSH (wback) */
240*ef639e6fSAlexey Brodkin 		aux_cmd = cacheop & OP_INV ? ARC_AUX_DC_IVDL : ARC_AUX_DC_FLDL;
241*ef639e6fSAlexey Brodkin #if (CONFIG_ARC_MMU_VER == 3)
242*ef639e6fSAlexey Brodkin 		aux_tag = ARC_AUX_DC_PTAG;
243*ef639e6fSAlexey Brodkin #endif
244660d5f0dSAlexey Brodkin 	}
245660d5f0dSAlexey Brodkin 
246*ef639e6fSAlexey Brodkin 	sz += paddr & ~CACHE_LINE_MASK;
247*ef639e6fSAlexey Brodkin 	paddr &= CACHE_LINE_MASK;
248*ef639e6fSAlexey Brodkin 
249*ef639e6fSAlexey Brodkin 	num_lines = DIV_ROUND_UP(sz, CONFIG_SYS_CACHELINE_SIZE);
250*ef639e6fSAlexey Brodkin 
251*ef639e6fSAlexey Brodkin 	while (num_lines-- > 0) {
252*ef639e6fSAlexey Brodkin #if (CONFIG_ARC_MMU_VER == 3)
253*ef639e6fSAlexey Brodkin 		write_aux_reg(aux_tag, paddr);
254*ef639e6fSAlexey Brodkin #endif
255*ef639e6fSAlexey Brodkin 		write_aux_reg(aux_cmd, paddr);
256*ef639e6fSAlexey Brodkin 		paddr += CONFIG_SYS_CACHELINE_SIZE;
257*ef639e6fSAlexey Brodkin 	}
258*ef639e6fSAlexey Brodkin }
259*ef639e6fSAlexey Brodkin 
260*ef639e6fSAlexey Brodkin static unsigned int __before_dc_op(const int op)
261*ef639e6fSAlexey Brodkin {
262*ef639e6fSAlexey Brodkin 	unsigned int reg;
263*ef639e6fSAlexey Brodkin 
264*ef639e6fSAlexey Brodkin 	if (op == OP_INV) {
265*ef639e6fSAlexey Brodkin 		/*
266*ef639e6fSAlexey Brodkin 		 * IM is set by default and implies Flush-n-inv
267*ef639e6fSAlexey Brodkin 		 * Clear it here for vanilla inv
268*ef639e6fSAlexey Brodkin 		 */
269*ef639e6fSAlexey Brodkin 		reg = read_aux_reg(ARC_AUX_DC_CTRL);
270*ef639e6fSAlexey Brodkin 		write_aux_reg(ARC_AUX_DC_CTRL, reg & ~DC_CTRL_INV_MODE_FLUSH);
271*ef639e6fSAlexey Brodkin 	}
272*ef639e6fSAlexey Brodkin 
273*ef639e6fSAlexey Brodkin 	return reg;
274*ef639e6fSAlexey Brodkin }
275*ef639e6fSAlexey Brodkin 
276*ef639e6fSAlexey Brodkin static void __after_dc_op(const int op, unsigned int reg)
277*ef639e6fSAlexey Brodkin {
278*ef639e6fSAlexey Brodkin 	if (op & OP_FLUSH)	/* flush / flush-n-inv both wait */
279*ef639e6fSAlexey Brodkin 		while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS)
280*ef639e6fSAlexey Brodkin 			;
281*ef639e6fSAlexey Brodkin 
282*ef639e6fSAlexey Brodkin 	/* Switch back to default Invalidate mode */
283*ef639e6fSAlexey Brodkin 	if (op == OP_INV)
284*ef639e6fSAlexey Brodkin 		write_aux_reg(ARC_AUX_DC_CTRL, reg | DC_CTRL_INV_MODE_FLUSH);
285*ef639e6fSAlexey Brodkin }
286*ef639e6fSAlexey Brodkin 
287*ef639e6fSAlexey Brodkin static inline void __dc_entire_op(const int cacheop)
288*ef639e6fSAlexey Brodkin {
289*ef639e6fSAlexey Brodkin 	int aux;
290*ef639e6fSAlexey Brodkin 	unsigned int ctrl_reg = __before_dc_op(cacheop);
291*ef639e6fSAlexey Brodkin 
292*ef639e6fSAlexey Brodkin 	if (cacheop & OP_INV)	/* Inv or flush-n-inv use same cmd reg */
293*ef639e6fSAlexey Brodkin 		aux = ARC_AUX_DC_IVDC;
294*ef639e6fSAlexey Brodkin 	else
295*ef639e6fSAlexey Brodkin 		aux = ARC_AUX_DC_FLSH;
296*ef639e6fSAlexey Brodkin 
297*ef639e6fSAlexey Brodkin 	write_aux_reg(aux, 0x1);
298*ef639e6fSAlexey Brodkin 
299*ef639e6fSAlexey Brodkin 	__after_dc_op(cacheop, ctrl_reg);
300*ef639e6fSAlexey Brodkin }
301*ef639e6fSAlexey Brodkin 
302*ef639e6fSAlexey Brodkin static inline void __dc_line_op(unsigned long paddr, unsigned long sz,
303*ef639e6fSAlexey Brodkin 				const int cacheop)
304*ef639e6fSAlexey Brodkin {
305*ef639e6fSAlexey Brodkin 	unsigned int ctrl_reg = __before_dc_op(cacheop);
306*ef639e6fSAlexey Brodkin 	__cache_line_loop(paddr, sz, cacheop);
307*ef639e6fSAlexey Brodkin 	__after_dc_op(cacheop, ctrl_reg);
308*ef639e6fSAlexey Brodkin }
309*ef639e6fSAlexey Brodkin #else
310*ef639e6fSAlexey Brodkin #define __dc_entire_op(cacheop)
311*ef639e6fSAlexey Brodkin #define __dc_line_op(paddr, sz, cacheop)
312*ef639e6fSAlexey Brodkin #endif /* !CONFIG_SYS_DCACHE_OFF */
313*ef639e6fSAlexey Brodkin 
314660d5f0dSAlexey Brodkin void invalidate_dcache_range(unsigned long start, unsigned long end)
315660d5f0dSAlexey Brodkin {
316*ef639e6fSAlexey Brodkin 	__dc_line_op(start, end - start, OP_INV);
317*ef639e6fSAlexey Brodkin #ifdef CONFIG_ISA_ARCV2
318*ef639e6fSAlexey Brodkin 	if (slc_exists)
319*ef639e6fSAlexey Brodkin 		__slc_line_op(start, end - start, OP_INV);
320660d5f0dSAlexey Brodkin #endif
321660d5f0dSAlexey Brodkin }
322660d5f0dSAlexey Brodkin 
323*ef639e6fSAlexey Brodkin void flush_dcache_range(unsigned long start, unsigned long end)
324660d5f0dSAlexey Brodkin {
325*ef639e6fSAlexey Brodkin 	__dc_line_op(start, end - start, OP_FLUSH);
326*ef639e6fSAlexey Brodkin #ifdef CONFIG_ISA_ARCV2
327*ef639e6fSAlexey Brodkin 	if (slc_exists)
328*ef639e6fSAlexey Brodkin 		__slc_line_op(start, end - start, OP_FLUSH);
329*ef639e6fSAlexey Brodkin #endif
330660d5f0dSAlexey Brodkin }
331660d5f0dSAlexey Brodkin 
332660d5f0dSAlexey Brodkin void flush_cache(unsigned long start, unsigned long size)
333660d5f0dSAlexey Brodkin {
334660d5f0dSAlexey Brodkin 	flush_dcache_range(start, start + size);
335660d5f0dSAlexey Brodkin }
3366eb15e50SAlexey Brodkin 
337*ef639e6fSAlexey Brodkin void invalidate_dcache_all(void)
338*ef639e6fSAlexey Brodkin {
339*ef639e6fSAlexey Brodkin 	__dc_entire_op(OP_INV);
3406eb15e50SAlexey Brodkin #ifdef CONFIG_ISA_ARCV2
341*ef639e6fSAlexey Brodkin 	if (slc_exists)
342*ef639e6fSAlexey Brodkin 		__slc_entire_op(OP_INV);
343*ef639e6fSAlexey Brodkin #endif
3446eb15e50SAlexey Brodkin }
3456eb15e50SAlexey Brodkin 
346*ef639e6fSAlexey Brodkin void flush_dcache_all(void)
3476eb15e50SAlexey Brodkin {
348*ef639e6fSAlexey Brodkin 	__dc_entire_op(OP_FLUSH);
349*ef639e6fSAlexey Brodkin #ifdef CONFIG_ISA_ARCV2
350*ef639e6fSAlexey Brodkin 	if (slc_exists)
351*ef639e6fSAlexey Brodkin 		__slc_entire_op(OP_FLUSH);
352*ef639e6fSAlexey Brodkin #endif
3536eb15e50SAlexey Brodkin }
354