aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorGregory CLEMENT <gregory.clement@free-electrons.com>2014-04-14 09:54:06 -0400
committerJason Cooper <jason@lakedaemon.net>2014-05-08 12:08:30 -0400
commit87384cc0b4bffbe26d9172d49d8b287332e9d397 (patch)
treef7ec16c6826131eea6bfd8016895dfec80860c61 /arch/arm
parent1ee89e2231a1b04dc34765edd195725ddf4ba998 (diff)
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 <gregory.clement@free-electrons.com> Link: https://lkml.kernel.org/r/1397483648-26611-10-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Link: https://lkml.kernel.org/r/1397483648-26611-10-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-mvebu/headsmp-a9.S12
-rw-r--r--arch/arm/mach-mvebu/platsmp-a9.c32
2 files changed, 44 insertions, 0 deletions
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 @@
16#include <linux/init.h> 16#include <linux/init.h>
17 17
18 __CPUINIT 18 __CPUINIT
19#define CPU_RESUME_ADDR_REG 0xf10182d4
20
21.global armada_375_smp_cpu1_enable_code_start
22.global armada_375_smp_cpu1_enable_code_end
23
24armada_375_smp_cpu1_enable_code_start:
25 ldr r0, [pc, #4]
26 ldr r1, [r0]
27 mov pc, r1
28 .word CPU_RESUME_ADDR_REG
29armada_375_smp_cpu1_enable_code_end:
30
19ENTRY(mvebu_cortex_a9_secondary_startup) 31ENTRY(mvebu_cortex_a9_secondary_startup)
20 bl v7_invalidate_l1 32 bl v7_invalidate_l1
21 b secondary_startup 33 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 @@
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/of.h> 17#include <linux/of.h>
18#include <linux/smp.h> 18#include <linux/smp.h>
19#include <linux/mbus.h>
19#include <asm/smp_scu.h> 20#include <asm/smp_scu.h>
20#include <asm/smp_plat.h> 21#include <asm/smp_plat.h>
21#include "common.h" 22#include "common.h"
22#include "pmsu.h" 23#include "pmsu.h"
23 24
25#define CRYPT0_ENG_ID 41
26#define CRYPT0_ENG_ATTR 0x1
27#define SRAM_PHYS_BASE 0xFFFF0000
28
29#define BOOTROM_BASE 0xFFF00000
30#define BOOTROM_SIZE 0x100000
31
32extern unsigned char armada_375_smp_cpu1_enable_code_end;
33extern unsigned char armada_375_smp_cpu1_enable_code_start;
34
35void armada_375_smp_cpu1_enable_wa(void)
36{
37 void __iomem *sram_virt_base;
38
39 mvebu_mbus_del_window(BOOTROM_BASE, BOOTROM_SIZE);
40 mvebu_mbus_add_window_by_id(CRYPT0_ENG_ID, CRYPT0_ENG_ATTR,
41 SRAM_PHYS_BASE, SZ_64K);
42 sram_virt_base = ioremap(SRAM_PHYS_BASE, SZ_64K);
43
44 memcpy(sram_virt_base, &armada_375_smp_cpu1_enable_code_start,
45 &armada_375_smp_cpu1_enable_code_end
46 - &armada_375_smp_cpu1_enable_code_start);
47}
48
24extern void mvebu_cortex_a9_secondary_startup(void); 49extern void mvebu_cortex_a9_secondary_startup(void);
25 50
26static int __cpuinit mvebu_cortex_a9_boot_secondary(unsigned int cpu, 51static 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,
55 return 0; 80 return 0;
56} 81}
57 82
83static void __init mvebu_cortex_a9_smp_prepare_cpus(unsigned int max_cpus)
84{
85 if (of_machine_is_compatible("marvell,armada375"))
86 armada_375_smp_cpu1_enable_wa();
87}
88
58static struct smp_operations mvebu_cortex_a9_smp_ops __initdata = { 89static struct smp_operations mvebu_cortex_a9_smp_ops __initdata = {
90 .smp_prepare_cpus = mvebu_cortex_a9_smp_prepare_cpus,
59 .smp_boot_secondary = mvebu_cortex_a9_boot_secondary, 91 .smp_boot_secondary = mvebu_cortex_a9_boot_secondary,
60#ifdef CONFIG_HOTPLUG_CPU 92#ifdef CONFIG_HOTPLUG_CPU
61 .cpu_die = armada_xp_cpu_die, 93 .cpu_die = armada_xp_cpu_die,