1
2
3
4
5
6
7
8
9
10
11#include <linux/err.h>
12#include <linux/spinlock.h>
13#include <linux/io.h>
14#include <linux/bitops.h>
15#include <linux/of_address.h>
16#include <linux/notifier.h>
17#include <linux/cpu.h>
18#include <linux/syscore_ops.h>
19#include <linux/reboot.h>
20
21#include <asm/cacheflush.h>
22#include <asm/hardware/cache-b15-rac.h>
23
24extern void v7_flush_kern_cache_all(void);
25
26
27#define RAC_CONFIG0_REG (0x78)
28#define RACENPREF_MASK (0x3)
29#define RACPREFINST_SHIFT (0)
30#define RACENINST_SHIFT (2)
31#define RACPREFDATA_SHIFT (4)
32#define RACENDATA_SHIFT (6)
33#define RAC_CPU_SHIFT (8)
34#define RACCFG_MASK (0xff)
35#define RAC_CONFIG1_REG (0x7c)
36#define RAC_FLUSH_REG (0x80)
37#define FLUSH_RAC (1 << 0)
38
39
40#define RAC_DATA_INST_EN_MASK (1 << RACPREFINST_SHIFT | \
41 RACENPREF_MASK << RACENINST_SHIFT | \
42 1 << RACPREFDATA_SHIFT | \
43 RACENPREF_MASK << RACENDATA_SHIFT)
44
45#define RAC_ENABLED 0
46
47
48
49#define RAC_SUSPENDED 1
50
51static void __iomem *b15_rac_base;
52static DEFINE_SPINLOCK(rac_lock);
53
54static u32 rac_config0_reg;
55
56
57
58
59static unsigned long b15_rac_flags;
60
61static inline u32 __b15_rac_disable(void)
62{
63 u32 val = __raw_readl(b15_rac_base + RAC_CONFIG0_REG);
64 __raw_writel(0, b15_rac_base + RAC_CONFIG0_REG);
65 dmb();
66 return val;
67}
68
69static inline void __b15_rac_flush(void)
70{
71 u32 reg;
72
73 __raw_writel(FLUSH_RAC, b15_rac_base + RAC_FLUSH_REG);
74 do {
75
76
77
78
79 dmb();
80 reg = __raw_readl(b15_rac_base + RAC_FLUSH_REG);
81 } while (reg & FLUSH_RAC);
82}
83
84static inline u32 b15_rac_disable_and_flush(void)
85{
86 u32 reg;
87
88 reg = __b15_rac_disable();
89 __b15_rac_flush();
90 return reg;
91}
92
93static inline void __b15_rac_enable(u32 val)
94{
95 __raw_writel(val, b15_rac_base + RAC_CONFIG0_REG);
96
97 dsb();
98}
99
100#define BUILD_RAC_CACHE_OP(name, bar) \
101void b15_flush_##name(void) \
102{ \
103 unsigned int do_flush; \
104 u32 val = 0; \
105 \
106 if (test_bit(RAC_SUSPENDED, &b15_rac_flags)) { \
107 v7_flush_##name(); \
108 bar; \
109 return; \
110 } \
111 \
112 spin_lock(&rac_lock); \
113 do_flush = test_bit(RAC_ENABLED, &b15_rac_flags); \
114 if (do_flush) \
115 val = b15_rac_disable_and_flush(); \
116 v7_flush_##name(); \
117 if (!do_flush) \
118 bar; \
119 else \
120 __b15_rac_enable(val); \
121 spin_unlock(&rac_lock); \
122}
123
124#define nobarrier
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142BUILD_RAC_CACHE_OP(kern_cache_all, nobarrier);
143
144static void b15_rac_enable(void)
145{
146 unsigned int cpu;
147 u32 enable = 0;
148
149 for_each_possible_cpu(cpu)
150 enable |= (RAC_DATA_INST_EN_MASK << (cpu * RAC_CPU_SHIFT));
151
152 b15_rac_disable_and_flush();
153 __b15_rac_enable(enable);
154}
155
156static int b15_rac_reboot_notifier(struct notifier_block *nb,
157 unsigned long action,
158 void *data)
159{
160
161
162
163
164 if (action == SYS_RESTART) {
165 spin_lock(&rac_lock);
166 b15_rac_disable_and_flush();
167 clear_bit(RAC_ENABLED, &b15_rac_flags);
168 set_bit(RAC_SUSPENDED, &b15_rac_flags);
169 spin_unlock(&rac_lock);
170 }
171
172 return NOTIFY_DONE;
173}
174
175static struct notifier_block b15_rac_reboot_nb = {
176 .notifier_call = b15_rac_reboot_notifier,
177};
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216static int b15_rac_dying_cpu(unsigned int cpu)
217{
218
219
220
221 if (test_bit(RAC_SUSPENDED, &b15_rac_flags))
222 return 0;
223
224 spin_lock(&rac_lock);
225
226
227 __clear_bit(RAC_ENABLED, &b15_rac_flags);
228
229
230 rac_config0_reg = b15_rac_disable_and_flush();
231
232 spin_unlock(&rac_lock);
233
234 return 0;
235}
236
237
238static int b15_rac_dead_cpu(unsigned int cpu)
239{
240
241
242
243 if (test_bit(RAC_SUSPENDED, &b15_rac_flags))
244 return 0;
245
246 spin_lock(&rac_lock);
247
248
249 __b15_rac_enable(rac_config0_reg);
250 __set_bit(RAC_ENABLED, &b15_rac_flags);
251
252 spin_unlock(&rac_lock);
253
254 return 0;
255}
256
257static int b15_rac_suspend(void)
258{
259
260
261
262
263
264
265
266 rac_config0_reg = b15_rac_disable_and_flush();
267 set_bit(RAC_SUSPENDED, &b15_rac_flags);
268
269 return 0;
270}
271
272static void b15_rac_resume(void)
273{
274
275
276
277
278
279 __b15_rac_enable(rac_config0_reg);
280 clear_bit(RAC_SUSPENDED, &b15_rac_flags);
281}
282
283static struct syscore_ops b15_rac_syscore_ops = {
284 .suspend = b15_rac_suspend,
285 .resume = b15_rac_resume,
286};
287
288static int __init b15_rac_init(void)
289{
290 struct device_node *dn;
291 int ret = 0, cpu;
292 u32 reg, en_mask = 0;
293
294 dn = of_find_compatible_node(NULL, NULL, "brcm,brcmstb-cpu-biu-ctrl");
295 if (!dn)
296 return -ENODEV;
297
298 if (WARN(num_possible_cpus() > 4, "RAC only supports 4 CPUs\n"))
299 goto out;
300
301 b15_rac_base = of_iomap(dn, 0);
302 if (!b15_rac_base) {
303 pr_err("failed to remap BIU control base\n");
304 ret = -ENOMEM;
305 goto out;
306 }
307
308 ret = register_reboot_notifier(&b15_rac_reboot_nb);
309 if (ret) {
310 pr_err("failed to register reboot notifier\n");
311 iounmap(b15_rac_base);
312 goto out;
313 }
314
315 if (IS_ENABLED(CONFIG_HOTPLUG_CPU)) {
316 ret = cpuhp_setup_state_nocalls(CPUHP_AP_ARM_CACHE_B15_RAC_DEAD,
317 "arm/cache-b15-rac:dead",
318 NULL, b15_rac_dead_cpu);
319 if (ret)
320 goto out_unmap;
321
322 ret = cpuhp_setup_state_nocalls(CPUHP_AP_ARM_CACHE_B15_RAC_DYING,
323 "arm/cache-b15-rac:dying",
324 NULL, b15_rac_dying_cpu);
325 if (ret)
326 goto out_cpu_dead;
327 }
328
329 if (IS_ENABLED(CONFIG_PM_SLEEP))
330 register_syscore_ops(&b15_rac_syscore_ops);
331
332 spin_lock(&rac_lock);
333 reg = __raw_readl(b15_rac_base + RAC_CONFIG0_REG);
334 for_each_possible_cpu(cpu)
335 en_mask |= ((1 << RACPREFDATA_SHIFT) << (cpu * RAC_CPU_SHIFT));
336 WARN(reg & en_mask, "Read-ahead cache not previously disabled\n");
337
338 b15_rac_enable();
339 set_bit(RAC_ENABLED, &b15_rac_flags);
340 spin_unlock(&rac_lock);
341
342 pr_info("Broadcom Brahma-B15 readahead cache at: 0x%p\n",
343 b15_rac_base + RAC_CONFIG0_REG);
344
345 goto out;
346
347out_cpu_dead:
348 cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CACHE_B15_RAC_DYING);
349out_unmap:
350 unregister_reboot_notifier(&b15_rac_reboot_nb);
351 iounmap(b15_rac_base);
352out:
353 of_node_put(dn);
354 return ret;
355}
356arch_initcall(b15_rac_init);
357