Skip to content

Commit 5fcf999

Browse files
Chris Brandffainelli
authored andcommitted
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>
1 parent 4533d5f commit 5fcf999

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

arch/arm/mach-bcm/platsmp.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/io.h>
2020
#include <linux/jiffies.h>
2121
#include <linux/of.h>
22+
#include <linux/of_address.h>
2223
#include <linux/sched.h>
2324
#include <linux/smp.h>
2425

@@ -255,6 +256,57 @@ static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle)
255256
return -ENXIO;
256257
}
257258

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+
*/
269+
static 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+
304+
out:
305+
iounmap(cdc_base);
306+
307+
return ret;
308+
}
309+
258310
static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle)
259311
{
260312
int ret;
@@ -283,6 +335,12 @@ static const struct smp_operations bcm_smp_ops __initconst = {
283335
CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method",
284336
&bcm_smp_ops);
285337

338+
static const struct smp_operations bcm23550_smp_ops __initconst = {
339+
.smp_boot_secondary = bcm23550_boot_secondary,
340+
};
341+
CPU_METHOD_OF_DECLARE(bcm_smp_bcm23550, "brcm,bcm23550",
342+
&bcm23550_smp_ops);
343+
286344
static const struct smp_operations nsp_smp_ops __initconst = {
287345
.smp_prepare_cpus = bcm_smp_prepare_cpus,
288346
.smp_boot_secondary = nsp_boot_secondary,

0 commit comments

Comments
 (0)