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