Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: BCM: Add SMP support for Broadcom NSP

Add SMP support for Broadcom's Northstar Plus SoC
cpu enable method. This changes also consolidates
iProc family's - BCM NSP and BCM Kona, platform
SMP handling in a common file.

Northstar Plus SoC is based on ARM Cortex-A9
revision r3p0 which requires configuration for ARM
Errata 764369 for SMP. This change adds the needed
configuration option.

Signed-off-by: Kapil Hali <kapilh@broadcom.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>

authored by

Kapil Hali and committed by
Florian Fainelli
97890821 84320e1a

+71 -3
+2
arch/arm/mach-bcm/Kconfig
··· 40 40 select ARCH_BCM_IPROC 41 41 select ARM_ERRATA_754322 42 42 select ARM_ERRATA_775420 43 + select ARM_ERRATA_764369 if SMP 44 + select HAVE_SMP 43 45 help 44 46 Support for Broadcom Northstar Plus SoC. 45 47 Broadcom Northstar Plus family of SoCs are used for switching control
+6 -2
arch/arm/mach-bcm/Makefile
··· 14 14 obj-$(CONFIG_ARCH_BCM_CYGNUS) += bcm_cygnus.o 15 15 16 16 # Northstar Plus 17 - obj-$(CONFIG_ARCH_BCM_NSP) += bcm_nsp.o 17 + obj-$(CONFIG_ARCH_BCM_NSP) += bcm_nsp.o 18 + 19 + ifeq ($(CONFIG_ARCH_BCM_NSP),y) 20 + obj-$(CONFIG_SMP) += platsmp.o 21 + endif 18 22 19 23 # BCM281XX 20 24 obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o ··· 27 23 obj-$(CONFIG_ARCH_BCM_21664) += board_bcm21664.o 28 24 29 25 # BCM281XX and BCM21664 SMP support 30 - obj-$(CONFIG_ARCH_BCM_MOBILE_SMP) += kona_smp.o 26 + obj-$(CONFIG_ARCH_BCM_MOBILE_SMP) += platsmp.o 31 27 32 28 # BCM281XX and BCM21664 L2 cache control 33 29 obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona_l2_cache.o
+63 -1
arch/arm/mach-bcm/kona_smp.c arch/arm/mach-bcm/platsmp.c
··· 12 12 * GNU General Public License for more details. 13 13 */ 14 14 15 - #include <linux/init.h> 15 + #include <linux/cpumask.h> 16 + #include <linux/delay.h> 16 17 #include <linux/errno.h> 18 + #include <linux/init.h> 17 19 #include <linux/io.h> 20 + #include <linux/jiffies.h> 18 21 #include <linux/of.h> 19 22 #include <linux/sched.h> 23 + #include <linux/smp.h> 20 24 25 + #include <asm/cacheflush.h> 21 26 #include <asm/smp.h> 22 27 #include <asm/smp_plat.h> 23 28 #include <asm/smp_scu.h> ··· 77 72 scu_enable(scu_base); 78 73 79 74 iounmap(scu_base); /* That's the last we'll need of this */ 75 + 76 + return 0; 77 + } 78 + 79 + static int nsp_write_lut(void) 80 + { 81 + void __iomem *sku_rom_lut; 82 + phys_addr_t secondary_startup_phy; 83 + 84 + if (!secondary_boot_addr) { 85 + pr_warn("required secondary boot register not specified\n"); 86 + return -EINVAL; 87 + } 88 + 89 + sku_rom_lut = ioremap_nocache((phys_addr_t)secondary_boot_addr, 90 + sizeof(secondary_boot_addr)); 91 + if (!sku_rom_lut) { 92 + pr_warn("unable to ioremap SKU-ROM LUT register\n"); 93 + return -ENOMEM; 94 + } 95 + 96 + secondary_startup_phy = virt_to_phys(secondary_startup); 97 + BUG_ON(secondary_startup_phy > (phys_addr_t)U32_MAX); 98 + 99 + writel_relaxed(secondary_startup_phy, sku_rom_lut); 100 + 101 + /* Ensure the write is visible to the secondary core */ 102 + smp_wmb(); 103 + 104 + iounmap(sku_rom_lut); 80 105 81 106 return 0; 82 107 } ··· 255 220 return -ENXIO; 256 221 } 257 222 223 + static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle) 224 + { 225 + int ret; 226 + 227 + /* 228 + * After wake up, secondary core branches to the startup 229 + * address programmed at SKU ROM LUT location. 230 + */ 231 + ret = nsp_write_lut(); 232 + if (ret) { 233 + pr_err("unable to write startup addr to SKU ROM LUT\n"); 234 + goto out; 235 + } 236 + 237 + /* Send a CPU wakeup interrupt to the secondary core */ 238 + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); 239 + 240 + out: 241 + return ret; 242 + } 243 + 258 244 static struct smp_operations bcm_smp_ops __initdata = { 259 245 .smp_prepare_cpus = bcm_smp_prepare_cpus, 260 246 .smp_boot_secondary = kona_boot_secondary, 261 247 }; 262 248 CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method", 263 249 &bcm_smp_ops); 250 + 251 + struct smp_operations nsp_smp_ops __initdata = { 252 + .smp_prepare_cpus = bcm_smp_prepare_cpus, 253 + .smp_boot_secondary = nsp_boot_secondary, 254 + }; 255 + CPU_METHOD_OF_DECLARE(bcm_smp_nsp, "brcm,bcm-nsp-smp", &nsp_smp_ops);