diff options
Diffstat (limited to 'arch/arm/mach-exynos/mcpm-exynos.c')
-rw-r--r-- | arch/arm/mach-exynos/mcpm-exynos.c | 32 |
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 | ||
34 | static 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 | ||
324 | static 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 | |||
337 | static struct syscore_ops exynos_mcpm_syscore_ops = { | ||
338 | .resume = exynos_mcpm_setup_entry_point, | ||
339 | }; | ||
340 | |||
321 | static int __init exynos_mcpm_init(void) | 341 | static 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 | } |