Merge branch 'master' of git://git.denx.de/u-boot-sh
[oweals/u-boot.git] / arch / arc / lib / cache.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
4  */
5
6 #include <config.h>
7 #include <common.h>
8 #include <linux/compiler.h>
9 #include <linux/kernel.h>
10 #include <linux/log2.h>
11 #include <asm/arcregs.h>
12 #include <asm/arc-bcr.h>
13 #include <asm/cache.h>
14
15 /*
16  * [ NOTE 1 ]:
17  * Data cache (L1 D$ or SL$) entire invalidate operation or data cache disable
18  * operation may result in unexpected behavior and data loss even if we flush
19  * data cache right before invalidation. That may happens if we store any context
20  * on stack (like we store BLINK register on stack before function call).
21  * BLINK register is the register where return address is automatically saved
22  * when we do function call with instructions like 'bl'.
23  *
24  * There is the real example:
25  * We may hang in the next code as we store any BLINK register on stack in
26  * invalidate_dcache_all() function.
27  *
28  * void flush_dcache_all() {
29  *     __dc_entire_op(OP_FLUSH);
30  *     // Other code //
31  * }
32  *
33  * void invalidate_dcache_all() {
34  *     __dc_entire_op(OP_INV);
35  *     // Other code //
36  * }
37  *
38  * void foo(void) {
39  *     flush_dcache_all();
40  *     invalidate_dcache_all();
41  * }
42  *
43  * Now let's see what really happens during that code execution:
44  *
45  * foo()
46  *   |->> call flush_dcache_all
47  *     [return address is saved to BLINK register]
48  *     [push BLINK] (save to stack)              ![point 1]
49  *     |->> call __dc_entire_op(OP_FLUSH)
50  *         [return address is saved to BLINK register]
51  *         [flush L1 D$]
52  *         return [jump to BLINK]
53  *     <<------
54  *     [other flush_dcache_all code]
55  *     [pop BLINK] (get from stack)
56  *     return [jump to BLINK]
57  *   <<------
58  *   |->> call invalidate_dcache_all
59  *     [return address is saved to BLINK register]
60  *     [push BLINK] (save to stack)               ![point 2]
61  *     |->> call __dc_entire_op(OP_FLUSH)
62  *         [return address is saved to BLINK register]
63  *         [invalidate L1 D$]                 ![point 3]
64  *         // Oops!!!
65  *         // We lose return address from invalidate_dcache_all function:
66  *         // we save it to stack and invalidate L1 D$ after that!
67  *         return [jump to BLINK]
68  *     <<------
69  *     [other invalidate_dcache_all code]
70  *     [pop BLINK] (get from stack)
71  *     // we don't have this data in L1 dcache as we invalidated it in [point 3]
72  *     // so we get it from next memory level (for example DDR memory)
73  *     // but in the memory we have value which we save in [point 1], which
74  *     // is return address from flush_dcache_all function (instead of
75  *     // address from current invalidate_dcache_all function which we
76  *     // saved in [point 2] !)
77  *     return [jump to BLINK]
78  *   <<------
79  *   // As BLINK points to invalidate_dcache_all, we call it again and
80  *   // loop forever.
81  *
82  * Fortunately we may fix that by using flush & invalidation of D$ with a single
83  * one instruction (instead of flush and invalidation instructions pair) and
84  * enabling force function inline with '__attribute__((always_inline))' gcc
85  * attribute to avoid any function call (and BLINK store) between cache flush
86  * and disable.
87  *
88  *
89  * [ NOTE 2 ]:
90  * As of today we only support the following cache configurations on ARC.
91  * Other configurations may exist in HW (for example, since version 3.0 HS
92  * supports SL$ (L2 system level cache) disable) but we don't support it in SW.
93  * Configuration 1:
94  *        ______________________
95  *       |                      |
96  *       |   ARC CPU            |
97  *       |______________________|
98  *        ___|___        ___|___
99  *       |       |      |       |
100  *       | L1 I$ |      | L1 D$ |
101  *       |_______|      |_______|
102  *        on/off         on/off
103  *        ___|______________|____
104  *       |                      |
105  *       |   main memory        |
106  *       |______________________|
107  *
108  * Configuration 2:
109  *        ______________________
110  *       |                      |
111  *       |   ARC CPU            |
112  *       |______________________|
113  *        ___|___        ___|___
114  *       |       |      |       |
115  *       | L1 I$ |      | L1 D$ |
116  *       |_______|      |_______|
117  *        on/off         on/off
118  *        ___|______________|____
119  *       |                      |
120  *       |   L2 (SL$)           |
121  *       |______________________|
122  *          always must be on
123  *        ___|______________|____
124  *       |                      |
125  *       |   main memory        |
126  *       |______________________|
127  *
128  * Configuration 3:
129  *        ______________________
130  *       |                      |
131  *       |   ARC CPU            |
132  *       |______________________|
133  *        ___|___        ___|___
134  *       |       |      |       |
135  *       | L1 I$ |      | L1 D$ |
136  *       |_______|      |_______|
137  *        on/off        must be on
138  *        ___|______________|____      _______
139  *       |                      |     |       |
140  *       |   L2 (SL$)           |-----|  IOC  |
141  *       |______________________|     |_______|
142  *          always must be on          on/off
143  *        ___|______________|____
144  *       |                      |
145  *       |   main memory        |
146  *       |______________________|
147  */
148
149 DECLARE_GLOBAL_DATA_PTR;
150
151 /* Bit values in IC_CTRL */
152 #define IC_CTRL_CACHE_DISABLE   BIT(0)
153
154 /* Bit values in DC_CTRL */
155 #define DC_CTRL_CACHE_DISABLE   BIT(0)
156 #define DC_CTRL_INV_MODE_FLUSH  BIT(6)
157 #define DC_CTRL_FLUSH_STATUS    BIT(8)
158
159 #define OP_INV                  BIT(0)
160 #define OP_FLUSH                BIT(1)
161 #define OP_FLUSH_N_INV          (OP_FLUSH | OP_INV)
162
163 /* Bit val in SLC_CONTROL */
164 #define SLC_CTRL_DIS            0x001
165 #define SLC_CTRL_IM             0x040
166 #define SLC_CTRL_BUSY           0x100
167 #define SLC_CTRL_RGN_OP_INV     0x200
168
169 #define CACHE_LINE_MASK         (~(gd->arch.l1_line_sz - 1))
170
171 /*
172  * We don't want to use '__always_inline' macro here as it can be redefined
173  * to simple 'inline' in some cases which breaks stuff. See [ NOTE 1 ] for more
174  * details about the reasons we need to use always_inline functions.
175  */
176 #define inlined_cachefunc        inline __attribute__((always_inline))
177
178 static inlined_cachefunc void __ic_entire_invalidate(void);
179 static inlined_cachefunc void __dc_entire_op(const int cacheop);
180
181 static inline bool pae_exists(void)
182 {
183         /* TODO: should we compare mmu version from BCR and from CONFIG? */
184 #if (CONFIG_ARC_MMU_VER >= 4)
185         union bcr_mmu_4 mmu4;
186
187         mmu4.word = read_aux_reg(ARC_AUX_MMU_BCR);
188
189         if (mmu4.fields.pae)
190                 return true;
191 #endif /* (CONFIG_ARC_MMU_VER >= 4) */
192
193         return false;
194 }
195
196 static inlined_cachefunc bool icache_exists(void)
197 {
198         union bcr_di_cache ibcr;
199
200         ibcr.word = read_aux_reg(ARC_BCR_IC_BUILD);
201         return !!ibcr.fields.ver;
202 }
203
204 static inlined_cachefunc bool icache_enabled(void)
205 {
206         if (!icache_exists())
207                 return false;
208
209         return !(read_aux_reg(ARC_AUX_IC_CTRL) & IC_CTRL_CACHE_DISABLE);
210 }
211
212 static inlined_cachefunc bool dcache_exists(void)
213 {
214         union bcr_di_cache dbcr;
215
216         dbcr.word = read_aux_reg(ARC_BCR_DC_BUILD);
217         return !!dbcr.fields.ver;
218 }
219
220 static inlined_cachefunc bool dcache_enabled(void)
221 {
222         if (!dcache_exists())
223                 return false;
224
225         return !(read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_CACHE_DISABLE);
226 }
227
228 static inlined_cachefunc bool slc_exists(void)
229 {
230         if (is_isa_arcv2()) {
231                 union bcr_generic sbcr;
232
233                 sbcr.word = read_aux_reg(ARC_BCR_SLC);
234                 return !!sbcr.fields.ver;
235         }
236
237         return false;
238 }
239
240 static inlined_cachefunc bool slc_data_bypass(void)
241 {
242         /*
243          * If L1 data cache is disabled SL$ is bypassed and all load/store
244          * requests are sent directly to main memory.
245          */
246         return !dcache_enabled();
247 }
248
249 static inline bool ioc_exists(void)
250 {
251         if (is_isa_arcv2()) {
252                 union bcr_clust_cfg cbcr;
253
254                 cbcr.word = read_aux_reg(ARC_BCR_CLUSTER);
255                 return cbcr.fields.c;
256         }
257
258         return false;
259 }
260
261 static inline bool ioc_enabled(void)
262 {
263         /*
264          * We check only CONFIG option instead of IOC HW state check as IOC
265          * must be disabled by default.
266          */
267         if (is_ioc_enabled())
268                 return ioc_exists();
269
270         return false;
271 }
272
273 static inlined_cachefunc void __slc_entire_op(const int op)
274 {
275         unsigned int ctrl;
276
277         if (!slc_exists())
278                 return;
279
280         ctrl = read_aux_reg(ARC_AUX_SLC_CTRL);
281
282         if (!(op & OP_FLUSH))           /* i.e. OP_INV */
283                 ctrl &= ~SLC_CTRL_IM;   /* clear IM: Disable flush before Inv */
284         else
285                 ctrl |= SLC_CTRL_IM;
286
287         write_aux_reg(ARC_AUX_SLC_CTRL, ctrl);
288
289         if (op & OP_INV)        /* Inv or flush-n-inv use same cmd reg */
290                 write_aux_reg(ARC_AUX_SLC_INVALIDATE, 0x1);
291         else
292                 write_aux_reg(ARC_AUX_SLC_FLUSH, 0x1);
293
294         /* Make sure "busy" bit reports correct stataus, see STAR 9001165532 */
295         read_aux_reg(ARC_AUX_SLC_CTRL);
296
297         /* Important to wait for flush to complete */
298         while (read_aux_reg(ARC_AUX_SLC_CTRL) & SLC_CTRL_BUSY);
299 }
300
301 static void slc_upper_region_init(void)
302 {
303         /*
304          * ARC_AUX_SLC_RGN_START1 and ARC_AUX_SLC_RGN_END1 register exist
305          * only if PAE exists in current HW. So we had to check pae_exist
306          * before using them.
307          */
308         if (!pae_exists())
309                 return;
310
311         /*
312          * ARC_AUX_SLC_RGN_END1 and ARC_AUX_SLC_RGN_START1 are always == 0
313          * as we don't use PAE40.
314          */
315         write_aux_reg(ARC_AUX_SLC_RGN_END1, 0);
316         write_aux_reg(ARC_AUX_SLC_RGN_START1, 0);
317 }
318
319 static void __slc_rgn_op(unsigned long paddr, unsigned long sz, const int op)
320 {
321 #ifdef CONFIG_ISA_ARCV2
322
323         unsigned int ctrl;
324         unsigned long end;
325
326         if (!slc_exists())
327                 return;
328
329         /*
330          * The Region Flush operation is specified by CTRL.RGN_OP[11..9]
331          *  - b'000 (default) is Flush,
332          *  - b'001 is Invalidate if CTRL.IM == 0
333          *  - b'001 is Flush-n-Invalidate if CTRL.IM == 1
334          */
335         ctrl = read_aux_reg(ARC_AUX_SLC_CTRL);
336
337         /* Don't rely on default value of IM bit */
338         if (!(op & OP_FLUSH))           /* i.e. OP_INV */
339                 ctrl &= ~SLC_CTRL_IM;   /* clear IM: Disable flush before Inv */
340         else
341                 ctrl |= SLC_CTRL_IM;
342
343         if (op & OP_INV)
344                 ctrl |= SLC_CTRL_RGN_OP_INV;    /* Inv or flush-n-inv */
345         else
346                 ctrl &= ~SLC_CTRL_RGN_OP_INV;
347
348         write_aux_reg(ARC_AUX_SLC_CTRL, ctrl);
349
350         /*
351          * Lower bits are ignored, no need to clip
352          * END needs to be setup before START (latter triggers the operation)
353          * END can't be same as START, so add (l2_line_sz - 1) to sz
354          */
355         end = paddr + sz + gd->arch.slc_line_sz - 1;
356
357         /*
358          * Upper addresses (ARC_AUX_SLC_RGN_END1 and ARC_AUX_SLC_RGN_START1)
359          * are always == 0 as we don't use PAE40, so we only setup lower ones
360          * (ARC_AUX_SLC_RGN_END and ARC_AUX_SLC_RGN_START)
361          */
362         write_aux_reg(ARC_AUX_SLC_RGN_END, end);
363         write_aux_reg(ARC_AUX_SLC_RGN_START, paddr);
364
365         /* Make sure "busy" bit reports correct stataus, see STAR 9001165532 */
366         read_aux_reg(ARC_AUX_SLC_CTRL);
367
368         while (read_aux_reg(ARC_AUX_SLC_CTRL) & SLC_CTRL_BUSY);
369
370 #endif /* CONFIG_ISA_ARCV2 */
371 }
372
373 static void arc_ioc_setup(void)
374 {
375         /* IOC Aperture start is equal to DDR start */
376         unsigned int ap_base = CONFIG_SYS_SDRAM_BASE;
377         /* IOC Aperture size is equal to DDR size */
378         long ap_size = CONFIG_SYS_SDRAM_SIZE;
379
380         /* Unsupported configuration. See [ NOTE 2 ] for more details. */
381         if (!slc_exists())
382                 panic("Try to enable IOC but SLC is not present");
383
384         /* Unsupported configuration. See [ NOTE 2 ] for more details. */
385         if (!dcache_enabled())
386                 panic("Try to enable IOC but L1 D$ is disabled");
387
388         if (!is_power_of_2(ap_size) || ap_size < 4096)
389                 panic("IOC Aperture size must be power of 2 and bigger 4Kib");
390
391         /* IOC Aperture start must be aligned to the size of the aperture */
392         if (ap_base % ap_size != 0)
393                 panic("IOC Aperture start must be aligned to the size of the aperture");
394
395         flush_n_invalidate_dcache_all();
396
397         /*
398          * IOC Aperture size decoded as 2 ^ (SIZE + 2) KB,
399          * so setting 0x11 implies 512M, 0x12 implies 1G...
400          */
401         write_aux_reg(ARC_AUX_IO_COH_AP0_SIZE,
402                       order_base_2(ap_size / 1024) - 2);
403
404         write_aux_reg(ARC_AUX_IO_COH_AP0_BASE, ap_base >> 12);
405         write_aux_reg(ARC_AUX_IO_COH_PARTIAL, 1);
406         write_aux_reg(ARC_AUX_IO_COH_ENABLE, 1);
407 }
408
409 static void read_decode_cache_bcr_arcv2(void)
410 {
411 #ifdef CONFIG_ISA_ARCV2
412
413         union bcr_slc_cfg slc_cfg;
414
415         if (slc_exists()) {
416                 slc_cfg.word = read_aux_reg(ARC_AUX_SLC_CONFIG);
417                 gd->arch.slc_line_sz = (slc_cfg.fields.lsz == 0) ? 128 : 64;
418
419                 /*
420                  * We don't support configuration where L1 I$ or L1 D$ is
421                  * absent but SL$ exists. See [ NOTE 2 ] for more details.
422                  */
423                 if (!icache_exists() || !dcache_exists())
424                         panic("Unsupported cache configuration: SLC exists but one of L1 caches is absent");
425         }
426
427 #endif /* CONFIG_ISA_ARCV2 */
428 }
429
430 void read_decode_cache_bcr(void)
431 {
432         int dc_line_sz = 0, ic_line_sz = 0;
433         union bcr_di_cache ibcr, dbcr;
434
435         /*
436          * We don't care much about I$ line length really as there're
437          * no per-line ops on I$ instead we only do full invalidation of it
438          * on occasion of relocation and right before jumping to the OS.
439          * Still we check insane config with zero-encoded line length in
440          * presense of version field in I$ BCR. Just in case.
441          */
442         ibcr.word = read_aux_reg(ARC_BCR_IC_BUILD);
443         if (ibcr.fields.ver) {
444                 ic_line_sz = 8 << ibcr.fields.line_len;
445                 if (!ic_line_sz)
446                         panic("Instruction exists but line length is 0\n");
447         }
448
449         dbcr.word = read_aux_reg(ARC_BCR_DC_BUILD);
450         if (dbcr.fields.ver) {
451                 gd->arch.l1_line_sz = dc_line_sz = 16 << dbcr.fields.line_len;
452                 if (!dc_line_sz)
453                         panic("Data cache exists but line length is 0\n");
454         }
455 }
456
457 void cache_init(void)
458 {
459         read_decode_cache_bcr();
460
461         if (is_isa_arcv2())
462                 read_decode_cache_bcr_arcv2();
463
464         if (is_isa_arcv2() && ioc_enabled())
465                 arc_ioc_setup();
466
467         if (is_isa_arcv2() && slc_exists())
468                 slc_upper_region_init();
469 }
470
471 int icache_status(void)
472 {
473         return icache_enabled();
474 }
475
476 void icache_enable(void)
477 {
478         if (icache_exists())
479                 write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) &
480                               ~IC_CTRL_CACHE_DISABLE);
481 }
482
483 void icache_disable(void)
484 {
485         if (!icache_exists())
486                 return;
487
488         __ic_entire_invalidate();
489
490         write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) |
491                       IC_CTRL_CACHE_DISABLE);
492 }
493
494 /* IC supports only invalidation */
495 static inlined_cachefunc void __ic_entire_invalidate(void)
496 {
497         if (!icache_enabled())
498                 return;
499
500         /* Any write to IC_IVIC register triggers invalidation of entire I$ */
501         write_aux_reg(ARC_AUX_IC_IVIC, 1);
502         /*
503          * As per ARC HS databook (see chapter 5.3.3.2)
504          * it is required to add 3 NOPs after each write to IC_IVIC.
505          */
506         __builtin_arc_nop();
507         __builtin_arc_nop();
508         __builtin_arc_nop();
509         read_aux_reg(ARC_AUX_IC_CTRL);  /* blocks */
510 }
511
512 void invalidate_icache_all(void)
513 {
514         __ic_entire_invalidate();
515
516         /*
517          * If SL$ is bypassed for data it is used only for instructions,
518          * so we need to invalidate it too.
519          * TODO: HS 3.0 supports SLC disable so we need to check slc
520          * enable/disable status here.
521          */
522         if (is_isa_arcv2() && slc_data_bypass())
523                 __slc_entire_op(OP_INV);
524 }
525
526 int dcache_status(void)
527 {
528         return dcache_enabled();
529 }
530
531 void dcache_enable(void)
532 {
533         if (!dcache_exists())
534                 return;
535
536         write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) &
537                       ~(DC_CTRL_INV_MODE_FLUSH | DC_CTRL_CACHE_DISABLE));
538 }
539
540 void dcache_disable(void)
541 {
542         if (!dcache_exists())
543                 return;
544
545         __dc_entire_op(OP_FLUSH_N_INV);
546
547         /*
548          * As SLC will be bypassed for data after L1 D$ disable we need to
549          * flush it first before L1 D$ disable. Also we invalidate SLC to
550          * avoid any inconsistent data problems after enabling L1 D$ again with
551          * dcache_enable function.
552          */
553         if (is_isa_arcv2())
554                 __slc_entire_op(OP_FLUSH_N_INV);
555
556         write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) |
557                       DC_CTRL_CACHE_DISABLE);
558 }
559
560 /* Common Helper for Line Operations on D-cache */
561 static inline void __dcache_line_loop(unsigned long paddr, unsigned long sz,
562                                       const int cacheop)
563 {
564         unsigned int aux_cmd;
565         int num_lines;
566
567         /* d$ cmd: INV (discard or wback-n-discard) OR FLUSH (wback) */
568         aux_cmd = cacheop & OP_INV ? ARC_AUX_DC_IVDL : ARC_AUX_DC_FLDL;
569
570         sz += paddr & ~CACHE_LINE_MASK;
571         paddr &= CACHE_LINE_MASK;
572
573         num_lines = DIV_ROUND_UP(sz, gd->arch.l1_line_sz);
574
575         while (num_lines-- > 0) {
576 #if (CONFIG_ARC_MMU_VER == 3)
577                 write_aux_reg(ARC_AUX_DC_PTAG, paddr);
578 #endif
579                 write_aux_reg(aux_cmd, paddr);
580                 paddr += gd->arch.l1_line_sz;
581         }
582 }
583
584 static inlined_cachefunc void __before_dc_op(const int op)
585 {
586         unsigned int ctrl;
587
588         ctrl = read_aux_reg(ARC_AUX_DC_CTRL);
589
590         /* IM bit implies flush-n-inv, instead of vanilla inv */
591         if (op == OP_INV)
592                 ctrl &= ~DC_CTRL_INV_MODE_FLUSH;
593         else
594                 ctrl |= DC_CTRL_INV_MODE_FLUSH;
595
596         write_aux_reg(ARC_AUX_DC_CTRL, ctrl);
597 }
598
599 static inlined_cachefunc void __after_dc_op(const int op)
600 {
601         if (op & OP_FLUSH)      /* flush / flush-n-inv both wait */
602                 while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS);
603 }
604
605 static inlined_cachefunc void __dc_entire_op(const int cacheop)
606 {
607         int aux;
608
609         if (!dcache_enabled())
610                 return;
611
612         __before_dc_op(cacheop);
613
614         if (cacheop & OP_INV)   /* Inv or flush-n-inv use same cmd reg */
615                 aux = ARC_AUX_DC_IVDC;
616         else
617                 aux = ARC_AUX_DC_FLSH;
618
619         write_aux_reg(aux, 0x1);
620
621         __after_dc_op(cacheop);
622 }
623
624 static inline void __dc_line_op(unsigned long paddr, unsigned long sz,
625                                 const int cacheop)
626 {
627         if (!dcache_enabled())
628                 return;
629
630         __before_dc_op(cacheop);
631         __dcache_line_loop(paddr, sz, cacheop);
632         __after_dc_op(cacheop);
633 }
634
635 void invalidate_dcache_range(unsigned long start, unsigned long end)
636 {
637         if (start >= end)
638                 return;
639
640         /*
641          * ARCv1                                 -> call __dc_line_op
642          * ARCv2 && L1 D$ disabled               -> nothing
643          * ARCv2 && L1 D$ enabled && IOC enabled -> nothing
644          * ARCv2 && L1 D$ enabled && no IOC      -> call __dc_line_op; call __slc_rgn_op
645          */
646         if (!is_isa_arcv2() || !ioc_enabled())
647                 __dc_line_op(start, end - start, OP_INV);
648
649         if (is_isa_arcv2() && !ioc_enabled() && !slc_data_bypass())
650                 __slc_rgn_op(start, end - start, OP_INV);
651 }
652
653 void flush_dcache_range(unsigned long start, unsigned long end)
654 {
655         if (start >= end)
656                 return;
657
658         /*
659          * ARCv1                                 -> call __dc_line_op
660          * ARCv2 && L1 D$ disabled               -> nothing
661          * ARCv2 && L1 D$ enabled && IOC enabled -> nothing
662          * ARCv2 && L1 D$ enabled && no IOC      -> call __dc_line_op; call __slc_rgn_op
663          */
664         if (!is_isa_arcv2() || !ioc_enabled())
665                 __dc_line_op(start, end - start, OP_FLUSH);
666
667         if (is_isa_arcv2() && !ioc_enabled() && !slc_data_bypass())
668                 __slc_rgn_op(start, end - start, OP_FLUSH);
669 }
670
671 void flush_cache(unsigned long start, unsigned long size)
672 {
673         flush_dcache_range(start, start + size);
674 }
675
676 /*
677  * As invalidate_dcache_all() is not used in generic U-Boot code and as we
678  * don't need it in arch/arc code alone (invalidate without flush) we implement
679  * flush_n_invalidate_dcache_all (flush and invalidate in 1 operation) because
680  * it's much safer. See [ NOTE 1 ] for more details.
681  */
682 void flush_n_invalidate_dcache_all(void)
683 {
684         __dc_entire_op(OP_FLUSH_N_INV);
685
686         if (is_isa_arcv2() && !slc_data_bypass())
687                 __slc_entire_op(OP_FLUSH_N_INV);
688 }
689
690 void flush_dcache_all(void)
691 {
692         __dc_entire_op(OP_FLUSH);
693
694         if (is_isa_arcv2() && !slc_data_bypass())
695                 __slc_entire_op(OP_FLUSH);
696 }
697
698 /*
699  * This is function to cleanup all caches (and therefore sync I/D caches) which
700  * can be used for cleanup before linux launch or to sync caches during
701  * relocation.
702  */
703 void sync_n_cleanup_cache_all(void)
704 {
705         __dc_entire_op(OP_FLUSH_N_INV);
706
707         /*
708          * If SL$ is bypassed for data it is used only for instructions,
709          * and we shouldn't flush it. So invalidate it instead of flush_n_inv.
710          */
711         if (is_isa_arcv2()) {
712                 if (slc_data_bypass())
713                         __slc_entire_op(OP_INV);
714                 else
715                         __slc_entire_op(OP_FLUSH_N_INV);
716         }
717
718         __ic_entire_invalidate();
719 }