License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[sfrench/cifs-2.6.git] / arch / metag / include / asm / l2cache.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _METAG_L2CACHE_H
3 #define _METAG_L2CACHE_H
4
5 #ifdef CONFIG_METAG_L2C
6
7 #include <asm/global_lock.h>
8 #include <asm/io.h>
9
10 /*
11  * Store the last known value of pfenable (we don't want prefetch enabled while
12  * L2 is off).
13  */
14 extern int l2c_pfenable;
15
16 /* defined in arch/metag/drivers/core-sysfs.c */
17 extern struct sysdev_class cache_sysclass;
18
19 static inline void wr_fence(void);
20
21 /*
22  * Functions for reading of L2 cache configuration.
23  */
24
25 /* Get raw L2 config register (CORE_CONFIG3) */
26 static inline unsigned int meta_l2c_config(void)
27 {
28         const unsigned int *corecfg3 = (const unsigned int *)METAC_CORE_CONFIG3;
29         return *corecfg3;
30 }
31
32 /* Get whether the L2 is present */
33 static inline int meta_l2c_is_present(void)
34 {
35         return meta_l2c_config() & METAC_CORECFG3_L2C_HAVE_L2C_BIT;
36 }
37
38 /* Get whether the L2 is configured for write-back instead of write-through */
39 static inline int meta_l2c_is_writeback(void)
40 {
41         return meta_l2c_config() & METAC_CORECFG3_L2C_MODE_BIT;
42 }
43
44 /* Get whether the L2 is unified instead of separated code/data */
45 static inline int meta_l2c_is_unified(void)
46 {
47         return meta_l2c_config() & METAC_CORECFG3_L2C_UNIFIED_BIT;
48 }
49
50 /* Get the L2 cache size in bytes */
51 static inline unsigned int meta_l2c_size(void)
52 {
53         unsigned int size_s;
54         if (!meta_l2c_is_present())
55                 return 0;
56         size_s = (meta_l2c_config() & METAC_CORECFG3_L2C_SIZE_BITS)
57                         >> METAC_CORECFG3_L2C_SIZE_S;
58         /* L2CSIZE is in KiB */
59         return 1024 << size_s;
60 }
61
62 /* Get the number of ways in the L2 cache */
63 static inline unsigned int meta_l2c_ways(void)
64 {
65         unsigned int ways_s;
66         if (!meta_l2c_is_present())
67                 return 0;
68         ways_s = (meta_l2c_config() & METAC_CORECFG3_L2C_NUM_WAYS_BITS)
69                         >> METAC_CORECFG3_L2C_NUM_WAYS_S;
70         return 0x1 << ways_s;
71 }
72
73 /* Get the line size of the L2 cache */
74 static inline unsigned int meta_l2c_linesize(void)
75 {
76         unsigned int line_size;
77         if (!meta_l2c_is_present())
78                 return 0;
79         line_size = (meta_l2c_config() & METAC_CORECFG3_L2C_LINE_SIZE_BITS)
80                         >> METAC_CORECFG3_L2C_LINE_SIZE_S;
81         switch (line_size) {
82         case METAC_CORECFG3_L2C_LINE_SIZE_64B:
83                 return 64;
84         default:
85                 return 0;
86         }
87 }
88
89 /* Get the revision ID of the L2 cache */
90 static inline unsigned int meta_l2c_revision(void)
91 {
92         return (meta_l2c_config() & METAC_CORECFG3_L2C_REV_ID_BITS)
93                         >> METAC_CORECFG3_L2C_REV_ID_S;
94 }
95
96
97 /*
98  * Start an initialisation of the L2 cachelines and wait for completion.
99  * This should only be done in a LOCK1 or LOCK2 critical section while the L2
100  * is disabled.
101  */
102 static inline void _meta_l2c_init(void)
103 {
104         metag_out32(SYSC_L2C_INIT_INIT, SYSC_L2C_INIT);
105         while (metag_in32(SYSC_L2C_INIT) == SYSC_L2C_INIT_IN_PROGRESS)
106                 /* do nothing */;
107 }
108
109 /*
110  * Start a writeback of dirty L2 cachelines and wait for completion.
111  * This should only be done in a LOCK1 or LOCK2 critical section.
112  */
113 static inline void _meta_l2c_purge(void)
114 {
115         metag_out32(SYSC_L2C_PURGE_PURGE, SYSC_L2C_PURGE);
116         while (metag_in32(SYSC_L2C_PURGE) == SYSC_L2C_PURGE_IN_PROGRESS)
117                 /* do nothing */;
118 }
119
120 /* Set whether the L2 cache is enabled. */
121 static inline void _meta_l2c_enable(int enabled)
122 {
123         unsigned int enable;
124
125         enable = metag_in32(SYSC_L2C_ENABLE);
126         if (enabled)
127                 enable |= SYSC_L2C_ENABLE_ENABLE_BIT;
128         else
129                 enable &= ~SYSC_L2C_ENABLE_ENABLE_BIT;
130         metag_out32(enable, SYSC_L2C_ENABLE);
131 }
132
133 /* Set whether the L2 cache prefetch is enabled. */
134 static inline void _meta_l2c_pf_enable(int pfenabled)
135 {
136         unsigned int enable;
137
138         enable = metag_in32(SYSC_L2C_ENABLE);
139         if (pfenabled)
140                 enable |= SYSC_L2C_ENABLE_PFENABLE_BIT;
141         else
142                 enable &= ~SYSC_L2C_ENABLE_PFENABLE_BIT;
143         metag_out32(enable, SYSC_L2C_ENABLE);
144 }
145
146 /* Return whether the L2 cache is enabled */
147 static inline int _meta_l2c_is_enabled(void)
148 {
149         return metag_in32(SYSC_L2C_ENABLE) & SYSC_L2C_ENABLE_ENABLE_BIT;
150 }
151
152 /* Return whether the L2 cache prefetch is enabled */
153 static inline int _meta_l2c_pf_is_enabled(void)
154 {
155         return metag_in32(SYSC_L2C_ENABLE) & SYSC_L2C_ENABLE_PFENABLE_BIT;
156 }
157
158
159 /* Return whether the L2 cache is enabled */
160 static inline int meta_l2c_is_enabled(void)
161 {
162         int en;
163
164         /*
165          * There is no need to lock at the moment, as the enable bit is never
166          * intermediately changed, so we will never see an intermediate result.
167          */
168         en = _meta_l2c_is_enabled();
169
170         return en;
171 }
172
173 /*
174  * Ensure the L2 cache is disabled.
175  * Return whether the L2 was previously disabled.
176  */
177 int meta_l2c_disable(void);
178
179 /*
180  * Ensure the L2 cache is enabled.
181  * Return whether the L2 was previously enabled.
182  */
183 int meta_l2c_enable(void);
184
185 /* Return whether the L2 cache prefetch is enabled */
186 static inline int meta_l2c_pf_is_enabled(void)
187 {
188         return l2c_pfenable;
189 }
190
191 /*
192  * Set whether the L2 cache prefetch is enabled.
193  * Return whether the L2 prefetch was previously enabled.
194  */
195 int meta_l2c_pf_enable(int pfenable);
196
197 /*
198  * Flush the L2 cache.
199  * Return 1 if the L2 is disabled.
200  */
201 int meta_l2c_flush(void);
202
203 /*
204  * Write back all dirty cache lines in the L2 cache.
205  * Return 1 if the L2 is disabled or there isn't any writeback.
206  */
207 static inline int meta_l2c_writeback(void)
208 {
209         unsigned long flags;
210         int en;
211
212         /* no need to purge if it's not a writeback cache */
213         if (!meta_l2c_is_writeback())
214                 return 1;
215
216         /*
217          * Purge only works if the L2 is enabled, and involves reading back to
218          * detect completion, so keep this operation atomic with other threads.
219          */
220         __global_lock1(flags);
221         en = meta_l2c_is_enabled();
222         if (likely(en)) {
223                 wr_fence();
224                 _meta_l2c_purge();
225         }
226         __global_unlock1(flags);
227
228         return !en;
229 }
230
231 #else /* CONFIG_METAG_L2C */
232
233 #define meta_l2c_config()               0
234 #define meta_l2c_is_present()           0
235 #define meta_l2c_is_writeback()         0
236 #define meta_l2c_is_unified()           0
237 #define meta_l2c_size()                 0
238 #define meta_l2c_ways()                 0
239 #define meta_l2c_linesize()             0
240 #define meta_l2c_revision()             0
241
242 #define meta_l2c_is_enabled()           0
243 #define _meta_l2c_pf_is_enabled()       0
244 #define meta_l2c_pf_is_enabled()        0
245 #define meta_l2c_disable()              1
246 #define meta_l2c_enable()               0
247 #define meta_l2c_pf_enable(X)           0
248 static inline int meta_l2c_flush(void)
249 {
250         return 1;
251 }
252 static inline int meta_l2c_writeback(void)
253 {
254         return 1;
255 }
256
257 #endif /* CONFIG_METAG_L2C */
258
259 #endif /* _METAG_L2CACHE_H */