diff options
| -rw-r--r-- | arch/arm/mach-socfpga/core.h | 2 | ||||
| -rw-r--r-- | arch/arm/mach-socfpga/headsmp.S | 25 | ||||
| -rw-r--r-- | arch/arm/mach-socfpga/platsmp.c | 4 | ||||
| -rw-r--r-- | arch/arm/mach-socfpga/socfpga.c | 4 |
4 files changed, 20 insertions, 15 deletions
diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h index 572b8f719ffb..60c443dadb58 100644 --- a/arch/arm/mach-socfpga/core.h +++ b/arch/arm/mach-socfpga/core.h | |||
| @@ -40,7 +40,7 @@ extern void __iomem *rst_manager_base_addr; | |||
| 40 | extern struct smp_operations socfpga_smp_ops; | 40 | extern struct smp_operations socfpga_smp_ops; |
| 41 | extern char secondary_trampoline, secondary_trampoline_end; | 41 | extern char secondary_trampoline, secondary_trampoline_end; |
| 42 | 42 | ||
| 43 | extern unsigned long cpu1start_addr; | 43 | extern unsigned long socfpga_cpu1start_addr; |
| 44 | 44 | ||
| 45 | #define SOCFPGA_SCU_VIRT_BASE 0xfffec000 | 45 | #define SOCFPGA_SCU_VIRT_BASE 0xfffec000 |
| 46 | 46 | ||
diff --git a/arch/arm/mach-socfpga/headsmp.S b/arch/arm/mach-socfpga/headsmp.S index 95c115d8b5ee..f65ea0af4af3 100644 --- a/arch/arm/mach-socfpga/headsmp.S +++ b/arch/arm/mach-socfpga/headsmp.S | |||
| @@ -9,21 +9,26 @@ | |||
| 9 | */ | 9 | */ |
| 10 | #include <linux/linkage.h> | 10 | #include <linux/linkage.h> |
| 11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
| 12 | #include <asm/memory.h> | ||
| 12 | 13 | ||
| 13 | .arch armv7-a | 14 | .arch armv7-a |
| 14 | 15 | ||
| 15 | ENTRY(secondary_trampoline) | 16 | ENTRY(secondary_trampoline) |
| 16 | movw r2, #:lower16:cpu1start_addr | 17 | /* CPU1 will always fetch from 0x0 when it is brought out of reset. |
| 17 | movt r2, #:upper16:cpu1start_addr | 18 | * Thus, we can just subtract the PAGE_OFFSET to get the physical |
| 18 | 19 | * address of &cpu1start_addr. This would not work for platforms | |
| 19 | /* The socfpga VT cannot handle a 0xC0000000 page offset when loading | 20 | * where the physical memory does not start at 0x0. |
| 20 | the cpu1start_addr, we bit clear it. Tested on HW and VT. */ | 21 | */ |
| 21 | bic r2, r2, #0x40000000 | 22 | adr r0, 1f |
| 22 | 23 | ldmia r0, {r1, r2} | |
| 23 | ldr r0, [r2] | 24 | sub r2, r2, #PAGE_OFFSET |
| 24 | ldr r1, [r0] | 25 | ldr r3, [r2] |
| 25 | bx r1 | 26 | ldr r4, [r3] |
| 27 | bx r4 | ||
| 26 | 28 | ||
| 29 | .align | ||
| 30 | 1: .long . | ||
| 31 | .long socfpga_cpu1start_addr | ||
| 27 | ENTRY(secondary_trampoline_end) | 32 | ENTRY(secondary_trampoline_end) |
| 28 | 33 | ||
| 29 | ENTRY(socfpga_secondary_startup) | 34 | ENTRY(socfpga_secondary_startup) |
diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c index 5356a72bc8ce..16ca97b039f9 100644 --- a/arch/arm/mach-socfpga/platsmp.c +++ b/arch/arm/mach-socfpga/platsmp.c | |||
| @@ -33,11 +33,11 @@ static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
| 33 | { | 33 | { |
| 34 | int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; | 34 | int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; |
| 35 | 35 | ||
| 36 | if (cpu1start_addr) { | 36 | if (socfpga_cpu1start_addr) { |
| 37 | memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); | 37 | memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); |
| 38 | 38 | ||
| 39 | __raw_writel(virt_to_phys(socfpga_secondary_startup), | 39 | __raw_writel(virt_to_phys(socfpga_secondary_startup), |
| 40 | (sys_manager_base_addr + (cpu1start_addr & 0x000000ff))); | 40 | (sys_manager_base_addr + (socfpga_cpu1start_addr & 0x000000ff))); |
| 41 | 41 | ||
| 42 | flush_cache_all(); | 42 | flush_cache_all(); |
| 43 | smp_wmb(); | 43 | smp_wmb(); |
diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c index adbf38314ca8..383d61e138af 100644 --- a/arch/arm/mach-socfpga/socfpga.c +++ b/arch/arm/mach-socfpga/socfpga.c | |||
| @@ -29,7 +29,7 @@ | |||
| 29 | void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE)); | 29 | void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE)); |
| 30 | void __iomem *sys_manager_base_addr; | 30 | void __iomem *sys_manager_base_addr; |
| 31 | void __iomem *rst_manager_base_addr; | 31 | void __iomem *rst_manager_base_addr; |
| 32 | unsigned long cpu1start_addr; | 32 | unsigned long socfpga_cpu1start_addr; |
| 33 | 33 | ||
| 34 | static struct map_desc scu_io_desc __initdata = { | 34 | static struct map_desc scu_io_desc __initdata = { |
| 35 | .virtual = SOCFPGA_SCU_VIRT_BASE, | 35 | .virtual = SOCFPGA_SCU_VIRT_BASE, |
| @@ -70,7 +70,7 @@ void __init socfpga_sysmgr_init(void) | |||
| 70 | np = of_find_compatible_node(NULL, NULL, "altr,sys-mgr"); | 70 | np = of_find_compatible_node(NULL, NULL, "altr,sys-mgr"); |
| 71 | 71 | ||
| 72 | if (of_property_read_u32(np, "cpu1-start-addr", | 72 | if (of_property_read_u32(np, "cpu1-start-addr", |
| 73 | (u32 *) &cpu1start_addr)) | 73 | (u32 *) &socfpga_cpu1start_addr)) |
| 74 | pr_err("SMP: Need cpu1-start-addr in device tree.\n"); | 74 | pr_err("SMP: Need cpu1-start-addr in device tree.\n"); |
| 75 | 75 | ||
| 76 | sys_manager_base_addr = of_iomap(np, 0); | 76 | sys_manager_base_addr = of_iomap(np, 0); |
