From 937b12306ea79044c86f2e69b3061c7279245825 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 15 Oct 2015 12:32:22 +0200 Subject: [PATCH 1/5] ARM: BCM5301X: remove workaround imprecise abort fault handler This is not needed anymore. Handling a potentially pending imprecise external abort left behind by the bootloader is now done in a slightly safer way inside the common ARM startup code. Signed-off-by: Lucas Stach Acked-by: Hauke Mehrtens Tested-by: Tyler Baker Signed-off-by: Florian Fainelli --- arch/arm/mach-bcm/bcm_5301x.c | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/arch/arm/mach-bcm/bcm_5301x.c b/arch/arm/mach-bcm/bcm_5301x.c index 5478fe6bcce6..c8830a2b0d60 100644 --- a/arch/arm/mach-bcm/bcm_5301x.c +++ b/arch/arm/mach-bcm/bcm_5301x.c @@ -9,40 +9,6 @@ #include #include -#include -#include - - -static bool first_fault = true; - -static int bcm5301x_abort_handler(unsigned long addr, unsigned int fsr, - struct pt_regs *regs) -{ - if ((fsr == 0x1406 || fsr == 0x1c06) && first_fault) { - first_fault = false; - - /* - * These faults with codes 0x1406 (BCM4709) or 0x1c06 happens - * for no good reason, possibly left over from the CFE boot - * loader. - */ - pr_warn("External imprecise Data abort at addr=%#lx, fsr=%#x ignored.\n", - addr, fsr); - - /* Returning non-zero causes fault display and panic */ - return 0; - } - - /* Others should cause a fault */ - return 1; -} - -static void __init bcm5301x_init_early(void) -{ - /* Install our hook */ - hook_fault_code(16 + 6, bcm5301x_abort_handler, SIGBUS, BUS_OBJERR, - "imprecise external abort"); -} static const char *const bcm5301x_dt_compat[] __initconst = { "brcm,bcm4708", @@ -52,6 +18,5 @@ static const char *const bcm5301x_dt_compat[] __initconst = { DT_MACHINE_START(BCM5301X, "BCM5301X") .l2c_aux_val = 0, .l2c_aux_mask = ~0, - .init_early = bcm5301x_init_early, .dt_compat = bcm5301x_dt_compat, MACHINE_END From f4ce7effe2253a325f8ba182903cbdf0d8698593 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 21 Nov 2015 15:29:47 +0100 Subject: [PATCH 2/5] ARM: BCM5310X: activate erratas needed for SoC The BCM4708 I have, which is probably the first generation which got to the consumer market, is using a ARM Cortex-A9 rev r3p0 and a L2C-310 rev r3p2 L2 cache controller. There are 3 workarounds for known erratas in the Linux kernel which could be activated and will be in this patch. There are currently no workarounds which have to be activated for the L2C-310 rev r3p2 in Linux. Signed-off-by: Hauke Mehrtens Signed-off-by: Florian Fainelli --- arch/arm/mach-bcm/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index 8c53c55be1fe..c32628b045e4 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig @@ -52,6 +52,10 @@ config ARCH_BCM_NSP config ARCH_BCM_5301X bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7 select ARCH_BCM_IPROC + select ARM_ERRATA_754322 + select ARM_ERRATA_775420 + select ARM_ERRATA_764369 if SMP + help Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores. From 84320e1a635fcf90cff4185f029ce9e31bf1d4a7 Mon Sep 17 00:00:00 2001 From: Kapil Hali Date: Tue, 1 Dec 2015 11:24:06 -0500 Subject: [PATCH 3/5] ARM: BCM: Clean up SMP support for Broadcom Kona These changes cleans up SMP implementaion for Broadcom's Kona SoC which are required for handling SMP for iProc family of SoCs at a single place for BCM NSP and BCM Kona. Signed-off-by: Kapil Hali Acked-by: Rob Herring Signed-off-by: Florian Fainelli --- arch/arm/boot/dts/bcm11351.dtsi | 2 +- arch/arm/boot/dts/bcm21664.dtsi | 2 +- arch/arm/mach-bcm/kona_smp.c | 80 ++++++++++++++++++++++----------- 3 files changed, 55 insertions(+), 29 deletions(-) diff --git a/arch/arm/boot/dts/bcm11351.dtsi b/arch/arm/boot/dts/bcm11351.dtsi index 2ddaa5136611..3dc7a8cc5812 100644 --- a/arch/arm/boot/dts/bcm11351.dtsi +++ b/arch/arm/boot/dts/bcm11351.dtsi @@ -31,7 +31,6 @@ cpus { #address-cells = <1>; #size-cells = <0>; enable-method = "brcm,bcm11351-cpu-method"; - secondary-boot-reg = <0x3500417c>; cpu0: cpu@0 { device_type = "cpu"; @@ -42,6 +41,7 @@ cpu0: cpu@0 { cpu1: cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a9"; + secondary-boot-reg = <0x3500417c>; reg = <1>; }; }; diff --git a/arch/arm/boot/dts/bcm21664.dtsi b/arch/arm/boot/dts/bcm21664.dtsi index 2016b72a8fb7..3f525be28fd0 100644 --- a/arch/arm/boot/dts/bcm21664.dtsi +++ b/arch/arm/boot/dts/bcm21664.dtsi @@ -31,7 +31,6 @@ cpus { #address-cells = <1>; #size-cells = <0>; enable-method = "brcm,bcm11351-cpu-method"; - secondary-boot-reg = <0x35004178>; cpu0: cpu@0 { device_type = "cpu"; @@ -42,6 +41,7 @@ cpu0: cpu@0 { cpu1: cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a9"; + secondary-boot-reg = <0x35004178>; reg = <1>; }; }; diff --git a/arch/arm/mach-bcm/kona_smp.c b/arch/arm/mach-bcm/kona_smp.c index 66a0465528a5..15af781228a5 100644 --- a/arch/arm/mach-bcm/kona_smp.c +++ b/arch/arm/mach-bcm/kona_smp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Broadcom Corporation + * Copyright (C) 2014-2015 Broadcom Corporation * Copyright 2014 Linaro Limited * * This program is free software; you can redistribute it and/or @@ -30,9 +30,10 @@ /* Name of device node property defining secondary boot register location */ #define OF_SECONDARY_BOOT "secondary-boot-reg" +#define MPIDR_CPUID_BITMASK 0x3 /* I/O address of register used to coordinate secondary core startup */ -static u32 secondary_boot; +static u32 secondary_boot_addr; /* * Enable the Cortex A9 Snoop Control Unit @@ -78,44 +79,68 @@ static int __init scu_a9_enable(void) static void __init bcm_smp_prepare_cpus(unsigned int max_cpus) { static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 }; - struct device_node *node; + struct device_node *cpus_node = NULL; + struct device_node *cpu_node = NULL; int ret; - BUG_ON(secondary_boot); /* We're called only once */ - /* * This function is only called via smp_ops->smp_prepare_cpu(). * That only happens if a "/cpus" device tree node exists * and has an "enable-method" property that selects the SMP * operations defined herein. */ - node = of_find_node_by_path("/cpus"); - BUG_ON(!node); + cpus_node = of_find_node_by_path("/cpus"); + if (!cpus_node) + return; - /* - * Our secondary enable method requires a "secondary-boot-reg" - * property to specify a register address used to request the - * ROM code boot a secondary code. If we have any trouble - * getting this we fall back to uniprocessor mode. - */ - if (of_property_read_u32(node, OF_SECONDARY_BOOT, &secondary_boot)) { - pr_err("%s: missing/invalid " OF_SECONDARY_BOOT " property\n", - node->name); - ret = -ENOENT; /* Arrange to disable SMP */ - goto out; + for_each_child_of_node(cpus_node, cpu_node) { + u32 cpuid; + + if (of_node_cmp(cpu_node->type, "cpu")) + continue; + + if (of_property_read_u32(cpu_node, "reg", &cpuid)) { + pr_debug("%s: missing reg property\n", + cpu_node->full_name); + ret = -ENOENT; + goto out; + } + + /* + * "secondary-boot-reg" property should be defined only + * for secondary cpu + */ + if ((cpuid & MPIDR_CPUID_BITMASK) == 1) { + /* + * Our secondary enable method requires a + * "secondary-boot-reg" property to specify a register + * address used to request the ROM code boot a secondary + * core. If we have any trouble getting this we fall + * back to uniprocessor mode. + */ + if (of_property_read_u32(cpu_node, + OF_SECONDARY_BOOT, + &secondary_boot_addr)) { + pr_warn("%s: no" OF_SECONDARY_BOOT "property\n", + cpu_node->name); + ret = -ENOENT; + goto out; + } + } } /* - * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is + * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is * returned, the SoC reported a uniprocessor configuration. * We bail on any other error. */ ret = scu_a9_enable(); out: - of_node_put(node); + of_node_put(cpu_node); + of_node_put(cpus_node); + if (ret) { /* Update the CPU present map to reflect uniprocessor mode */ - BUG_ON(ret != -ENOENT); pr_warn("disabling SMP\n"); init_cpu_present(&only_cpu_0); } @@ -139,7 +164,7 @@ static void __init bcm_smp_prepare_cpus(unsigned int max_cpus) * - Wait for the secondary boot register to be re-written, which * indicates the secondary core has started. */ -static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle) +static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle) { void __iomem *boot_reg; phys_addr_t boot_func; @@ -154,15 +179,16 @@ static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle) return -EINVAL; } - if (!secondary_boot) { + if (!secondary_boot_addr) { pr_err("required secondary boot register not specified\n"); return -EINVAL; } - boot_reg = ioremap_nocache((phys_addr_t)secondary_boot, sizeof(u32)); + boot_reg = ioremap_nocache( + (phys_addr_t)secondary_boot_addr, sizeof(u32)); if (!boot_reg) { pr_err("unable to map boot register for cpu %u\n", cpu_id); - return -ENOSYS; + return -ENOMEM; } /* @@ -191,12 +217,12 @@ static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle) pr_err("timeout waiting for cpu %u to start\n", cpu_id); - return -ENOSYS; + return -ENXIO; } static struct smp_operations bcm_smp_ops __initdata = { .smp_prepare_cpus = bcm_smp_prepare_cpus, - .smp_boot_secondary = bcm_boot_secondary, + .smp_boot_secondary = kona_boot_secondary, }; CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method", &bcm_smp_ops); From 97890821bb58dea522f823d8db396f9c17c6e356 Mon Sep 17 00:00:00 2001 From: Kapil Hali Date: Tue, 1 Dec 2015 11:24:08 -0500 Subject: [PATCH 4/5] 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 Signed-off-by: Florian Fainelli --- arch/arm/mach-bcm/Kconfig | 2 + arch/arm/mach-bcm/Makefile | 8 ++- arch/arm/mach-bcm/{kona_smp.c => platsmp.c} | 64 ++++++++++++++++++++- 3 files changed, 71 insertions(+), 3 deletions(-) rename arch/arm/mach-bcm/{kona_smp.c => platsmp.c} (81%) diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index c32628b045e4..6e3e043ce332 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig @@ -40,6 +40,8 @@ config ARCH_BCM_NSP select ARCH_BCM_IPROC select ARM_ERRATA_754322 select ARM_ERRATA_775420 + select ARM_ERRATA_764369 if SMP + select HAVE_SMP help Support for Broadcom Northstar Plus SoC. Broadcom Northstar Plus family of SoCs are used for switching control diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile index 892261fec0ae..5193a25a56ca 100644 --- a/arch/arm/mach-bcm/Makefile +++ b/arch/arm/mach-bcm/Makefile @@ -14,7 +14,11 @@ obj-$(CONFIG_ARCH_BCM_CYGNUS) += bcm_cygnus.o # Northstar Plus -obj-$(CONFIG_ARCH_BCM_NSP) += bcm_nsp.o +obj-$(CONFIG_ARCH_BCM_NSP) += bcm_nsp.o + +ifeq ($(CONFIG_ARCH_BCM_NSP),y) +obj-$(CONFIG_SMP) += platsmp.o +endif # BCM281XX obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o @@ -23,7 +27,7 @@ obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o obj-$(CONFIG_ARCH_BCM_21664) += board_bcm21664.o # BCM281XX and BCM21664 SMP support -obj-$(CONFIG_ARCH_BCM_MOBILE_SMP) += kona_smp.o +obj-$(CONFIG_ARCH_BCM_MOBILE_SMP) += platsmp.o # BCM281XX and BCM21664 L2 cache control obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona_l2_cache.o diff --git a/arch/arm/mach-bcm/kona_smp.c b/arch/arm/mach-bcm/platsmp.c similarity index 81% rename from arch/arm/mach-bcm/kona_smp.c rename to arch/arm/mach-bcm/platsmp.c index 15af781228a5..ea4201e6d0c9 100644 --- a/arch/arm/mach-bcm/kona_smp.c +++ b/arch/arm/mach-bcm/platsmp.c @@ -12,12 +12,17 @@ * GNU General Public License for more details. */ -#include +#include +#include #include +#include #include +#include #include #include +#include +#include #include #include #include @@ -76,6 +81,36 @@ static int __init scu_a9_enable(void) return 0; } +static int nsp_write_lut(void) +{ + void __iomem *sku_rom_lut; + phys_addr_t secondary_startup_phy; + + if (!secondary_boot_addr) { + pr_warn("required secondary boot register not specified\n"); + return -EINVAL; + } + + sku_rom_lut = ioremap_nocache((phys_addr_t)secondary_boot_addr, + sizeof(secondary_boot_addr)); + if (!sku_rom_lut) { + pr_warn("unable to ioremap SKU-ROM LUT register\n"); + return -ENOMEM; + } + + secondary_startup_phy = virt_to_phys(secondary_startup); + BUG_ON(secondary_startup_phy > (phys_addr_t)U32_MAX); + + writel_relaxed(secondary_startup_phy, sku_rom_lut); + + /* Ensure the write is visible to the secondary core */ + smp_wmb(); + + iounmap(sku_rom_lut); + + return 0; +} + static void __init bcm_smp_prepare_cpus(unsigned int max_cpus) { static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 }; @@ -220,9 +255,36 @@ static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle) return -ENXIO; } +static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + int ret; + + /* + * After wake up, secondary core branches to the startup + * address programmed at SKU ROM LUT location. + */ + ret = nsp_write_lut(); + if (ret) { + pr_err("unable to write startup addr to SKU ROM LUT\n"); + goto out; + } + + /* Send a CPU wakeup interrupt to the secondary core */ + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); + +out: + return ret; +} + static struct smp_operations bcm_smp_ops __initdata = { .smp_prepare_cpus = bcm_smp_prepare_cpus, .smp_boot_secondary = kona_boot_secondary, }; CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method", &bcm_smp_ops); + +struct smp_operations nsp_smp_ops __initdata = { + .smp_prepare_cpus = bcm_smp_prepare_cpus, + .smp_boot_secondary = nsp_boot_secondary, +}; +CPU_METHOD_OF_DECLARE(bcm_smp_nsp, "brcm,bcm-nsp-smp", &nsp_smp_ops); From 99498905ac1fbc73a97d27d21ea449fb939072e3 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Tue, 1 Dec 2015 11:24:09 -0500 Subject: [PATCH 5/5] ARM: BCM: Add SMP support for Broadcom 4708 Add SMP support for Broadcom's 4708 SoCs. Signed-off-by: Jon Mason Acked-by: Hauke Mehrtens Tested-by: Hauke Mehrtens Signed-off-by: Kapil Hali Signed-off-by: Florian Fainelli --- arch/arm/boot/dts/bcm4708.dtsi | 2 ++ arch/arm/mach-bcm/Kconfig | 1 + arch/arm/mach-bcm/Makefile | 3 +++ 3 files changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/bcm4708.dtsi b/arch/arm/boot/dts/bcm4708.dtsi index 31141e83fedd..eed4dd159995 100644 --- a/arch/arm/boot/dts/bcm4708.dtsi +++ b/arch/arm/boot/dts/bcm4708.dtsi @@ -15,6 +15,7 @@ / { cpus { #address-cells = <1>; #size-cells = <0>; + enable-method = "brcm,bcm-nsp-smp"; cpu@0 { device_type = "cpu"; @@ -27,6 +28,7 @@ cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a9"; next-level-cache = <&L2>; + secondary-boot-reg = <0xffff0400>; reg = <0x1>; }; }; diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index 6e3e043ce332..0207736674d6 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig @@ -57,6 +57,7 @@ config ARCH_BCM_5301X select ARM_ERRATA_754322 select ARM_ERRATA_775420 select ARM_ERRATA_764369 if SMP + select HAVE_SMP help Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores. diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile index 5193a25a56ca..7d665151c772 100644 --- a/arch/arm/mach-bcm/Makefile +++ b/arch/arm/mach-bcm/Makefile @@ -43,6 +43,9 @@ obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o # BCM5301X obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o +ifeq ($(CONFIG_ARCH_BCM_5301X),y) +obj-$(CONFIG_SMP) += platsmp.o +endif # BCM63XXx ifeq ($(CONFIG_ARCH_BCM_63XX),y)