xref: /openbmc/linux/arch/arm/mach-mvebu/platsmp-a9.c (revision 305969fb629284bcd35065911179a79f41954b9a)
11ee89e22SGregory CLEMENT /*
21ee89e22SGregory CLEMENT  * Symmetric Multi Processing (SMP) support for Marvell EBU Cortex-A9
31ee89e22SGregory CLEMENT  * based SOCs (Armada 375/38x).
41ee89e22SGregory CLEMENT  *
51ee89e22SGregory CLEMENT  * Copyright (C) 2014 Marvell
61ee89e22SGregory CLEMENT  *
71ee89e22SGregory CLEMENT  * Gregory CLEMENT <gregory.clement@free-electrons.com>
81ee89e22SGregory CLEMENT  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
91ee89e22SGregory CLEMENT  *
101ee89e22SGregory CLEMENT  * This file is licensed under the terms of the GNU General Public
111ee89e22SGregory CLEMENT  * License version 2.  This program is licensed "as is" without any
121ee89e22SGregory CLEMENT  * warranty of any kind, whether express or implied.
131ee89e22SGregory CLEMENT  */
141ee89e22SGregory CLEMENT 
151ee89e22SGregory CLEMENT #include <linux/init.h>
161ee89e22SGregory CLEMENT #include <linux/io.h>
171ee89e22SGregory CLEMENT #include <linux/of.h>
181ee89e22SGregory CLEMENT #include <linux/smp.h>
1987384cc0SGregory CLEMENT #include <linux/mbus.h>
201ee89e22SGregory CLEMENT #include <asm/smp_scu.h>
211ee89e22SGregory CLEMENT #include <asm/smp_plat.h>
221ee89e22SGregory CLEMENT #include "common.h"
231ee89e22SGregory CLEMENT #include "pmsu.h"
241ee89e22SGregory CLEMENT 
251ee89e22SGregory CLEMENT extern void mvebu_cortex_a9_secondary_startup(void);
261ee89e22SGregory CLEMENT 
271ee89e22SGregory CLEMENT static int __cpuinit mvebu_cortex_a9_boot_secondary(unsigned int cpu,
281ee89e22SGregory CLEMENT 						    struct task_struct *idle)
291ee89e22SGregory CLEMENT {
301ee89e22SGregory CLEMENT 	int ret, hw_cpu;
311ee89e22SGregory CLEMENT 
321ee89e22SGregory CLEMENT 	pr_info("Booting CPU %d\n", cpu);
331ee89e22SGregory CLEMENT 
341ee89e22SGregory CLEMENT 	/*
351ee89e22SGregory CLEMENT 	 * Write the address of secondary startup into the system-wide
361ee89e22SGregory CLEMENT 	 * flags register. The boot monitor waits until it receives a
371ee89e22SGregory CLEMENT 	 * soft interrupt, and then the secondary CPU branches to this
381ee89e22SGregory CLEMENT 	 * address.
391ee89e22SGregory CLEMENT 	 */
401ee89e22SGregory CLEMENT 	hw_cpu = cpu_logical_map(cpu);
41*305969fbSGregory CLEMENT 	if (of_machine_is_compatible("marvell,armada375"))
421ee89e22SGregory CLEMENT 		mvebu_system_controller_set_cpu_boot_addr(mvebu_cortex_a9_secondary_startup);
43*305969fbSGregory CLEMENT 	else
44*305969fbSGregory CLEMENT 		mvebu_pmsu_set_cpu_boot_addr(hw_cpu, mvebu_cortex_a9_secondary_startup);
451ee89e22SGregory CLEMENT 	smp_wmb();
461ee89e22SGregory CLEMENT 	ret = mvebu_cpu_reset_deassert(hw_cpu);
471ee89e22SGregory CLEMENT 	if (ret) {
481ee89e22SGregory CLEMENT 		pr_err("Could not start the secondary CPU: %d\n", ret);
491ee89e22SGregory CLEMENT 		return ret;
501ee89e22SGregory CLEMENT 	}
511ee89e22SGregory CLEMENT 	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
521ee89e22SGregory CLEMENT 
531ee89e22SGregory CLEMENT 	return 0;
541ee89e22SGregory CLEMENT }
551ee89e22SGregory CLEMENT 
561ee89e22SGregory CLEMENT static struct smp_operations mvebu_cortex_a9_smp_ops __initdata = {
571ee89e22SGregory CLEMENT 	.smp_boot_secondary	= mvebu_cortex_a9_boot_secondary,
581ee89e22SGregory CLEMENT };
591ee89e22SGregory CLEMENT 
601ee89e22SGregory CLEMENT CPU_METHOD_OF_DECLARE(mvebu_armada_375_smp, "marvell,armada-375-smp",
611ee89e22SGregory CLEMENT 		      &mvebu_cortex_a9_smp_ops);
621ee89e22SGregory CLEMENT CPU_METHOD_OF_DECLARE(mvebu_armada_380_smp, "marvell,armada-380-smp",
631ee89e22SGregory CLEMENT 		      &mvebu_cortex_a9_smp_ops);
64