2014-04-14 15:54:05 +02:00
/*
* Symmetric Multi Processing ( SMP ) support for Marvell EBU Cortex - A9
* based SOCs ( Armada 375 / 38 x ) .
*
* Copyright ( C ) 2014 Marvell
*
* Gregory CLEMENT < gregory . clement @ free - electrons . com >
* Thomas Petazzoni < thomas . petazzoni @ free - electrons . com >
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed " as is " without any
* warranty of any kind , whether express or implied .
*/
# include <linux/init.h>
# include <linux/io.h>
# include <linux/of.h>
# include <linux/smp.h>
2014-04-14 15:54:06 +02:00
# include <linux/mbus.h>
2014-04-14 15:54:05 +02:00
# include <asm/smp_scu.h>
# include <asm/smp_plat.h>
# include "common.h"
# include "pmsu.h"
extern void mvebu_cortex_a9_secondary_startup ( void ) ;
2015-01-17 16:42:47 -05:00
static int mvebu_cortex_a9_boot_secondary ( unsigned int cpu ,
2014-04-14 15:54:05 +02:00
struct task_struct * idle )
{
int ret , hw_cpu ;
pr_info ( " Booting CPU %d \n " , cpu ) ;
/*
* Write the address of secondary startup into the system - wide
* flags register . The boot monitor waits until it receives a
* soft interrupt , and then the secondary CPU branches to this
* address .
*/
hw_cpu = cpu_logical_map ( cpu ) ;
2014-07-23 15:00:41 +02:00
if ( of_machine_is_compatible ( " marvell,armada375 " ) )
2014-04-14 15:54:05 +02:00
mvebu_system_controller_set_cpu_boot_addr ( mvebu_cortex_a9_secondary_startup ) ;
2014-07-23 15:00:41 +02:00
else
mvebu_pmsu_set_cpu_boot_addr ( hw_cpu , mvebu_cortex_a9_secondary_startup ) ;
2014-04-14 15:54:05 +02:00
smp_wmb ( ) ;
2014-10-30 12:39:44 +01:00
/*
* Doing this before deasserting the CPUs is needed to wake up CPUs
* in the offline state after using CPU hotplug .
*/
arch_send_wakeup_ipi_mask ( cpumask_of ( cpu ) ) ;
2014-04-14 15:54:05 +02:00
ret = mvebu_cpu_reset_deassert ( hw_cpu ) ;
if ( ret ) {
pr_err ( " Could not start the secondary CPU: %d \n " , ret ) ;
return ret ;
}
return 0 ;
}
2014-10-30 12:39:44 +01:00
/*
* When a CPU is brought back online , either through CPU hotplug , or
* because of the boot of a kexec ' ed kernel , the PMSU configuration
* for this CPU might be in the deep idle state , preventing this CPU
* from receiving interrupts . Here , we therefore take out the current
* CPU from this state , which was entered by armada_38x_cpu_die ( )
* below .
*/
static void armada_38x_secondary_init ( unsigned int cpu )
{
mvebu_v7_pmsu_idle_exit ( ) ;
}
# ifdef CONFIG_HOTPLUG_CPU
static void armada_38x_cpu_die ( unsigned int cpu )
{
/*
* CPU hotplug is implemented by putting offline CPUs into the
* deep idle sleep state .
*/
armada_38x_do_cpu_suspend ( true ) ;
}
/*
* We need a dummy function , so that platform_can_cpu_hotplug ( ) knows
* we support CPU hotplug . However , the function does not need to do
* anything , because CPUs going offline can enter the deep idle state
* by themselves , without any help from a still alive CPU .
*/
static int armada_38x_cpu_kill ( unsigned int cpu )
{
return 1 ;
}
# endif
2014-04-14 15:54:05 +02:00
2015-11-15 10:39:53 +09:00
static const struct smp_operations mvebu_cortex_a9_smp_ops __initconst = {
2014-04-14 15:54:05 +02:00
. smp_boot_secondary = mvebu_cortex_a9_boot_secondary ,
} ;
2015-11-15 10:39:53 +09:00
static const struct smp_operations armada_38x_smp_ops __initconst = {
2014-10-30 12:39:44 +01:00
. smp_boot_secondary = mvebu_cortex_a9_boot_secondary ,
. smp_secondary_init = armada_38x_secondary_init ,
# ifdef CONFIG_HOTPLUG_CPU
. cpu_die = armada_38x_cpu_die ,
. cpu_kill = armada_38x_cpu_kill ,
# endif
} ;
2014-04-14 15:54:05 +02:00
CPU_METHOD_OF_DECLARE ( mvebu_armada_375_smp , " marvell,armada-375-smp " ,
& mvebu_cortex_a9_smp_ops ) ;
CPU_METHOD_OF_DECLARE ( mvebu_armada_380_smp , " marvell,armada-380-smp " ,
2014-10-30 12:39:44 +01:00
& armada_38x_smp_ops ) ;
ARM: mvebu: add core support for Armada 39x
This commit adds the core support for Armada 39x, which is quite
simple:
- a new Kconfig option which selects the appropriate clock and
pinctrl drivers as well as other common features (GIC, L2 cache,
SMP, etc.)
- a new DT_MACHINE_START which references the top-level compatible
strings supported for the Marvell Armada 39x.
- a new SMP enable-method. The mechanism to enable CPUs for Armada
39x appears to be the same as Armada 38x. However, we do not want
to use marvell,armada-380-smp in the Device Tree, in the case of
the discovery of a subtle difference in the future, which would
require changing the Device Tree. And the enable-method isn't a
compatible string: you can't specify several values and expect a
fallback on the second string if the first one isn't
supported. Therefore, we simply declare the SMP enable method
"marvell,armada-390-smp" as doing the same thing as the
"marvell,armada-380-smp" one.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
2015-03-03 15:41:11 +01:00
CPU_METHOD_OF_DECLARE ( mvebu_armada_390_smp , " marvell,armada-390-smp " ,
& armada_38x_smp_ops ) ;