platsmp.c (191a66353b22fad8ac89404ab4c929cbe7b0afb2) platsmp.c (6f024978e74bda616b27183adee029b65eb27032)
1 /*
2 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com
4 *
5 * Cloned from linux/arch/arm/mach-vexpress/platsmp.c
6 *
7 * Copyright (C) 2002 ARM Ltd.
8 * All Rights Reserved

--- 20 unchanged lines hidden (view full) ---

29
30#include <mach/map.h>
31
32#include "common.h"
33#include "regs-pmu.h"
34
35extern void exynos4_secondary_startup(void);
36
1 /*
2 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com
4 *
5 * Cloned from linux/arch/arm/mach-vexpress/platsmp.c
6 *
7 * Copyright (C) 2002 ARM Ltd.
8 * All Rights Reserved

--- 20 unchanged lines hidden (view full) ---

29
30#include <mach/map.h>
31
32#include "common.h"
33#include "regs-pmu.h"
34
35extern void exynos4_secondary_startup(void);
36
37/*
38 * Set or clear the USE_DELAYED_RESET_ASSERTION option, set on Exynos4 SoCs
39 * during hot-(un)plugging CPUx.
40 *
41 * The feature can be cleared safely during first boot of secondary CPU.
42 *
43 * Exynos4 SoCs require setting USE_DELAYED_RESET_ASSERTION during powering
44 * down a CPU so the CPU idle clock down feature could properly detect global
45 * idle state when CPUx is off.
46 */
47static void exynos_set_delayed_reset_assertion(u32 core_id, bool enable)
48{
49 if (soc_is_exynos4()) {
50 unsigned int tmp;
51
52 tmp = pmu_raw_readl(EXYNOS_ARM_CORE_OPTION(core_id));
53 if (enable)
54 tmp |= S5P_USE_DELAYED_RESET_ASSERTION;
55 else
56 tmp &= ~(S5P_USE_DELAYED_RESET_ASSERTION);
57 pmu_raw_writel(tmp, EXYNOS_ARM_CORE_OPTION(core_id));
58 }
59}
60
61#ifdef CONFIG_HOTPLUG_CPU
62static inline void cpu_leave_lowpower(u32 core_id)
63{
64 unsigned int v;
65
66 asm volatile(
67 "mrc p15, 0, %0, c1, c0, 0\n"
68 " orr %0, %0, %1\n"
69 " mcr p15, 0, %0, c1, c0, 0\n"
70 " mrc p15, 0, %0, c1, c0, 1\n"
71 " orr %0, %0, %2\n"
72 " mcr p15, 0, %0, c1, c0, 1\n"
73 : "=&r" (v)
74 : "Ir" (CR_C), "Ir" (0x40)
75 : "cc");
37#ifdef CONFIG_HOTPLUG_CPU
38static inline void cpu_leave_lowpower(u32 core_id)
39{
40 unsigned int v;
41
42 asm volatile(
43 "mrc p15, 0, %0, c1, c0, 0\n"
44 " orr %0, %0, %1\n"
45 " mcr p15, 0, %0, c1, c0, 0\n"
46 " mrc p15, 0, %0, c1, c0, 1\n"
47 " orr %0, %0, %2\n"
48 " mcr p15, 0, %0, c1, c0, 1\n"
49 : "=&r" (v)
50 : "Ir" (CR_C), "Ir" (0x40)
51 : "cc");
76
77 exynos_set_delayed_reset_assertion(core_id, false);
78}
79
80static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
81{
82 u32 mpidr = cpu_logical_map(cpu);
83 u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
84
85 for (;;) {
86
87 /* Turn the CPU off on next WFI instruction. */
88 exynos_cpu_power_down(core_id);
89
52}
53
54static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
55{
56 u32 mpidr = cpu_logical_map(cpu);
57 u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
58
59 for (;;) {
60
61 /* Turn the CPU off on next WFI instruction. */
62 exynos_cpu_power_down(core_id);
63
90 /*
91 * Exynos4 SoCs require setting
92 * USE_DELAYED_RESET_ASSERTION so the CPU idle
93 * clock down feature could properly detect
94 * global idle state when CPUx is off.
95 */
96 exynos_set_delayed_reset_assertion(core_id, true);
97
98 wfi();
99
100 if (pen_release == core_id) {
101 /*
102 * OK, proper wakeup, we're done
103 */
104 break;
105 }

--- 260 unchanged lines hidden (view full) ---

366 arch_send_wakeup_ipi_mask(cpumask_of(cpu));
367
368 if (pen_release == -1)
369 break;
370
371 udelay(10);
372 }
373
64 wfi();
65
66 if (pen_release == core_id) {
67 /*
68 * OK, proper wakeup, we're done
69 */
70 break;
71 }

--- 260 unchanged lines hidden (view full) ---

332 arch_send_wakeup_ipi_mask(cpumask_of(cpu));
333
334 if (pen_release == -1)
335 break;
336
337 udelay(10);
338 }
339
374 /* No harm if this is called during first boot of secondary CPU */
375 exynos_set_delayed_reset_assertion(core_id, false);
376
377 /*
378 * now the secondary core is starting up let it run its
379 * calibrations, then wait for it to finish
380 */
381fail:
382 spin_unlock(&boot_lock);
383
384 return pen_release != -1 ? ret : 0;

--- 30 unchanged lines hidden (view full) ---

415}
416
417static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
418{
419 int i;
420
421 exynos_sysram_init();
422
340 /*
341 * now the secondary core is starting up let it run its
342 * calibrations, then wait for it to finish
343 */
344fail:
345 spin_unlock(&boot_lock);
346
347 return pen_release != -1 ? ret : 0;

--- 30 unchanged lines hidden (view full) ---

378}
379
380static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
381{
382 int i;
383
384 exynos_sysram_init();
385
386 exynos_set_delayed_reset_assertion(true);
387
423 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
424 scu_enable(scu_base_addr());
425
426 /*
427 * Write the address of secondary startup into the
428 * system-wide flags register. The boot monitor waits
429 * until it receives a soft interrupt, and then the
430 * secondary CPU branches to this address.

--- 63 unchanged lines hidden ---
388 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
389 scu_enable(scu_base_addr());
390
391 /*
392 * Write the address of secondary startup into the
393 * system-wide flags register. The boot monitor waits
394 * until it receives a soft interrupt, and then the
395 * secondary CPU branches to this address.

--- 63 unchanged lines hidden ---