From 1ee89e2231a1b04dc34765edd195725ddf4ba998 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Mon, 14 Apr 2014 15:54:05 +0200 Subject: ARM: mvebu: add SMP support for Armada 375 and Armada 38x This commit adds the SMP support for Armada 375 and Armada 38x. It turns out that the SMP logic for both of these SOCs are fairly similar, the only differences being: * A different method to set the secondary CPU boot address * An Armada 375 specific workaround needed for the early Z1 stepping, added by the following patch. Other than that, the patch is fairly straightforward and adds the usual platsmp and headsmp code, defining the smp_operations structure that is referenced from the DT_MACHINE structures. Signed-off-by: Gregory CLEMENT Link: https://lkml.kernel.org/r/1397483648-26611-9-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Thomas Petazzoni Link: https://lkml.kernel.org/r/1397483648-26611-9-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper --- arch/arm/mach-mvebu/headsmp-a9.S | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 arch/arm/mach-mvebu/headsmp-a9.S (limited to 'arch/arm/mach-mvebu/headsmp-a9.S') diff --git a/arch/arm/mach-mvebu/headsmp-a9.S b/arch/arm/mach-mvebu/headsmp-a9.S new file mode 100644 index 000000000000..78e66c96e718 --- /dev/null +++ b/arch/arm/mach-mvebu/headsmp-a9.S @@ -0,0 +1,22 @@ +/* + * SMP support: Entry point for secondary CPUs of Marvell EBU + * Cortex-A9 based SOCs (Armada 375 and Armada 38x). + * + * Copyright (C) 2014 Marvell + * + * Gregory CLEMENT + * Thomas Petazzoni + * + * 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 +#include + + __CPUINIT +ENTRY(mvebu_cortex_a9_secondary_startup) + bl v7_invalidate_l1 + b secondary_startup +ENDPROC(mvebu_cortex_a9_secondary_startup) -- cgit v1.2.3 From 87384cc0b4bffbe26d9172d49d8b287332e9d397 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Mon, 14 Apr 2014 15:54:06 +0200 Subject: ARM: mvebu: add workaround for SMP support for Armada 375 stepping Z1 Due to internal bootrom issue, CPU[1] initial jump code (four instructions) should be placed in SRAM memory of the SoC. In order to achieve this, we have to unmap the BootROM and at some specific location where the BootROM was place, create a specific MBus window for the SRAM. This SRAM is initialized with a few instructions of code that allows to jump into the real secondary CPU boot address. This workaround will most likely be disabled when newer steppings of the Armada 375 will be made available, in which case a dynamic test based on mvebu-soc-id will be added. Signed-off-by: Gregory CLEMENT Link: https://lkml.kernel.org/r/1397483648-26611-10-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Thomas Petazzoni Link: https://lkml.kernel.org/r/1397483648-26611-10-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper --- arch/arm/mach-mvebu/headsmp-a9.S | 12 ++++++++++++ arch/arm/mach-mvebu/platsmp-a9.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) (limited to 'arch/arm/mach-mvebu/headsmp-a9.S') diff --git a/arch/arm/mach-mvebu/headsmp-a9.S b/arch/arm/mach-mvebu/headsmp-a9.S index 78e66c96e718..5925366bc03c 100644 --- a/arch/arm/mach-mvebu/headsmp-a9.S +++ b/arch/arm/mach-mvebu/headsmp-a9.S @@ -16,6 +16,18 @@ #include __CPUINIT +#define CPU_RESUME_ADDR_REG 0xf10182d4 + +.global armada_375_smp_cpu1_enable_code_start +.global armada_375_smp_cpu1_enable_code_end + +armada_375_smp_cpu1_enable_code_start: + ldr r0, [pc, #4] + ldr r1, [r0] + mov pc, r1 + .word CPU_RESUME_ADDR_REG +armada_375_smp_cpu1_enable_code_end: + ENTRY(mvebu_cortex_a9_secondary_startup) bl v7_invalidate_l1 b secondary_startup diff --git a/arch/arm/mach-mvebu/platsmp-a9.c b/arch/arm/mach-mvebu/platsmp-a9.c index 27dacfc7fe98..04d0b1847c39 100644 --- a/arch/arm/mach-mvebu/platsmp-a9.c +++ b/arch/arm/mach-mvebu/platsmp-a9.c @@ -16,11 +16,36 @@ #include #include #include +#include #include #include #include "common.h" #include "pmsu.h" +#define CRYPT0_ENG_ID 41 +#define CRYPT0_ENG_ATTR 0x1 +#define SRAM_PHYS_BASE 0xFFFF0000 + +#define BOOTROM_BASE 0xFFF00000 +#define BOOTROM_SIZE 0x100000 + +extern unsigned char armada_375_smp_cpu1_enable_code_end; +extern unsigned char armada_375_smp_cpu1_enable_code_start; + +void armada_375_smp_cpu1_enable_wa(void) +{ + void __iomem *sram_virt_base; + + mvebu_mbus_del_window(BOOTROM_BASE, BOOTROM_SIZE); + mvebu_mbus_add_window_by_id(CRYPT0_ENG_ID, CRYPT0_ENG_ATTR, + SRAM_PHYS_BASE, SZ_64K); + sram_virt_base = ioremap(SRAM_PHYS_BASE, SZ_64K); + + memcpy(sram_virt_base, &armada_375_smp_cpu1_enable_code_start, + &armada_375_smp_cpu1_enable_code_end + - &armada_375_smp_cpu1_enable_code_start); +} + extern void mvebu_cortex_a9_secondary_startup(void); static int __cpuinit mvebu_cortex_a9_boot_secondary(unsigned int cpu, @@ -55,7 +80,14 @@ static int __cpuinit mvebu_cortex_a9_boot_secondary(unsigned int cpu, return 0; } +static void __init mvebu_cortex_a9_smp_prepare_cpus(unsigned int max_cpus) +{ + if (of_machine_is_compatible("marvell,armada375")) + armada_375_smp_cpu1_enable_wa(); +} + static struct smp_operations mvebu_cortex_a9_smp_ops __initdata = { + .smp_prepare_cpus = mvebu_cortex_a9_smp_prepare_cpus, .smp_boot_secondary = mvebu_cortex_a9_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU .cpu_die = armada_xp_cpu_die, -- cgit v1.2.3