]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/sh/cpu/sh3/cache.c
Add GPL-2.0+ SPDX-License-Identifier to source files
[karo-tx-uboot.git] / arch / sh / cpu / sh3 / cache.c
1 /*
2  * (C) Copyright 2007
3  * Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
4  *
5  * (C) Copyright 2007
6  * Nobobuhiro Iwamatsu <iwamatsu@nigauri.org>
7  *
8  * SPDX-License-Identifier:     GPL-2.0+
9  */
10
11 #include <common.h>
12 #include <command.h>
13 #include <asm/processor.h>
14 #include <asm/io.h>
15
16 /*
17  * Jump to P2 area.
18  * When handling TLB or caches, we need to do it from P2 area.
19  */
20 #define jump_to_P2()                    \
21   do {                                    \
22     unsigned long __dummy;              \
23     __asm__ __volatile__(                       \
24                 "mov.l  1f, %0\n\t"     \
25                 "or     %1, %0\n\t"     \
26                 "jmp    @%0\n\t"        \
27                 " nop\n\t"              \
28                 ".balign 4\n"           \
29                 "1:     .long 2f\n"     \
30                 "2:"                    \
31                 : "=&r" (__dummy)       \
32                 : "r" (0x20000000));    \
33   } while (0)
34
35 /*
36  * Back to P1 area.
37  */
38 #define back_to_P1()                                    \
39   do {                                                    \
40     unsigned long __dummy;                          \
41     __asm__ __volatile__(                           \
42                 "nop;nop;nop;nop;nop;nop;nop\n\t"       \
43                 "mov.l  1f, %0\n\t"                     \
44                 "jmp    @%0\n\t"                        \
45                 " nop\n\t"                              \
46                 ".balign 4\n"                           \
47                 "1:     .long 2f\n"                     \
48                 "2:"                                    \
49                 : "=&r" (__dummy));                     \
50   } while (0)
51
52 #define CACHE_VALID       1
53 #define CACHE_UPDATED     2
54
55 static inline void cache_wback_all(void)
56 {
57         unsigned long addr, data, i, j;
58
59         jump_to_P2();
60         for (i = 0; i < CACHE_OC_NUM_ENTRIES; i++) {
61                 for (j = 0; j < CACHE_OC_NUM_WAYS; j++) {
62                         addr = CACHE_OC_ADDRESS_ARRAY
63                                 | (j << CACHE_OC_WAY_SHIFT)
64                                 | (i << CACHE_OC_ENTRY_SHIFT);
65                         data = inl(addr);
66                         if (data & CACHE_UPDATED) {
67                                 data &= ~CACHE_UPDATED;
68                                 outl(data, addr);
69                         }
70                 }
71         }
72         back_to_P1();
73 }
74
75
76 #define CACHE_ENABLE      0
77 #define CACHE_DISABLE     1
78
79 int cache_control(unsigned int cmd)
80 {
81         unsigned long ccr;
82
83         jump_to_P2();
84         ccr = inl(CCR);
85
86         if (ccr & CCR_CACHE_ENABLE)
87                 cache_wback_all();
88
89         if (cmd == CACHE_DISABLE)
90                 outl(CCR_CACHE_STOP, CCR);
91         else
92                 outl(CCR_CACHE_INIT, CCR);
93         back_to_P1();
94
95         return 0;
96 }