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