aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-bcm
diff options
context:
space:
mode:
authorChris Brand <chris.brand@broadcom.com>2016-05-11 17:36:21 -0400
committerFlorian Fainelli <f.fainelli@gmail.com>2016-06-06 14:47:33 -0400
commit5fcf999abfeb908f5a6fead7c4a99c23c705e9c0 (patch)
treea76780c515f99cb8aef3494f2dcdced7a01653ff /arch/arm/mach-bcm
parent4533d5f7dd8bcf4d9348f1f8b707ca2599531183 (diff)
ARM: BCM23550 SMP support
BCM23550 has a Cluster Dormant Control IP block that holds cores in an idle state. Support a new CPU enable method in which the CDC is accessed to bring the core online. Signed-off-by: Raymond Ngun <raymond.ngun@broadcom.com> Signed-off-by: Chris Brand <chris.brand@broadcom.com> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Diffstat (limited to 'arch/arm/mach-bcm')
-rw-r--r--arch/arm/mach-bcm/platsmp.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/arch/arm/mach-bcm/platsmp.c b/arch/arm/mach-bcm/platsmp.c
index cfae9c71fb74..33c4d8349f95 100644
--- a/arch/arm/mach-bcm/platsmp.c
+++ b/arch/arm/mach-bcm/platsmp.c
@@ -19,6 +19,7 @@
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/jiffies.h> 20#include <linux/jiffies.h>
21#include <linux/of.h> 21#include <linux/of.h>
22#include <linux/of_address.h>
22#include <linux/sched.h> 23#include <linux/sched.h>
23#include <linux/smp.h> 24#include <linux/smp.h>
24 25
@@ -255,6 +256,57 @@ static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle)
255 return -ENXIO; 256 return -ENXIO;
256} 257}
257 258
259/* Cluster Dormant Control command to bring CPU into a running state */
260#define CDC_CMD 6
261#define CDC_CMD_OFFSET 0
262#define CDC_CMD_REG(cpu) (CDC_CMD_OFFSET + 4*(cpu))
263
264/*
265 * BCM23550 has a Cluster Dormant Control block that keeps the core in
266 * idle state. A command needs to be sent to the block to bring the CPU
267 * into running state.
268 */
269static int bcm23550_boot_secondary(unsigned int cpu, struct task_struct *idle)
270{
271 void __iomem *cdc_base;
272 struct device_node *dn;
273 char *name;
274 int ret;
275
276 /* Make sure a CDC node exists before booting the
277 * secondary core.
278 */
279 name = "brcm,bcm23550-cdc";
280 dn = of_find_compatible_node(NULL, NULL, name);
281 if (!dn) {
282 pr_err("unable to find cdc node\n");
283 return -ENODEV;
284 }
285
286 cdc_base = of_iomap(dn, 0);
287 of_node_put(dn);
288
289 if (!cdc_base) {
290 pr_err("unable to remap cdc base register\n");
291 return -ENOMEM;
292 }
293
294 /* Boot the secondary core */
295 ret = kona_boot_secondary(cpu, idle);
296 if (ret)
297 goto out;
298
299 /* Bring this CPU to RUN state so that nIRQ nFIQ
300 * signals are unblocked.
301 */
302 writel_relaxed(CDC_CMD, cdc_base + CDC_CMD_REG(cpu));
303
304out:
305 iounmap(cdc_base);
306
307 return ret;
308}
309
258static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle) 310static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle)
259{ 311{
260 int ret; 312 int ret;
@@ -283,6 +335,12 @@ static const struct smp_operations bcm_smp_ops __initconst = {
283CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method", 335CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method",
284 &bcm_smp_ops); 336 &bcm_smp_ops);
285 337
338static const struct smp_operations bcm23550_smp_ops __initconst = {
339 .smp_boot_secondary = bcm23550_boot_secondary,
340};
341CPU_METHOD_OF_DECLARE(bcm_smp_bcm23550, "brcm,bcm23550",
342 &bcm23550_smp_ops);
343
286static const struct smp_operations nsp_smp_ops __initconst = { 344static const struct smp_operations nsp_smp_ops __initconst = {
287 .smp_prepare_cpus = bcm_smp_prepare_cpus, 345 .smp_prepare_cpus = bcm_smp_prepare_cpus,
288 .smp_boot_secondary = nsp_boot_secondary, 346 .smp_boot_secondary = nsp_boot_secondary,