Changeset 47687
- Timestamp:
- 2015-12-02T16:23:08+01:00 (2 years ago)
- Location:
- trunk/target/linux/bcm53xx
- Files:
-
- 4 added
- 4 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/target/linux/bcm53xx/patches-4.1/133-ARM-BCM-Add-SMP-support-for-Broadcom-NSP.patch
r47686 r47687 1 From a0ad1511d5805b95ac4c454d7904c670a1696055Mon Sep 17 00:00:00 20011 From e99fb6d01cddf38cffc11655aba4a96a981d604e Mon Sep 17 00:00:00 2001 2 2 From: Kapil Hali <kapilh@broadcom.com> 3 Date: Wed, 14 Oct 2015 13:47:00 -04004 Subject: [PATCH ] ARM: BCM: Add SMP support for Broadcom NSP3 Date: Wed, 25 Nov 2015 13:25:55 -0500 4 Subject: [PATCH 133/134] ARM: BCM: Add SMP support for Broadcom NSP 5 5 6 Add SMP support for Broadcom's Northstar Plus SoC ,7 cpu enable method and pen_release procedures. This8 changes also consolidates iProc family's - BCM NSP 9 and BCM Kona,SMP handling in a common file.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 10 11 11 Northstar Plus SoC is based on ARM Cortex-A9 … … 16 16 Signed-off-by: Kapil Hali <kapilh@broadcom.com> 17 17 --- 18 arch/arm/mach-bcm/Makefile | 2 +- 19 arch/arm/mach-bcm/bcm_nsp.h | 19 +++ 20 arch/arm/mach-bcm/headsmp.S | 37 +++++ 21 arch/arm/mach-bcm/kona_smp.c | 202 --------------------------- 22 arch/arm/mach-bcm/platsmp.c | 326 +++++++++++++++++++++++++++++++++++++++++++ 23 5 files changed, 383 insertions(+), 203 deletions(-) 24 create mode 100644 arch/arm/mach-bcm/bcm_nsp.h 25 create mode 100644 arch/arm/mach-bcm/headsmp.S 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(-) 26 23 delete mode 100644 arch/arm/mach-bcm/kona_smp.c 27 24 create mode 100644 arch/arm/mach-bcm/platsmp.c … … 38 35 # BCM281XX and BCM21664 L2 cache control 39 36 obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona_l2_cache.o 40 --- /dev/null41 +++ b/arch/arm/mach-bcm/bcm_nsp.h42 @@ -0,0 +1,19 @@43 +/*44 + * Copyright (C) 2015 Broadcom Corporation45 + *46 + * This program is free software; you can redistribute it and/or47 + * modify it under the terms of the GNU General Public License as48 + * published by the Free Software Foundation version 2.49 + *50 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any51 + * kind, whether express or implied; without even the implied warranty52 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the53 + * GNU General Public License for more details.54 + */55 +56 +#ifndef __BCM_NSP_H57 +#define __BCM_NSP_H58 +59 +extern void nsp_secondary_startup(void);60 +61 +#endif /* __BCM_NSP_H */62 --- /dev/null63 +++ b/arch/arm/mach-bcm/headsmp.S64 @@ -0,0 +1,37 @@65 +/*66 + * Copyright (C) 2015 Broadcom Corporation67 + *68 + * This program is free software; you can redistribute it and/or69 + * modify it under the terms of the GNU General Public License as70 + * published by the Free Software Foundation version 2.71 + *72 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any73 + * kind, whether express or implied; without even the implied warranty74 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the75 + * GNU General Public License for more details.76 + */77 +78 +#include <linux/linkage.h>79 +80 +/*81 + * iProc specific entry point for secondary CPUs. This provides82 + * a "holding pen" into which all secondary cores are held until83 + * we are ready for them to initialise.84 + */85 +ENTRY(nsp_secondary_startup)86 + mrc p15, 0, r0, c0, c0, 587 + and r0, r0, #1588 + adr r4, 1f89 + ldmia r4, {r5, r6}90 + sub r4, r4, r591 + add r6, r6, r492 +pen: ldr r7, [r6]93 + cmp r7, r094 + bne pen95 +96 + b secondary_startup97 +98 +1: .long .99 + .long pen_release100 +101 +ENDPROC(nsp_secondary_startup)102 37 --- a/arch/arm/mach-bcm/kona_smp.c 103 38 +++ /dev/null 104 @@ -1,2 02+0,0 @@39 @@ -1,228 +0,0 @@ 105 40 -/* 106 - * Copyright (C) 2014 Broadcom Corporation41 - * Copyright (C) 2014-2015 Broadcom Corporation 107 42 - * Copyright 2014 Linaro Limited 108 43 - * … … 135 70 -/* Name of device node property defining secondary boot register location */ 136 71 -#define OF_SECONDARY_BOOT "secondary-boot-reg" 72 -#define MPIDR_CPUID_BITMASK 0x3 137 73 - 138 74 -/* I/O address of register used to coordinate secondary core startup */ 139 -static u32 secondary_boot ;75 -static u32 secondary_boot_addr; 140 76 - 141 77 -/* … … 183 119 -{ 184 120 - static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 }; 185 - struct device_node *node; 121 - struct device_node *cpus_node = NULL; 122 - struct device_node *cpu_node = NULL; 186 123 - int ret; 187 -188 - BUG_ON(secondary_boot); /* We're called only once */189 124 - 190 125 - /* … … 194 129 - * operations defined herein. 195 130 - */ 196 - node = of_find_node_by_path("/cpus"); 197 - BUG_ON(!node); 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 - } 198 170 - 199 171 - /* 200 - * Our secondary enable method requires a "secondary-boot-reg" 201 - * property to specify a register address used to request the 202 - * ROM code boot a secondary code. If we have any trouble 203 - * getting this we fall back to uniprocessor mode. 204 - */ 205 - if (of_property_read_u32(node, OF_SECONDARY_BOOT, &secondary_boot)) { 206 - pr_err("%s: missing/invalid " OF_SECONDARY_BOOT " property\n", 207 - node->name); 208 - ret = -ENOENT; /* Arrange to disable SMP */ 209 - goto out; 210 - } 211 - 212 - /* 213 - * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is 172 - * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is 214 173 - * returned, the SoC reported a uniprocessor configuration. 215 174 - * We bail on any other error. … … 217 176 - ret = scu_a9_enable(); 218 177 -out: 219 - of_node_put(node); 178 - of_node_put(cpu_node); 179 - of_node_put(cpus_node); 180 - 220 181 - if (ret) { 221 182 - /* Update the CPU present map to reflect uniprocessor mode */ 222 - BUG_ON(ret != -ENOENT);223 183 - pr_warn("disabling SMP\n"); 224 184 - init_cpu_present(&only_cpu_0); … … 244 204 - * indicates the secondary core has started. 245 205 - */ 246 -static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle)206 -static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle) 247 207 -{ 248 208 - void __iomem *boot_reg; … … 259 219 - } 260 220 - 261 - if (!secondary_boot ) {221 - if (!secondary_boot_addr) { 262 222 - pr_err("required secondary boot register not specified\n"); 263 223 - return -EINVAL; 264 224 - } 265 225 - 266 - boot_reg = ioremap_nocache((phys_addr_t)secondary_boot, sizeof(u32)); 226 - boot_reg = ioremap_nocache( 227 - (phys_addr_t)secondary_boot_addr, sizeof(u32)); 267 228 - if (!boot_reg) { 268 229 - pr_err("unable to map boot register for cpu %u\n", cpu_id); 269 - return -ENO SYS;230 - return -ENOMEM; 270 231 - } 271 232 - … … 296 257 - pr_err("timeout waiting for cpu %u to start\n", cpu_id); 297 258 - 298 - return -EN OSYS;259 - return -ENXIO; 299 260 -} 300 261 - 301 262 -static struct smp_operations bcm_smp_ops __initdata = { 302 263 - .smp_prepare_cpus = bcm_smp_prepare_cpus, 303 - .smp_boot_secondary = bcm_boot_secondary,264 - .smp_boot_secondary = kona_boot_secondary, 304 265 -}; 305 266 -CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method", … … 307 268 --- /dev/null 308 269 +++ b/arch/arm/mach-bcm/platsmp.c 309 @@ -0,0 +1, 326@@270 @@ -0,0 +1,290 @@ 310 271 +/* 311 272 + * Copyright (C) 2014-2015 Broadcom Corporation … … 337 298 +#include <asm/smp_scu.h> 338 299 + 339 +#include "bcm_nsp.h"340 +341 300 +/* Size of mapped Cortex A9 SCU address space */ 342 301 +#define CORTEX_A9_SCU_SIZE 0x58 … … 347 306 +/* Name of device node property defining secondary boot register location */ 348 307 +#define OF_SECONDARY_BOOT "secondary-boot-reg" 308 +#define MPIDR_CPUID_BITMASK 0x3 349 309 + 350 310 +/* I/O address of register used to coordinate secondary core startup */ 351 +static u32 secondary_boot; 352 + 353 +static DEFINE_SPINLOCK(boot_lock); 354 + 355 +/* 356 + * Write pen_release in a way that is guaranteed to be visible to all 357 + * observers, irrespective of whether they're taking part in coherency 358 + * or not. This is necessary for the hotplug code to work reliably. 359 + */ 360 +static void write_pen_release(int val) 361 +{ 362 + pen_release = val; 363 + /* 364 + * Ensure write to pen_release is visible to the other cores, 365 + * here - primary core 366 + */ 367 + smp_wmb(); 368 + sync_cache_w(&pen_release); 369 +} 311 +static u32 secondary_boot_addr; 370 312 + 371 313 +/* … … 410 352 +} 411 353 + 412 +static int nsp_write_lut(void (*secondary_startup) (void))354 +static int nsp_write_lut(void) 413 355 +{ 414 356 + void __iomem *sku_rom_lut; 415 357 + phys_addr_t secondary_startup_phy; 416 358 + 417 + if (!secondary_boot ) {359 + if (!secondary_boot_addr) { 418 360 + pr_warn("required secondary boot register not specified\n"); 419 361 + return -EINVAL; 420 362 + } 421 363 + 422 + sku_rom_lut = ioremap_nocache((phys_addr_t)secondary_boot ,423 + sizeof(secondary_boot ));364 + sku_rom_lut = ioremap_nocache((phys_addr_t)secondary_boot_addr, 365 + sizeof(secondary_boot_addr)); 424 366 + if (!sku_rom_lut) { 425 367 + pr_warn("unable to ioremap SKU-ROM LUT register\n"); … … 431 373 + 432 374 + writel_relaxed(secondary_startup_phy, sku_rom_lut); 433 + /* 434 + * Ensure the write is visible to the secondary core. 435 + */ 375 + 376 + /* Ensure the write is visible to the secondary core */ 436 377 + smp_wmb(); 437 378 + … … 439 380 + 440 381 + return 0; 441 +}442 +443 +static void nsp_secondary_init(unsigned int cpu)444 +{445 + /*446 + * Let the primary cpu know we are out of holding pen.447 + */448 + write_pen_release(-1);449 +450 + /*451 + * Synchronise with the boot thread.452 + */453 + spin_lock(&boot_lock);454 + spin_unlock(&boot_lock);455 382 +} 456 383 + … … 458 385 +{ 459 386 + static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 }; 460 + struct device_node *node; 387 + struct device_node *cpus_node = NULL; 388 + struct device_node *cpu_node = NULL; 461 389 + int ret; 462 +463 + BUG_ON(secondary_boot); /* We're called only once */464 390 + 465 391 + /* … … 469 395 + * operations defined herein. 470 396 + */ 471 + node = of_find_node_by_path("/cpus"); 472 + BUG_ON(!node); 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 + } 473 436 + 474 437 + /* 475 + * Our secondary enable method requires a "secondary-boot-reg" 476 + * property to specify a register address used to request the 477 + * ROM code boot a secondary core. If we have any trouble 478 + * getting this we fall back to uniprocessor mode. 479 + */ 480 + if (of_property_read_u32(node, OF_SECONDARY_BOOT, &secondary_boot)) { 481 + pr_warn("%s: missing/invalid " OF_SECONDARY_BOOT " property\n", 482 + node->name); 483 + ret = -ENOENT; /* Arrange to disable SMP */ 484 + goto out; 485 + } 486 + 487 + /* 488 + * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is 438 + * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is 489 439 + * returned, the SoC reported a uniprocessor configuration. 490 440 + * We bail on any other error. … … 492 442 + ret = scu_a9_enable(); 493 443 +out: 494 + of_node_put(node); 444 + of_node_put(cpu_node); 445 + of_node_put(cpus_node); 446 + 495 447 + if (ret) { 496 448 + /* Update the CPU present map to reflect uniprocessor mode */ … … 533 485 + } 534 486 + 535 + if (!secondary_boot ) {487 + if (!secondary_boot_addr) { 536 488 + pr_err("required secondary boot register not specified\n"); 537 489 + return -EINVAL; 538 490 + } 539 491 + 540 + boot_reg = ioremap_nocache((phys_addr_t)secondary_boot, sizeof(u32)); 492 + boot_reg = ioremap_nocache( 493 + (phys_addr_t)secondary_boot_addr, sizeof(u32)); 541 494 + if (!boot_reg) { 542 495 + pr_err("unable to map boot register for cpu %u\n", cpu_id); … … 575 528 +static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle) 576 529 +{ 577 + unsigned long timeout;578 530 + int ret; 579 531 + … … 582 534 + * address programmed at SKU ROM LUT location. 583 535 + */ 584 + ret = nsp_write_lut( nsp_secondary_startup);536 + ret = nsp_write_lut(); 585 537 + if (ret) { 586 538 + pr_err("unable to write startup addr to SKU ROM LUT\n"); … … 588 540 + } 589 541 + 590 + /* 591 + * The secondary processor is waiting to be released from 592 + * the holding pen - release it, then wait for it to flag 593 + * that it has been released by resetting pen_release. 594 + */ 595 + spin_lock(&boot_lock); 596 + 597 + write_pen_release(cpu_logical_map(cpu)); 598 + /* 599 + * Send an Event to wake up the secondary core which is in 600 + * WFE state. Updated pen_release should also be visible to 601 + * the secondary core. 602 + */ 603 + dsb_sev(); 604 + 605 + timeout = jiffies + (1 * HZ); 606 + while (time_before(jiffies, timeout)) { 607 + /* Make sure loads on other CPU is visible */ 608 + smp_rmb(); 609 + if (pen_release == -1) 610 + break; 611 + 612 + udelay(10); 613 + } 614 + 615 + spin_unlock(&boot_lock); 616 + 617 + ret = pen_release != -1 ? -ENXIO : 0; 542 + /* Send a CPU wakeup interrupt to the secondary core */ 543 + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); 618 544 + 619 545 +out: … … 630 556 +struct smp_operations nsp_smp_ops __initdata = { 631 557 + .smp_prepare_cpus = bcm_smp_prepare_cpus, 632 + .smp_secondary_init = nsp_secondary_init,633 558 + .smp_boot_secondary = nsp_boot_secondary, 634 559 +}; -
trunk/target/linux/bcm53xx/patches-4.1/134-ARM-BCM-Add-SMP-support-for-Broadcom-4708.patch
r47686 r47687 1 From ddbf0ad85be06948dd214c7beb7b315ef2749e65Mon Sep 17 00:00:00 20011 From 16e1bf7dde22ee22a331aabf824cc31a6794a4cb Mon Sep 17 00:00:00 2001 2 2 From: Jon Mason <jonmason@broadcom.com> 3 Date: Thu, 15 Oct 2015 14:14:10 -0400 4 Subject: [PATCH] ARM: BCM: Add SMP support for Broadcom 4708 5 6 ARM: BCM: Add SMP support for Broadcom 4708 3 Date: Thu, 15 Oct 2015 14:09:10 -0400 4 Subject: [PATCH 134/134] ARM: BCM: Add SMP support for Broadcom 4708 7 5 8 6 Add SMP support for Broadcom's 4708 SoCs. 9 7 10 8 Signed-off-by: Jon Mason <jonmason@broadcom.com> 9 Acked-by: Hauke Mehrtens <hauke@hauke-m.de> 10 Tested-by: Hauke Mehrtens <hauke@hauke-m.de> 11 Signed-off-by: Kapil Hali <kapilh@broadcom.com> 11 12 --- 12 13 arch/arm/boot/dts/bcm4708.dtsi | 2 ++ 13 arch/arm/mach-bcm/Kconfig | 2 ++14 arch/arm/mach-bcm/Kconfig | 1 + 14 15 arch/arm/mach-bcm/Makefile | 3 +++ 15 3 files changed, 7insertions(+)16 3 files changed, 6 insertions(+) 16 17 17 18 --- a/arch/arm/boot/dts/bcm4708.dtsi 18 19 +++ b/arch/arm/boot/dts/bcm4708.dtsi 19 @@ -15,6 +15, 8@@20 @@ -15,6 +15,7 @@ 20 21 cpus { 21 22 #address-cells = <1>; 22 23 #size-cells = <0>; 23 24 + enable-method = "brcm,bcm-nsp-smp"; 24 + secondary-boot-reg = <0xffff0400>;25 25 26 26 cpu@0 { 27 27 device_type = "cpu"; 28 @@ -27,6 +28,7 @@ 29 device_type = "cpu"; 30 compatible = "arm,cortex-a9"; 31 next-level-cache = <&L2>; 32 + secondary-boot-reg = <0xffff0400>; 33 reg = <0x1>; 34 }; 35 }; 28 36 --- a/arch/arm/mach-bcm/Kconfig 29 37 +++ b/arch/arm/mach-bcm/Kconfig … … 43 51 obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o 44 52 +ifeq ($(CONFIG_ARCH_BCM_5301X),y) 45 +obj-$(CONFIG_SMP) += headsmp.oplatsmp.o53 +obj-$(CONFIG_SMP) += platsmp.o 46 54 +endif 47 55 -
trunk/target/linux/bcm53xx/patches-4.3/133-ARM-BCM-Add-SMP-support-for-Broadcom-NSP.patch
r47686 r47687 1 From a0ad1511d5805b95ac4c454d7904c670a1696055Mon Sep 17 00:00:00 20011 From e99fb6d01cddf38cffc11655aba4a96a981d604e Mon Sep 17 00:00:00 2001 2 2 From: Kapil Hali <kapilh@broadcom.com> 3 Date: Wed, 14 Oct 2015 13:47:00 -04004 Subject: [PATCH ] ARM: BCM: Add SMP support for Broadcom NSP3 Date: Wed, 25 Nov 2015 13:25:55 -0500 4 Subject: [PATCH 133/134] ARM: BCM: Add SMP support for Broadcom NSP 5 5 6 Add SMP support for Broadcom's Northstar Plus SoC ,7 cpu enable method and pen_release procedures. This8 changes also consolidates iProc family's - BCM NSP 9 and BCM Kona,SMP handling in a common file.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 10 11 11 Northstar Plus SoC is based on ARM Cortex-A9 … … 16 16 Signed-off-by: Kapil Hali <kapilh@broadcom.com> 17 17 --- 18 arch/arm/mach-bcm/Makefile | 2 +- 19 arch/arm/mach-bcm/bcm_nsp.h | 19 +++ 20 arch/arm/mach-bcm/headsmp.S | 37 +++++ 21 arch/arm/mach-bcm/kona_smp.c | 202 --------------------------- 22 arch/arm/mach-bcm/platsmp.c | 326 +++++++++++++++++++++++++++++++++++++++++++ 23 5 files changed, 383 insertions(+), 203 deletions(-) 24 create mode 100644 arch/arm/mach-bcm/bcm_nsp.h 25 create mode 100644 arch/arm/mach-bcm/headsmp.S 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(-) 26 23 delete mode 100644 arch/arm/mach-bcm/kona_smp.c 27 24 create mode 100644 arch/arm/mach-bcm/platsmp.c … … 38 35 # BCM281XX and BCM21664 L2 cache control 39 36 obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona_l2_cache.o 40 --- /dev/null41 +++ b/arch/arm/mach-bcm/bcm_nsp.h42 @@ -0,0 +1,19 @@43 +/*44 + * Copyright (C) 2015 Broadcom Corporation45 + *46 + * This program is free software; you can redistribute it and/or47 + * modify it under the terms of the GNU General Public License as48 + * published by the Free Software Foundation version 2.49 + *50 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any51 + * kind, whether express or implied; without even the implied warranty52 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the53 + * GNU General Public License for more details.54 + */55 +56 +#ifndef __BCM_NSP_H57 +#define __BCM_NSP_H58 +59 +extern void nsp_secondary_startup(void);60 +61 +#endif /* __BCM_NSP_H */62 --- /dev/null63 +++ b/arch/arm/mach-bcm/headsmp.S64 @@ -0,0 +1,37 @@65 +/*66 + * Copyright (C) 2015 Broadcom Corporation67 + *68 + * This program is free software; you can redistribute it and/or69 + * modify it under the terms of the GNU General Public License as70 + * published by the Free Software Foundation version 2.71 + *72 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any73 + * kind, whether express or implied; without even the implied warranty74 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the75 + * GNU General Public License for more details.76 + */77 +78 +#include <linux/linkage.h>79 +80 +/*81 + * iProc specific entry point for secondary CPUs. This provides82 + * a "holding pen" into which all secondary cores are held until83 + * we are ready for them to initialise.84 + */85 +ENTRY(nsp_secondary_startup)86 + mrc p15, 0, r0, c0, c0, 587 + and r0, r0, #1588 + adr r4, 1f89 + ldmia r4, {r5, r6}90 + sub r4, r4, r591 + add r6, r6, r492 +pen: ldr r7, [r6]93 + cmp r7, r094 + bne pen95 +96 + b secondary_startup97 +98 +1: .long .99 + .long pen_release100 +101 +ENDPROC(nsp_secondary_startup)102 37 --- a/arch/arm/mach-bcm/kona_smp.c 103 38 +++ /dev/null 104 @@ -1,2 02+0,0 @@39 @@ -1,228 +0,0 @@ 105 40 -/* 106 - * Copyright (C) 2014 Broadcom Corporation41 - * Copyright (C) 2014-2015 Broadcom Corporation 107 42 - * Copyright 2014 Linaro Limited 108 43 - * … … 135 70 -/* Name of device node property defining secondary boot register location */ 136 71 -#define OF_SECONDARY_BOOT "secondary-boot-reg" 72 -#define MPIDR_CPUID_BITMASK 0x3 137 73 - 138 74 -/* I/O address of register used to coordinate secondary core startup */ 139 -static u32 secondary_boot ;75 -static u32 secondary_boot_addr; 140 76 - 141 77 -/* … … 183 119 -{ 184 120 - static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 }; 185 - struct device_node *node; 121 - struct device_node *cpus_node = NULL; 122 - struct device_node *cpu_node = NULL; 186 123 - int ret; 187 -188 - BUG_ON(secondary_boot); /* We're called only once */189 124 - 190 125 - /* … … 194 129 - * operations defined herein. 195 130 - */ 196 - node = of_find_node_by_path("/cpus"); 197 - BUG_ON(!node); 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 - } 198 170 - 199 171 - /* 200 - * Our secondary enable method requires a "secondary-boot-reg" 201 - * property to specify a register address used to request the 202 - * ROM code boot a secondary code. If we have any trouble 203 - * getting this we fall back to uniprocessor mode. 204 - */ 205 - if (of_property_read_u32(node, OF_SECONDARY_BOOT, &secondary_boot)) { 206 - pr_err("%s: missing/invalid " OF_SECONDARY_BOOT " property\n", 207 - node->name); 208 - ret = -ENOENT; /* Arrange to disable SMP */ 209 - goto out; 210 - } 211 - 212 - /* 213 - * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is 172 - * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is 214 173 - * returned, the SoC reported a uniprocessor configuration. 215 174 - * We bail on any other error. … … 217 176 - ret = scu_a9_enable(); 218 177 -out: 219 - of_node_put(node); 178 - of_node_put(cpu_node); 179 - of_node_put(cpus_node); 180 - 220 181 - if (ret) { 221 182 - /* Update the CPU present map to reflect uniprocessor mode */ 222 - BUG_ON(ret != -ENOENT);223 183 - pr_warn("disabling SMP\n"); 224 184 - init_cpu_present(&only_cpu_0); … … 244 204 - * indicates the secondary core has started. 245 205 - */ 246 -static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle)206 -static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle) 247 207 -{ 248 208 - void __iomem *boot_reg; … … 259 219 - } 260 220 - 261 - if (!secondary_boot ) {221 - if (!secondary_boot_addr) { 262 222 - pr_err("required secondary boot register not specified\n"); 263 223 - return -EINVAL; 264 224 - } 265 225 - 266 - boot_reg = ioremap_nocache((phys_addr_t)secondary_boot, sizeof(u32)); 226 - boot_reg = ioremap_nocache( 227 - (phys_addr_t)secondary_boot_addr, sizeof(u32)); 267 228 - if (!boot_reg) { 268 229 - pr_err("unable to map boot register for cpu %u\n", cpu_id); 269 - return -ENO SYS;230 - return -ENOMEM; 270 231 - } 271 232 - … … 296 257 - pr_err("timeout waiting for cpu %u to start\n", cpu_id); 297 258 - 298 - return -EN OSYS;259 - return -ENXIO; 299 260 -} 300 261 - 301 262 -static struct smp_operations bcm_smp_ops __initdata = { 302 263 - .smp_prepare_cpus = bcm_smp_prepare_cpus, 303 - .smp_boot_secondary = bcm_boot_secondary,264 - .smp_boot_secondary = kona_boot_secondary, 304 265 -}; 305 266 -CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method", … … 307 268 --- /dev/null 308 269 +++ b/arch/arm/mach-bcm/platsmp.c 309 @@ -0,0 +1, 326@@270 @@ -0,0 +1,290 @@ 310 271 +/* 311 272 + * Copyright (C) 2014-2015 Broadcom Corporation … … 337 298 +#include <asm/smp_scu.h> 338 299 + 339 +#include "bcm_nsp.h"340 +341 300 +/* Size of mapped Cortex A9 SCU address space */ 342 301 +#define CORTEX_A9_SCU_SIZE 0x58 … … 347 306 +/* Name of device node property defining secondary boot register location */ 348 307 +#define OF_SECONDARY_BOOT "secondary-boot-reg" 308 +#define MPIDR_CPUID_BITMASK 0x3 349 309 + 350 310 +/* I/O address of register used to coordinate secondary core startup */ 351 +static u32 secondary_boot; 352 + 353 +static DEFINE_SPINLOCK(boot_lock); 354 + 355 +/* 356 + * Write pen_release in a way that is guaranteed to be visible to all 357 + * observers, irrespective of whether they're taking part in coherency 358 + * or not. This is necessary for the hotplug code to work reliably. 359 + */ 360 +static void write_pen_release(int val) 361 +{ 362 + pen_release = val; 363 + /* 364 + * Ensure write to pen_release is visible to the other cores, 365 + * here - primary core 366 + */ 367 + smp_wmb(); 368 + sync_cache_w(&pen_release); 369 +} 311 +static u32 secondary_boot_addr; 370 312 + 371 313 +/* … … 410 352 +} 411 353 + 412 +static int nsp_write_lut(void (*secondary_startup) (void))354 +static int nsp_write_lut(void) 413 355 +{ 414 356 + void __iomem *sku_rom_lut; 415 357 + phys_addr_t secondary_startup_phy; 416 358 + 417 + if (!secondary_boot ) {359 + if (!secondary_boot_addr) { 418 360 + pr_warn("required secondary boot register not specified\n"); 419 361 + return -EINVAL; 420 362 + } 421 363 + 422 + sku_rom_lut = ioremap_nocache((phys_addr_t)secondary_boot ,423 + sizeof(secondary_boot ));364 + sku_rom_lut = ioremap_nocache((phys_addr_t)secondary_boot_addr, 365 + sizeof(secondary_boot_addr)); 424 366 + if (!sku_rom_lut) { 425 367 + pr_warn("unable to ioremap SKU-ROM LUT register\n"); … … 431 373 + 432 374 + writel_relaxed(secondary_startup_phy, sku_rom_lut); 433 + /* 434 + * Ensure the write is visible to the secondary core. 435 + */ 375 + 376 + /* Ensure the write is visible to the secondary core */ 436 377 + smp_wmb(); 437 378 + … … 439 380 + 440 381 + return 0; 441 +}442 +443 +static void nsp_secondary_init(unsigned int cpu)444 +{445 + /*446 + * Let the primary cpu know we are out of holding pen.447 + */448 + write_pen_release(-1);449 +450 + /*451 + * Synchronise with the boot thread.452 + */453 + spin_lock(&boot_lock);454 + spin_unlock(&boot_lock);455 382 +} 456 383 + … … 458 385 +{ 459 386 + static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 }; 460 + struct device_node *node; 387 + struct device_node *cpus_node = NULL; 388 + struct device_node *cpu_node = NULL; 461 389 + int ret; 462 +463 + BUG_ON(secondary_boot); /* We're called only once */464 390 + 465 391 + /* … … 469 395 + * operations defined herein. 470 396 + */ 471 + node = of_find_node_by_path("/cpus"); 472 + BUG_ON(!node); 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 + } 473 436 + 474 437 + /* 475 + * Our secondary enable method requires a "secondary-boot-reg" 476 + * property to specify a register address used to request the 477 + * ROM code boot a secondary core. If we have any trouble 478 + * getting this we fall back to uniprocessor mode. 479 + */ 480 + if (of_property_read_u32(node, OF_SECONDARY_BOOT, &secondary_boot)) { 481 + pr_warn("%s: missing/invalid " OF_SECONDARY_BOOT " property\n", 482 + node->name); 483 + ret = -ENOENT; /* Arrange to disable SMP */ 484 + goto out; 485 + } 486 + 487 + /* 488 + * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is 438 + * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is 489 439 + * returned, the SoC reported a uniprocessor configuration. 490 440 + * We bail on any other error. … … 492 442 + ret = scu_a9_enable(); 493 443 +out: 494 + of_node_put(node); 444 + of_node_put(cpu_node); 445 + of_node_put(cpus_node); 446 + 495 447 + if (ret) { 496 448 + /* Update the CPU present map to reflect uniprocessor mode */ … … 533 485 + } 534 486 + 535 + if (!secondary_boot ) {487 + if (!secondary_boot_addr) { 536 488 + pr_err("required secondary boot register not specified\n"); 537 489 + return -EINVAL; 538 490 + } 539 491 + 540 + boot_reg = ioremap_nocache((phys_addr_t)secondary_boot, sizeof(u32)); 492 + boot_reg = ioremap_nocache( 493 + (phys_addr_t)secondary_boot_addr, sizeof(u32)); 541 494 + if (!boot_reg) { 542 495 + pr_err("unable to map boot register for cpu %u\n", cpu_id); … … 575 528 +static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle) 576 529 +{ 577 + unsigned long timeout;578 530 + int ret; 579 531 + … … 582 534 + * address programmed at SKU ROM LUT location. 583 535 + */ 584 + ret = nsp_write_lut( nsp_secondary_startup);536 + ret = nsp_write_lut(); 585 537 + if (ret) { 586 538 + pr_err("unable to write startup addr to SKU ROM LUT\n"); … … 588 540 + } 589 541 + 590 + /* 591 + * The secondary processor is waiting to be released from 592 + * the holding pen - release it, then wait for it to flag 593 + * that it has been released by resetting pen_release. 594 + */ 595 + spin_lock(&boot_lock); 596 + 597 + write_pen_release(cpu_logical_map(cpu)); 598 + /* 599 + * Send an Event to wake up the secondary core which is in 600 + * WFE state. Updated pen_release should also be visible to 601 + * the secondary core. 602 + */ 603 + dsb_sev(); 604 + 605 + timeout = jiffies + (1 * HZ); 606 + while (time_before(jiffies, timeout)) { 607 + /* Make sure loads on other CPU is visible */ 608 + smp_rmb(); 609 + if (pen_release == -1) 610 + break; 611 + 612 + udelay(10); 613 + } 614 + 615 + spin_unlock(&boot_lock); 616 + 617 + ret = pen_release != -1 ? -ENXIO : 0; 542 + /* Send a CPU wakeup interrupt to the secondary core */ 543 + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); 618 544 + 619 545 +out: … … 630 556 +struct smp_operations nsp_smp_ops __initdata = { 631 557 + .smp_prepare_cpus = bcm_smp_prepare_cpus, 632 + .smp_secondary_init = nsp_secondary_init,633 558 + .smp_boot_secondary = nsp_boot_secondary, 634 559 +}; -
trunk/target/linux/bcm53xx/patches-4.3/134-ARM-BCM-Add-SMP-support-for-Broadcom-4708.patch
r47686 r47687 1 From ddbf0ad85be06948dd214c7beb7b315ef2749e65Mon Sep 17 00:00:00 20011 From 16e1bf7dde22ee22a331aabf824cc31a6794a4cb Mon Sep 17 00:00:00 2001 2 2 From: Jon Mason <jonmason@broadcom.com> 3 Date: Thu, 15 Oct 2015 14:14:10 -0400 4 Subject: [PATCH] ARM: BCM: Add SMP support for Broadcom 4708 5 6 ARM: BCM: Add SMP support for Broadcom 4708 3 Date: Thu, 15 Oct 2015 14:09:10 -0400 4 Subject: [PATCH 134/134] ARM: BCM: Add SMP support for Broadcom 4708 7 5 8 6 Add SMP support for Broadcom's 4708 SoCs. 9 7 10 8 Signed-off-by: Jon Mason <jonmason@broadcom.com> 9 Acked-by: Hauke Mehrtens <hauke@hauke-m.de> 10 Tested-by: Hauke Mehrtens <hauke@hauke-m.de> 11 Signed-off-by: Kapil Hali <kapilh@broadcom.com> 11 12 --- 12 13 arch/arm/boot/dts/bcm4708.dtsi | 2 ++ 13 arch/arm/mach-bcm/Kconfig | 2 ++14 arch/arm/mach-bcm/Kconfig | 1 + 14 15 arch/arm/mach-bcm/Makefile | 3 +++ 15 3 files changed, 7insertions(+)16 3 files changed, 6 insertions(+) 16 17 17 18 --- a/arch/arm/boot/dts/bcm4708.dtsi 18 19 +++ b/arch/arm/boot/dts/bcm4708.dtsi 19 @@ -15,6 +15, 8@@20 @@ -15,6 +15,7 @@ 20 21 cpus { 21 22 #address-cells = <1>; 22 23 #size-cells = <0>; 23 24 + enable-method = "brcm,bcm-nsp-smp"; 24 + secondary-boot-reg = <0xffff0400>;25 25 26 26 cpu@0 { 27 27 device_type = "cpu"; 28 @@ -27,6 +28,7 @@ 29 device_type = "cpu"; 30 compatible = "arm,cortex-a9"; 31 next-level-cache = <&L2>; 32 + secondary-boot-reg = <0xffff0400>; 33 reg = <0x1>; 34 }; 35 }; 28 36 --- a/arch/arm/mach-bcm/Kconfig 29 37 +++ b/arch/arm/mach-bcm/Kconfig … … 43 51 obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o 44 52 +ifeq ($(CONFIG_ARCH_BCM_5301X),y) 45 +obj-$(CONFIG_SMP) += headsmp.oplatsmp.o53 +obj-$(CONFIG_SMP) += platsmp.o 46 54 +endif 47 55
Note: See TracChangeset
for help on using the changeset viewer.