Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 97890821 authored by Kapil Hali's avatar Kapil Hali Committed by Florian Fainelli
Browse files

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: default avatarKapil Hali <kapilh@broadcom.com>
Signed-off-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
parent 84320e1a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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
+6 −2
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@ obj-$(CONFIG_ARCH_BCM_CYGNUS) += bcm_cygnus.o
# Northstar Plus
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
+63 −1
Original line number Diff line number Diff line
@@ -12,12 +12,17 @@
 * GNU General Public License for more details.
 */

#include <linux/init.h>
#include <linux/cpumask.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/jiffies.h>
#include <linux/of.h>
#include <linux/sched.h>
#include <linux/smp.h>

#include <asm/cacheflush.h>
#include <asm/smp.h>
#include <asm/smp_plat.h>
#include <asm/smp_scu.h>
@@ -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);