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 --- |