brcm47xx: make bcm47xxpart patch apply after recent backports
[openwrt.git] / target / linux / bcm53xx / patches-4.4 / 133-ARM-BCM-Add-SMP-support-for-Broadcom-NSP.patch
1 From e99fb6d01cddf38cffc11655aba4a96a981d604e Mon Sep 17 00:00:00 2001
2 From: Kapil Hali <kapilh@broadcom.com>
3 Date: Wed, 25 Nov 2015 13:25:55 -0500
4 Subject: [PATCH 133/134] ARM: BCM: Add SMP support for Broadcom NSP
5
6 Add SMP support for Broadcom's Northstar Plus SoC
7 cpu enable method. This changes also consolidates
8 iProc family's - BCM NSP and BCM Kona, platform
9 SMP handling in a common file.
10
11 Northstar Plus SoC is based on ARM Cortex-A9
12 revision r3p0 which requires configuration for ARM
13 Errata 764369 for SMP. This change adds the needed
14 configuration option.
15
16 Signed-off-by: Kapil Hali <kapilh@broadcom.com>
17 ---
18  arch/arm/mach-bcm/Kconfig    |   2 +
19  arch/arm/mach-bcm/Makefile   |   8 +-
20  arch/arm/mach-bcm/kona_smp.c | 228 ----------------------------------
21  arch/arm/mach-bcm/platsmp.c  | 290 +++++++++++++++++++++++++++++++++++++++++++
22  4 files changed, 298 insertions(+), 230 deletions(-)
23  delete mode 100644 arch/arm/mach-bcm/kona_smp.c
24  create mode 100644 arch/arm/mach-bcm/platsmp.c
25
26 --- a/arch/arm/mach-bcm/Makefile
27 +++ b/arch/arm/mach-bcm/Makefile
28 @@ -23,7 +23,7 @@ obj-$(CONFIG_ARCH_BCM_281XX)  += board_bc
29  obj-$(CONFIG_ARCH_BCM_21664)   += board_bcm21664.o
30  
31  # BCM281XX and BCM21664 SMP support
32 -obj-$(CONFIG_ARCH_BCM_MOBILE_SMP) += kona_smp.o
33 +obj-$(CONFIG_ARCH_BCM_MOBILE_SMP) += platsmp.o
34  
35  # BCM281XX and BCM21664 L2 cache control
36  obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona_l2_cache.o
37 --- a/arch/arm/mach-bcm/kona_smp.c
38 +++ /dev/null
39 @@ -1,228 +0,0 @@
40 -/*
41 - * Copyright (C) 2014-2015 Broadcom Corporation
42 - * Copyright 2014 Linaro Limited
43 - *
44 - * This program is free software; you can redistribute it and/or
45 - * modify it under the terms of the GNU General Public License as
46 - * published by the Free Software Foundation version 2.
47 - *
48 - * This program is distributed "as is" WITHOUT ANY WARRANTY of any
49 - * kind, whether express or implied; without even the implied warranty
50 - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
51 - * GNU General Public License for more details.
52 - */
53 -
54 -#include <linux/init.h>
55 -#include <linux/errno.h>
56 -#include <linux/io.h>
57 -#include <linux/of.h>
58 -#include <linux/sched.h>
59 -
60 -#include <asm/smp.h>
61 -#include <asm/smp_plat.h>
62 -#include <asm/smp_scu.h>
63 -
64 -/* Size of mapped Cortex A9 SCU address space */
65 -#define CORTEX_A9_SCU_SIZE     0x58
66 -
67 -#define SECONDARY_TIMEOUT_NS   NSEC_PER_MSEC   /* 1 msec (in nanoseconds) */
68 -#define BOOT_ADDR_CPUID_MASK   0x3
69 -
70 -/* Name of device node property defining secondary boot register location */
71 -#define OF_SECONDARY_BOOT      "secondary-boot-reg"
72 -#define MPIDR_CPUID_BITMASK    0x3
73 -
74 -/* I/O address of register used to coordinate secondary core startup */
75 -static u32     secondary_boot_addr;
76 -
77 -/*
78 - * Enable the Cortex A9 Snoop Control Unit
79 - *
80 - * By the time this is called we already know there are multiple
81 - * cores present.  We assume we're running on a Cortex A9 processor,
82 - * so any trouble getting the base address register or getting the
83 - * SCU base is a problem.
84 - *
85 - * Return 0 if successful or an error code otherwise.
86 - */
87 -static int __init scu_a9_enable(void)
88 -{
89 -       unsigned long config_base;
90 -       void __iomem *scu_base;
91 -
92 -       if (!scu_a9_has_base()) {
93 -               pr_err("no configuration base address register!\n");
94 -               return -ENXIO;
95 -       }
96 -
97 -       /* Config base address register value is zero for uniprocessor */
98 -       config_base = scu_a9_get_base();
99 -       if (!config_base) {
100 -               pr_err("hardware reports only one core\n");
101 -               return -ENOENT;
102 -       }
103 -
104 -       scu_base = ioremap((phys_addr_t)config_base, CORTEX_A9_SCU_SIZE);
105 -       if (!scu_base) {
106 -               pr_err("failed to remap config base (%lu/%u) for SCU\n",
107 -                       config_base, CORTEX_A9_SCU_SIZE);
108 -               return -ENOMEM;
109 -       }
110 -
111 -       scu_enable(scu_base);
112 -
113 -       iounmap(scu_base);      /* That's the last we'll need of this */
114 -
115 -       return 0;
116 -}
117 -
118 -static void __init bcm_smp_prepare_cpus(unsigned int max_cpus)
119 -{
120 -       static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
121 -       struct device_node *cpus_node = NULL;
122 -       struct device_node *cpu_node = NULL;
123 -       int ret;
124 -
125 -       /*
126 -        * This function is only called via smp_ops->smp_prepare_cpu().
127 -        * That only happens if a "/cpus" device tree node exists
128 -        * and has an "enable-method" property that selects the SMP
129 -        * operations defined herein.
130 -        */
131 -       cpus_node = of_find_node_by_path("/cpus");
132 -       if (!cpus_node)
133 -               return;
134 -
135 -       for_each_child_of_node(cpus_node, cpu_node) {
136 -               u32 cpuid;
137 -
138 -               if (of_node_cmp(cpu_node->type, "cpu"))
139 -                       continue;
140 -
141 -               if (of_property_read_u32(cpu_node, "reg", &cpuid)) {
142 -                       pr_debug("%s: missing reg property\n",
143 -                                    cpu_node->full_name);
144 -                       ret = -ENOENT;
145 -                       goto out;
146 -               }
147 -
148 -               /*
149 -                * "secondary-boot-reg" property should be defined only
150 -                * for secondary cpu
151 -                */
152 -               if ((cpuid & MPIDR_CPUID_BITMASK) == 1) {
153 -                       /*
154 -                        * Our secondary enable method requires a
155 -                        * "secondary-boot-reg" property to specify a register
156 -                        * address used to request the ROM code boot a secondary
157 -                        * core. If we have any trouble getting this we fall
158 -                        * back to uniprocessor mode.
159 -                        */
160 -                       if (of_property_read_u32(cpu_node,
161 -                                               OF_SECONDARY_BOOT,
162 -                                               &secondary_boot_addr)) {
163 -                               pr_warn("%s: no" OF_SECONDARY_BOOT "property\n",
164 -                                       cpu_node->name);
165 -                               ret = -ENOENT;
166 -                               goto out;
167 -                       }
168 -               }
169 -       }
170 -
171 -       /*
172 -        * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is
173 -        * returned, the SoC reported a uniprocessor configuration.
174 -        * We bail on any other error.
175 -        */
176 -       ret = scu_a9_enable();
177 -out:
178 -       of_node_put(cpu_node);
179 -       of_node_put(cpus_node);
180 -
181 -       if (ret) {
182 -               /* Update the CPU present map to reflect uniprocessor mode */
183 -               pr_warn("disabling SMP\n");
184 -               init_cpu_present(&only_cpu_0);
185 -       }
186 -}
187 -
188 -/*
189 - * The ROM code has the secondary cores looping, waiting for an event.
190 - * When an event occurs each core examines the bottom two bits of the
191 - * secondary boot register.  When a core finds those bits contain its
192 - * own core id, it performs initialization, including computing its boot
193 - * address by clearing the boot register value's bottom two bits.  The
194 - * core signals that it is beginning its execution by writing its boot
195 - * address back to the secondary boot register, and finally jumps to
196 - * that address.
197 - *
198 - * So to start a core executing we need to:
199 - * - Encode the (hardware) CPU id with the bottom bits of the secondary
200 - *   start address.
201 - * - Write that value into the secondary boot register.
202 - * - Generate an event to wake up the secondary CPU(s).
203 - * - Wait for the secondary boot register to be re-written, which
204 - *   indicates the secondary core has started.
205 - */
206 -static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle)
207 -{
208 -       void __iomem *boot_reg;
209 -       phys_addr_t boot_func;
210 -       u64 start_clock;
211 -       u32 cpu_id;
212 -       u32 boot_val;
213 -       bool timeout = false;
214 -
215 -       cpu_id = cpu_logical_map(cpu);
216 -       if (cpu_id & ~BOOT_ADDR_CPUID_MASK) {
217 -               pr_err("bad cpu id (%u > %u)\n", cpu_id, BOOT_ADDR_CPUID_MASK);
218 -               return -EINVAL;
219 -       }
220 -
221 -       if (!secondary_boot_addr) {
222 -               pr_err("required secondary boot register not specified\n");
223 -               return -EINVAL;
224 -       }
225 -
226 -       boot_reg = ioremap_nocache(
227 -                       (phys_addr_t)secondary_boot_addr, sizeof(u32));
228 -       if (!boot_reg) {
229 -               pr_err("unable to map boot register for cpu %u\n", cpu_id);
230 -               return -ENOMEM;
231 -       }
232 -
233 -       /*
234 -        * Secondary cores will start in secondary_startup(),
235 -        * defined in "arch/arm/kernel/head.S"
236 -        */
237 -       boot_func = virt_to_phys(secondary_startup);
238 -       BUG_ON(boot_func & BOOT_ADDR_CPUID_MASK);
239 -       BUG_ON(boot_func > (phys_addr_t)U32_MAX);
240 -
241 -       /* The core to start is encoded in the low bits */
242 -       boot_val = (u32)boot_func | cpu_id;
243 -       writel_relaxed(boot_val, boot_reg);
244 -
245 -       sev();
246 -
247 -       /* The low bits will be cleared once the core has started */
248 -       start_clock = local_clock();
249 -       while (!timeout && readl_relaxed(boot_reg) == boot_val)
250 -               timeout = local_clock() - start_clock > SECONDARY_TIMEOUT_NS;
251 -
252 -       iounmap(boot_reg);
253 -
254 -       if (!timeout)
255 -               return 0;
256 -
257 -       pr_err("timeout waiting for cpu %u to start\n", cpu_id);
258 -
259 -       return -ENXIO;
260 -}
261 -
262 -static struct smp_operations bcm_smp_ops __initdata = {
263 -       .smp_prepare_cpus       = bcm_smp_prepare_cpus,
264 -       .smp_boot_secondary     = kona_boot_secondary,
265 -};
266 -CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method",
267 -                       &bcm_smp_ops);
268 --- /dev/null
269 +++ b/arch/arm/mach-bcm/platsmp.c
270 @@ -0,0 +1,290 @@
271 +/*
272 + * Copyright (C) 2014-2015 Broadcom Corporation
273 + * Copyright 2014 Linaro Limited
274 + *
275 + * This program is free software; you can redistribute it and/or
276 + * modify it under the terms of the GNU General Public License as
277 + * published by the Free Software Foundation version 2.
278 + *
279 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
280 + * kind, whether express or implied; without even the implied warranty
281 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
282 + * GNU General Public License for more details.
283 + */
284 +
285 +#include <linux/cpumask.h>
286 +#include <linux/delay.h>
287 +#include <linux/errno.h>
288 +#include <linux/init.h>
289 +#include <linux/io.h>
290 +#include <linux/jiffies.h>
291 +#include <linux/of.h>
292 +#include <linux/sched.h>
293 +#include <linux/smp.h>
294 +
295 +#include <asm/cacheflush.h>
296 +#include <asm/smp.h>
297 +#include <asm/smp_plat.h>
298 +#include <asm/smp_scu.h>
299 +
300 +/* Size of mapped Cortex A9 SCU address space */
301 +#define CORTEX_A9_SCU_SIZE     0x58
302 +
303 +#define SECONDARY_TIMEOUT_NS   NSEC_PER_MSEC   /* 1 msec (in nanoseconds) */
304 +#define BOOT_ADDR_CPUID_MASK   0x3
305 +
306 +/* Name of device node property defining secondary boot register location */
307 +#define OF_SECONDARY_BOOT      "secondary-boot-reg"
308 +#define MPIDR_CPUID_BITMASK    0x3
309 +
310 +/* I/O address of register used to coordinate secondary core startup */
311 +static u32     secondary_boot_addr;
312 +
313 +/*
314 + * Enable the Cortex A9 Snoop Control Unit
315 + *
316 + * By the time this is called we already know there are multiple
317 + * cores present.  We assume we're running on a Cortex A9 processor,
318 + * so any trouble getting the base address register or getting the
319 + * SCU base is a problem.
320 + *
321 + * Return 0 if successful or an error code otherwise.
322 + */
323 +static int __init scu_a9_enable(void)
324 +{
325 +       unsigned long config_base;
326 +       void __iomem *scu_base;
327 +
328 +       if (!scu_a9_has_base()) {
329 +               pr_err("no configuration base address register!\n");
330 +               return -ENXIO;
331 +       }
332 +
333 +       /* Config base address register value is zero for uniprocessor */
334 +       config_base = scu_a9_get_base();
335 +       if (!config_base) {
336 +               pr_err("hardware reports only one core\n");
337 +               return -ENOENT;
338 +       }
339 +
340 +       scu_base = ioremap((phys_addr_t)config_base, CORTEX_A9_SCU_SIZE);
341 +       if (!scu_base) {
342 +               pr_err("failed to remap config base (%lu/%u) for SCU\n",
343 +                       config_base, CORTEX_A9_SCU_SIZE);
344 +               return -ENOMEM;
345 +       }
346 +
347 +       scu_enable(scu_base);
348 +
349 +       iounmap(scu_base);      /* That's the last we'll need of this */
350 +
351 +       return 0;
352 +}
353 +
354 +static int nsp_write_lut(void)
355 +{
356 +       void __iomem *sku_rom_lut;
357 +       phys_addr_t secondary_startup_phy;
358 +
359 +       if (!secondary_boot_addr) {
360 +               pr_warn("required secondary boot register not specified\n");
361 +               return -EINVAL;
362 +       }
363 +
364 +       sku_rom_lut = ioremap_nocache((phys_addr_t)secondary_boot_addr,
365 +                                               sizeof(secondary_boot_addr));
366 +       if (!sku_rom_lut) {
367 +               pr_warn("unable to ioremap SKU-ROM LUT register\n");
368 +               return -ENOMEM;
369 +       }
370 +
371 +       secondary_startup_phy = virt_to_phys(secondary_startup);
372 +       BUG_ON(secondary_startup_phy > (phys_addr_t)U32_MAX);
373 +
374 +       writel_relaxed(secondary_startup_phy, sku_rom_lut);
375 +
376 +       /* Ensure the write is visible to the secondary core */
377 +       smp_wmb();
378 +
379 +       iounmap(sku_rom_lut);
380 +
381 +       return 0;
382 +}
383 +
384 +static void __init bcm_smp_prepare_cpus(unsigned int max_cpus)
385 +{
386 +       static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
387 +       struct device_node *cpus_node = NULL;
388 +       struct device_node *cpu_node = NULL;
389 +       int ret;
390 +
391 +       /*
392 +        * This function is only called via smp_ops->smp_prepare_cpu().
393 +        * That only happens if a "/cpus" device tree node exists
394 +        * and has an "enable-method" property that selects the SMP
395 +        * operations defined herein.
396 +        */
397 +       cpus_node = of_find_node_by_path("/cpus");
398 +       if (!cpus_node)
399 +               return;
400 +
401 +       for_each_child_of_node(cpus_node, cpu_node) {
402 +               u32 cpuid;
403 +
404 +               if (of_node_cmp(cpu_node->type, "cpu"))
405 +                       continue;
406 +
407 +               if (of_property_read_u32(cpu_node, "reg", &cpuid)) {
408 +                       pr_debug("%s: missing reg property\n",
409 +                                    cpu_node->full_name);
410 +                       ret = -ENOENT;
411 +                       goto out;
412 +               }
413 +
414 +               /*
415 +                * "secondary-boot-reg" property should be defined only
416 +                * for secondary cpu
417 +                */
418 +               if ((cpuid & MPIDR_CPUID_BITMASK) == 1) {
419 +                       /*
420 +                        * Our secondary enable method requires a
421 +                        * "secondary-boot-reg" property to specify a register
422 +                        * address used to request the ROM code boot a secondary
423 +                        * core. If we have any trouble getting this we fall
424 +                        * back to uniprocessor mode.
425 +                        */
426 +                       if (of_property_read_u32(cpu_node,
427 +                                               OF_SECONDARY_BOOT,
428 +                                               &secondary_boot_addr)) {
429 +                               pr_warn("%s: no" OF_SECONDARY_BOOT "property\n",
430 +                                       cpu_node->name);
431 +                               ret = -ENOENT;
432 +                               goto out;
433 +                       }
434 +               }
435 +       }
436 +
437 +       /*
438 +        * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is
439 +        * returned, the SoC reported a uniprocessor configuration.
440 +        * We bail on any other error.
441 +        */
442 +       ret = scu_a9_enable();
443 +out:
444 +       of_node_put(cpu_node);
445 +       of_node_put(cpus_node);
446 +
447 +       if (ret) {
448 +               /* Update the CPU present map to reflect uniprocessor mode */
449 +               pr_warn("disabling SMP\n");
450 +               init_cpu_present(&only_cpu_0);
451 +       }
452 +}
453 +
454 +/*
455 + * The ROM code has the secondary cores looping, waiting for an event.
456 + * When an event occurs each core examines the bottom two bits of the
457 + * secondary boot register.  When a core finds those bits contain its
458 + * own core id, it performs initialization, including computing its boot
459 + * address by clearing the boot register value's bottom two bits.  The
460 + * core signals that it is beginning its execution by writing its boot
461 + * address back to the secondary boot register, and finally jumps to
462 + * that address.
463 + *
464 + * So to start a core executing we need to:
465 + * - Encode the (hardware) CPU id with the bottom bits of the secondary
466 + *   start address.
467 + * - Write that value into the secondary boot register.
468 + * - Generate an event to wake up the secondary CPU(s).
469 + * - Wait for the secondary boot register to be re-written, which
470 + *   indicates the secondary core has started.
471 + */
472 +static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle)
473 +{
474 +       void __iomem *boot_reg;
475 +       phys_addr_t boot_func;
476 +       u64 start_clock;
477 +       u32 cpu_id;
478 +       u32 boot_val;
479 +       bool timeout = false;
480 +
481 +       cpu_id = cpu_logical_map(cpu);
482 +       if (cpu_id & ~BOOT_ADDR_CPUID_MASK) {
483 +               pr_err("bad cpu id (%u > %u)\n", cpu_id, BOOT_ADDR_CPUID_MASK);
484 +               return -EINVAL;
485 +       }
486 +
487 +       if (!secondary_boot_addr) {
488 +               pr_err("required secondary boot register not specified\n");
489 +               return -EINVAL;
490 +       }
491 +
492 +       boot_reg = ioremap_nocache(
493 +                       (phys_addr_t)secondary_boot_addr, sizeof(u32));
494 +       if (!boot_reg) {
495 +               pr_err("unable to map boot register for cpu %u\n", cpu_id);
496 +               return -ENOMEM;
497 +       }
498 +
499 +       /*
500 +        * Secondary cores will start in secondary_startup(),
501 +        * defined in "arch/arm/kernel/head.S"
502 +        */
503 +       boot_func = virt_to_phys(secondary_startup);
504 +       BUG_ON(boot_func & BOOT_ADDR_CPUID_MASK);
505 +       BUG_ON(boot_func > (phys_addr_t)U32_MAX);
506 +
507 +       /* The core to start is encoded in the low bits */
508 +       boot_val = (u32)boot_func | cpu_id;
509 +       writel_relaxed(boot_val, boot_reg);
510 +
511 +       sev();
512 +
513 +       /* The low bits will be cleared once the core has started */
514 +       start_clock = local_clock();
515 +       while (!timeout && readl_relaxed(boot_reg) == boot_val)
516 +               timeout = local_clock() - start_clock > SECONDARY_TIMEOUT_NS;
517 +
518 +       iounmap(boot_reg);
519 +
520 +       if (!timeout)
521 +               return 0;
522 +
523 +       pr_err("timeout waiting for cpu %u to start\n", cpu_id);
524 +
525 +       return -ENXIO;
526 +}
527 +
528 +static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle)
529 +{
530 +       int ret;
531 +
532 +       /*
533 +        * After wake up, secondary core branches to the startup
534 +        * address programmed at SKU ROM LUT location.
535 +        */
536 +       ret = nsp_write_lut();
537 +       if (ret) {
538 +               pr_err("unable to write startup addr to SKU ROM LUT\n");
539 +               goto out;
540 +       }
541 +
542 +       /* Send a CPU wakeup interrupt to the secondary core */
543 +       arch_send_wakeup_ipi_mask(cpumask_of(cpu));
544 +
545 +out:
546 +       return ret;
547 +}
548 +
549 +static struct smp_operations bcm_smp_ops __initdata = {
550 +       .smp_prepare_cpus       = bcm_smp_prepare_cpus,
551 +       .smp_boot_secondary     = kona_boot_secondary,
552 +};
553 +CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method",
554 +                       &bcm_smp_ops);
555 +
556 +struct smp_operations nsp_smp_ops __initdata = {
557 +       .smp_prepare_cpus       = bcm_smp_prepare_cpus,
558 +       .smp_boot_secondary     = nsp_boot_secondary,
559 +};
560 +CPU_METHOD_OF_DECLARE(bcm_smp_nsp, "brcm,bcm-nsp-smp", &nsp_smp_ops);