aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos/mcpm-exynos.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-exynos/mcpm-exynos.c')
-rw-r--r--arch/arm/mach-exynos/mcpm-exynos.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c
index dc9a764a7c37..b0d3c2e876fb 100644
--- a/arch/arm/mach-exynos/mcpm-exynos.c
+++ b/arch/arm/mach-exynos/mcpm-exynos.c
@@ -15,6 +15,7 @@
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/of_address.h> 17#include <linux/of_address.h>
18#include <linux/syscore_ops.h>
18 19
19#include <asm/cputype.h> 20#include <asm/cputype.h>
20#include <asm/cp15.h> 21#include <asm/cp15.h>
@@ -30,6 +31,8 @@
30#define EXYNOS5420_USE_ARM_CORE_DOWN_STATE BIT(29) 31#define EXYNOS5420_USE_ARM_CORE_DOWN_STATE BIT(29)
31#define EXYNOS5420_USE_L2_COMMON_UP_STATE BIT(30) 32#define EXYNOS5420_USE_L2_COMMON_UP_STATE BIT(30)
32 33
34static void __iomem *ns_sram_base_addr;
35
33/* 36/*
34 * The common v7_exit_coherency_flush API could not be used because of the 37 * The common v7_exit_coherency_flush API could not be used because of the
35 * Erratum 799270 workaround. This macro is the same as the common one (in 38 * Erratum 799270 workaround. This macro is the same as the common one (in
@@ -318,10 +321,26 @@ static const struct of_device_id exynos_dt_mcpm_match[] = {
318 {}, 321 {},
319}; 322};
320 323
324static void exynos_mcpm_setup_entry_point(void)
325{
326 /*
327 * U-Boot SPL is hardcoded to jump to the start of ns_sram_base_addr
328 * as part of secondary_cpu_start(). Let's redirect it to the
329 * mcpm_entry_point(). This is done during both secondary boot-up as
330 * well as system resume.
331 */
332 __raw_writel(0xe59f0000, ns_sram_base_addr); /* ldr r0, [pc, #0] */
333 __raw_writel(0xe12fff10, ns_sram_base_addr + 4); /* bx r0 */
334 __raw_writel(virt_to_phys(mcpm_entry_point), ns_sram_base_addr + 8);
335}
336
337static struct syscore_ops exynos_mcpm_syscore_ops = {
338 .resume = exynos_mcpm_setup_entry_point,
339};
340
321static int __init exynos_mcpm_init(void) 341static int __init exynos_mcpm_init(void)
322{ 342{
323 struct device_node *node; 343 struct device_node *node;
324 void __iomem *ns_sram_base_addr;
325 unsigned int value, i; 344 unsigned int value, i;
326 int ret; 345 int ret;
327 346
@@ -387,16 +406,9 @@ static int __init exynos_mcpm_init(void)
387 pmu_raw_writel(value, EXYNOS_COMMON_OPTION(i)); 406 pmu_raw_writel(value, EXYNOS_COMMON_OPTION(i));
388 } 407 }
389 408
390 /* 409 exynos_mcpm_setup_entry_point();
391 * U-Boot SPL is hardcoded to jump to the start of ns_sram_base_addr
392 * as part of secondary_cpu_start(). Let's redirect it to the
393 * mcpm_entry_point().
394 */
395 __raw_writel(0xe59f0000, ns_sram_base_addr); /* ldr r0, [pc, #0] */
396 __raw_writel(0xe12fff10, ns_sram_base_addr + 4); /* bx r0 */
397 __raw_writel(virt_to_phys(mcpm_entry_point), ns_sram_base_addr + 8);
398 410
399 iounmap(ns_sram_base_addr); 411 register_syscore_ops(&exynos_mcpm_syscore_ops);
400 412
401 return ret; 413 return ret;
402} 414}