aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-bcm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-bcm')
-rw-r--r--arch/arm/mach-bcm/Kconfig21
-rw-r--r--arch/arm/mach-bcm/Makefile5
-rw-r--r--arch/arm/mach-bcm/board_bcm21664.c45
-rw-r--r--arch/arm/mach-bcm/board_bcm23550.c25
-rw-r--r--arch/arm/mach-bcm/board_bcm281xx.c2
-rw-r--r--arch/arm/mach-bcm/board_bcm2835.c10
-rw-r--r--arch/arm/mach-bcm/kona_l2_cache.c1
-rw-r--r--arch/arm/mach-bcm/platsmp.c174
8 files changed, 140 insertions, 143 deletions
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 68ab6412392a..34f0fca0b847 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -17,7 +17,7 @@ config ARCH_BCM_IPROC
select ARM_GLOBAL_TIMER
select COMMON_CLK_IPROC
select CLKSRC_MMIO
- select ARCH_REQUIRE_GPIOLIB
+ select GPIOLIB
select ARM_AMBA
select PINCTRL
help
@@ -80,7 +80,7 @@ comment "KONA architected SoCs"
config ARCH_BCM_MOBILE
bool
- select ARCH_REQUIRE_GPIOLIB
+ select GPIOLIB
select ARM_ERRATA_754322
select ARM_ERRATA_775420
select ARM_GIC
@@ -89,6 +89,7 @@ config ARCH_BCM_MOBILE
select HAVE_ARM_ARCH_TIMER
select PINCTRL
select ARCH_BCM_MOBILE_SMP if SMP
+ select BCM_KONA_TIMER
help
This enables support for systems based on Broadcom mobile SoCs.
@@ -111,9 +112,17 @@ config ARCH_BCM_21664
Enable support for the BCM21664 family, which includes
BCM21663 and BCM21664 variants.
+config ARCH_BCM_23550
+ bool "Broadcom BCM23550 SoC"
+ depends on ARCH_MULTI_V7
+ select ARCH_BCM_MOBILE
+ select HAVE_SMP
+ help
+ Enable support for the BCM23550.
+
config ARCH_BCM_MOBILE_L2_CACHE
bool "Broadcom mobile SoC level 2 cache support"
- depends on ARCH_BCM_MOBILE
+ depends on ARCH_BCM_281XX || ARCH_BCM_21664
default y
select CACHE_L2X0
select ARCH_BCM_MOBILE_SMC
@@ -128,7 +137,7 @@ config ARCH_BCM_MOBILE_SMP
select HAVE_ARM_SCU
select ARM_ERRATA_764369
help
- SMP support for the BCM281XX and BCM21664 SoC families.
+ SMP support for the BCM281XX, BCM21664 and BCM23550 SoC families.
Provided as an option so SMP support for SoCs of this type
can be disabled for an SMP-enabled kernel.
@@ -137,12 +146,13 @@ comment "Other Architectures"
config ARCH_BCM2835
bool "Broadcom BCM2835 family"
depends on ARCH_MULTI_V6 || ARCH_MULTI_V7
- select ARCH_REQUIRE_GPIOLIB
+ select GPIOLIB
select ARM_AMBA
select ARM_ERRATA_411920 if ARCH_MULTI_V6
select ARM_TIMER_SP804
select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7
select CLKSRC_OF
+ select BCM2835_TIMER
select PINCTRL
select PINCTRL_BCM2835
help
@@ -176,7 +186,6 @@ config ARCH_BRCMSTB
select BRCMSTB_L2_IRQ
select BCM7120_L2_IRQ
select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
- select ARCH_WANT_OPTIONAL_GPIOLIB
select SOC_BRCMSTB
select SOC_BUS
help
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
index 7d665151c772..980f5850097c 100644
--- a/arch/arm/mach-bcm/Makefile
+++ b/arch/arm/mach-bcm/Makefile
@@ -26,7 +26,10 @@ obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o
# BCM21664
obj-$(CONFIG_ARCH_BCM_21664) += board_bcm21664.o
-# BCM281XX and BCM21664 SMP support
+# BCM23550
+obj-$(CONFIG_ARCH_BCM_23550) += board_bcm23550.o
+
+# BCM281XX, BCM21664 and BCM23550 SMP support
obj-$(CONFIG_ARCH_BCM_MOBILE_SMP) += platsmp.o
# BCM281XX and BCM21664 L2 cache control
diff --git a/arch/arm/mach-bcm/board_bcm21664.c b/arch/arm/mach-bcm/board_bcm21664.c
index 82ad5687771f..c5bf01641172 100644
--- a/arch/arm/mach-bcm/board_bcm21664.c
+++ b/arch/arm/mach-bcm/board_bcm21664.c
@@ -11,56 +11,12 @@
* GNU General Public License for more details.
*/
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
-#include <linux/io.h>
-
#include <asm/mach/arch.h>
#include "kona_l2_cache.h"
-#define RSTMGR_DT_STRING "brcm,bcm21664-resetmgr"
-
-#define RSTMGR_REG_WR_ACCESS_OFFSET 0
-#define RSTMGR_REG_CHIP_SOFT_RST_OFFSET 4
-
-#define RSTMGR_WR_PASSWORD 0xa5a5
-#define RSTMGR_WR_PASSWORD_SHIFT 8
-#define RSTMGR_WR_ACCESS_ENABLE 1
-
-static void bcm21664_restart(enum reboot_mode mode, const char *cmd)
-{
- void __iomem *base;
- struct device_node *resetmgr;
-
- resetmgr = of_find_compatible_node(NULL, NULL, RSTMGR_DT_STRING);
- if (!resetmgr) {
- pr_emerg("Couldn't find " RSTMGR_DT_STRING "\n");
- return;
- }
- base = of_iomap(resetmgr, 0);
- if (!base) {
- pr_emerg("Couldn't map " RSTMGR_DT_STRING "\n");
- return;
- }
-
- /*
- * A soft reset is triggered by writing a 0 to bit 0 of the soft reset
- * register. To write to that register we must first write the password
- * and the enable bit in the write access enable register.
- */
- writel((RSTMGR_WR_PASSWORD << RSTMGR_WR_PASSWORD_SHIFT) |
- RSTMGR_WR_ACCESS_ENABLE,
- base + RSTMGR_REG_WR_ACCESS_OFFSET);
- writel(0, base + RSTMGR_REG_CHIP_SOFT_RST_OFFSET);
-
- /* Wait for reset */
- while (1);
-}
-
static void __init bcm21664_init(void)
{
- of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
kona_l2_cache_init();
}
@@ -71,6 +27,5 @@ static const char * const bcm21664_dt_compat[] = {
DT_MACHINE_START(BCM21664_DT, "BCM21664 Broadcom Application Processor")
.init_machine = bcm21664_init,
- .restart = bcm21664_restart,
.dt_compat = bcm21664_dt_compat,
MACHINE_END
diff --git a/arch/arm/mach-bcm/board_bcm23550.c b/arch/arm/mach-bcm/board_bcm23550.c
new file mode 100644
index 000000000000..0ac01debd077
--- /dev/null
+++ b/arch/arm/mach-bcm/board_bcm23550.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+
+static const char * const bcm23550_dt_compat[] = {
+ "brcm,bcm23550",
+ NULL,
+};
+
+DT_MACHINE_START(BCM23550_DT, "BCM23550 Broadcom Application Processor")
+ .dt_compat = bcm23550_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-bcm/board_bcm281xx.c b/arch/arm/mach-bcm/board_bcm281xx.c
index 2e367bd7c600..b81bb386951d 100644
--- a/arch/arm/mach-bcm/board_bcm281xx.c
+++ b/arch/arm/mach-bcm/board_bcm281xx.c
@@ -13,7 +13,6 @@
#include <linux/clocksource.h>
#include <linux/of_address.h>
-#include <linux/of_platform.h>
#include <asm/mach/arch.h>
@@ -58,7 +57,6 @@ static void bcm281xx_restart(enum reboot_mode mode, const char *cmd)
static void __init bcm281xx_init(void)
{
- of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
kona_l2_cache_init();
}
diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c
index 834d67684e20..0c1edfc98696 100644
--- a/arch/arm/mach-bcm/board_bcm2835.c
+++ b/arch/arm/mach-bcm/board_bcm2835.c
@@ -15,7 +15,6 @@
#include <linux/init.h>
#include <linux/irqchip.h>
#include <linux/of_address.h>
-#include <linux/of_platform.h>
#include <linux/clk/bcm2835.h>
#include <asm/mach/arch.h>
@@ -23,16 +22,7 @@
static void __init bcm2835_init(void)
{
- int ret;
-
bcm2835_init_clocks();
-
- ret = of_platform_populate(NULL, of_default_bus_match_table, NULL,
- NULL);
- if (ret) {
- pr_err("of_platform_populate failed: %d\n", ret);
- BUG();
- }
}
static const char * const bcm2835_compat[] = {
diff --git a/arch/arm/mach-bcm/kona_l2_cache.c b/arch/arm/mach-bcm/kona_l2_cache.c
index b31970377c20..59ad86304092 100644
--- a/arch/arm/mach-bcm/kona_l2_cache.c
+++ b/arch/arm/mach-bcm/kona_l2_cache.c
@@ -17,6 +17,7 @@
#include <asm/hardware/cache-l2x0.h>
#include "bcm_kona_smc.h"
+#include "kona_l2_cache.h"
void __init kona_l2_cache_init(void)
{
diff --git a/arch/arm/mach-bcm/platsmp.c b/arch/arm/mach-bcm/platsmp.c
index cfae9c71fb74..3ac3a9bc663c 100644
--- a/arch/arm/mach-bcm/platsmp.c
+++ b/arch/arm/mach-bcm/platsmp.c
@@ -19,6 +19,7 @@
#include <linux/io.h>
#include <linux/jiffies.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/sched.h>
#include <linux/smp.h>
@@ -37,9 +38,6 @@
#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_addr;
-
/*
* Enable the Cortex A9 Snoop Control Unit
*
@@ -81,20 +79,40 @@ static int __init scu_a9_enable(void)
return 0;
}
-static int nsp_write_lut(void)
+static u32 secondary_boot_addr_for(unsigned int cpu)
+{
+ u32 secondary_boot_addr = 0;
+ struct device_node *cpu_node = of_get_cpu_node(cpu, NULL);
+
+ if (!cpu_node) {
+ pr_err("Failed to find device tree node for CPU%u\n", cpu);
+ return 0;
+ }
+
+ if (of_property_read_u32(cpu_node,
+ OF_SECONDARY_BOOT,
+ &secondary_boot_addr))
+ pr_err("required secondary boot register not specified for CPU%u\n",
+ cpu);
+
+ of_node_put(cpu_node);
+
+ return secondary_boot_addr;
+}
+
+static int nsp_write_lut(unsigned int cpu)
{
void __iomem *sku_rom_lut;
phys_addr_t secondary_startup_phy;
+ const u32 secondary_boot_addr = secondary_boot_addr_for(cpu);
- if (!secondary_boot_addr) {
- pr_warn("required secondary boot register not specified\n");
+ if (!secondary_boot_addr)
return -EINVAL;
- }
sku_rom_lut = ioremap_nocache((phys_addr_t)secondary_boot_addr,
- sizeof(secondary_boot_addr));
+ sizeof(phys_addr_t));
if (!sku_rom_lut) {
- pr_warn("unable to ioremap SKU-ROM LUT register\n");
+ pr_warn("unable to ioremap SKU-ROM LUT register for cpu %u\n", cpu);
return -ENOMEM;
}
@@ -113,70 +131,12 @@ static int nsp_write_lut(void)
static void __init bcm_smp_prepare_cpus(unsigned int max_cpus)
{
- static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
- struct device_node *cpus_node = NULL;
- struct device_node *cpu_node = NULL;
- int ret;
-
- /*
- * 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.
- */
- cpus_node = of_find_node_by_path("/cpus");
- if (!cpus_node)
- return;
-
- 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
- * returned, the SoC reported a uniprocessor configuration.
- * We bail on any other error.
- */
- ret = scu_a9_enable();
-out:
- of_node_put(cpu_node);
- of_node_put(cpus_node);
+ const cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
- if (ret) {
+ /* Enable the SCU on Cortex A9 based SoCs */
+ if (scu_a9_enable()) {
/* Update the CPU present map to reflect uniprocessor mode */
- pr_warn("disabling SMP\n");
+ pr_warn("failed to enable A9 SCU - disabling SMP\n");
init_cpu_present(&only_cpu_0);
}
}
@@ -207,6 +167,7 @@ static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle)
u32 cpu_id;
u32 boot_val;
bool timeout = false;
+ const u32 secondary_boot_addr = secondary_boot_addr_for(cpu);
cpu_id = cpu_logical_map(cpu);
if (cpu_id & ~BOOT_ADDR_CPUID_MASK) {
@@ -214,13 +175,11 @@ static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle)
return -EINVAL;
}
- if (!secondary_boot_addr) {
- pr_err("required secondary boot register not specified\n");
+ if (!secondary_boot_addr)
return -EINVAL;
- }
- boot_reg = ioremap_nocache(
- (phys_addr_t)secondary_boot_addr, sizeof(u32));
+ boot_reg = ioremap_nocache((phys_addr_t)secondary_boot_addr,
+ sizeof(phys_addr_t));
if (!boot_reg) {
pr_err("unable to map boot register for cpu %u\n", cpu_id);
return -ENOMEM;
@@ -255,6 +214,57 @@ static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle)
return -ENXIO;
}
+/* Cluster Dormant Control command to bring CPU into a running state */
+#define CDC_CMD 6
+#define CDC_CMD_OFFSET 0
+#define CDC_CMD_REG(cpu) (CDC_CMD_OFFSET + 4*(cpu))
+
+/*
+ * BCM23550 has a Cluster Dormant Control block that keeps the core in
+ * idle state. A command needs to be sent to the block to bring the CPU
+ * into running state.
+ */
+static int bcm23550_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ void __iomem *cdc_base;
+ struct device_node *dn;
+ char *name;
+ int ret;
+
+ /* Make sure a CDC node exists before booting the
+ * secondary core.
+ */
+ name = "brcm,bcm23550-cdc";
+ dn = of_find_compatible_node(NULL, NULL, name);
+ if (!dn) {
+ pr_err("unable to find cdc node\n");
+ return -ENODEV;
+ }
+
+ cdc_base = of_iomap(dn, 0);
+ of_node_put(dn);
+
+ if (!cdc_base) {
+ pr_err("unable to remap cdc base register\n");
+ return -ENOMEM;
+ }
+
+ /* Boot the secondary core */
+ ret = kona_boot_secondary(cpu, idle);
+ if (ret)
+ goto out;
+
+ /* Bring this CPU to RUN state so that nIRQ nFIQ
+ * signals are unblocked.
+ */
+ writel_relaxed(CDC_CMD, cdc_base + CDC_CMD_REG(cpu));
+
+out:
+ iounmap(cdc_base);
+
+ return ret;
+}
+
static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
int ret;
@@ -263,7 +273,7 @@ static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle)
* After wake up, secondary core branches to the startup
* address programmed at SKU ROM LUT location.
*/
- ret = nsp_write_lut();
+ ret = nsp_write_lut(cpu);
if (ret) {
pr_err("unable to write startup addr to SKU ROM LUT\n");
goto out;
@@ -276,12 +286,18 @@ out:
return ret;
}
-static const struct smp_operations bcm_smp_ops __initconst = {
+static const struct smp_operations kona_smp_ops __initconst = {
.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);
+ &kona_smp_ops);
+
+static const struct smp_operations bcm23550_smp_ops __initconst = {
+ .smp_boot_secondary = bcm23550_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(bcm_smp_bcm23550, "brcm,bcm23550",
+ &bcm23550_smp_ops);
static const struct smp_operations nsp_smp_ops __initconst = {
.smp_prepare_cpus = bcm_smp_prepare_cpus,