aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomasz Figa <t.figa@samsung.com>2014-03-17 18:28:27 -0400
committerKukjin Kim <kgene.kim@samsung.com>2014-03-20 15:09:28 -0400
commitd710aa31874e2ff6e656dbd4807f4bd8d659eb93 (patch)
treeb897e022fd8d9579acaabc318a2bffd0c55c1f2e
parent559ba237999d723ccba5b4a75cf6b280bac1ab21 (diff)
ARM: EXYNOS: Stop using legacy Samsung PM code
Since Exynos SoCs does not follow most of the semantics of older SoCs when configuring the system to enter sleep, there is no reason to rely on the legacy Samsung PM core anymore. This patch adds local Exynos suspend ops and removes all the code left unnecessary. As a side effect, suspend support on Exynos becomes multiplatform-friendly. Signed-off-by: Tomasz Figa <t.figa@samsung.com> Acked-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
-rw-r--r--arch/arm/mach-exynos/Kconfig8
-rw-r--r--arch/arm/mach-exynos/Makefile2
-rw-r--r--arch/arm/mach-exynos/common.h8
-rw-r--r--arch/arm/mach-exynos/include/mach/pm-core.h75
-rw-r--r--arch/arm/mach-exynos/pm.c79
-rw-r--r--arch/arm/mach-exynos/regs-pmu.h2
-rw-r--r--arch/arm/mach-exynos/sleep.S85
-rw-r--r--arch/arm/plat-samsung/s5p-sleep.S45
8 files changed, 167 insertions, 137 deletions
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 0964d97c2fa7..fcd78c201c0b 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -49,8 +49,6 @@ config CPU_EXYNOS4210
49 select ARCH_HAS_BANDGAP 49 select ARCH_HAS_BANDGAP
50 select ARM_CPU_SUSPEND if PM_SLEEP 50 select ARM_CPU_SUSPEND if PM_SLEEP
51 select PINCTRL_EXYNOS 51 select PINCTRL_EXYNOS
52 select S5P_PM if PM_SLEEP
53 select S5P_SLEEP if PM_SLEEP
54 select SAMSUNG_DMADEV 52 select SAMSUNG_DMADEV
55 help 53 help
56 Enable EXYNOS4210 CPU support 54 Enable EXYNOS4210 CPU support
@@ -61,8 +59,6 @@ config SOC_EXYNOS4212
61 depends on ARCH_EXYNOS4 59 depends on ARCH_EXYNOS4
62 select ARCH_HAS_BANDGAP 60 select ARCH_HAS_BANDGAP
63 select PINCTRL_EXYNOS 61 select PINCTRL_EXYNOS
64 select S5P_PM if PM_SLEEP
65 select S5P_SLEEP if PM_SLEEP
66 select SAMSUNG_DMADEV 62 select SAMSUNG_DMADEV
67 help 63 help
68 Enable EXYNOS4212 SoC support 64 Enable EXYNOS4212 SoC support
@@ -84,8 +80,6 @@ config SOC_EXYNOS5250
84 select ARCH_HAS_BANDGAP 80 select ARCH_HAS_BANDGAP
85 select PINCTRL_EXYNOS 81 select PINCTRL_EXYNOS
86 select PM_GENERIC_DOMAINS if PM_RUNTIME 82 select PM_GENERIC_DOMAINS if PM_RUNTIME
87 select S5P_PM if PM_SLEEP
88 select S5P_SLEEP if PM_SLEEP
89 select S5P_DEV_MFC 83 select S5P_DEV_MFC
90 select SAMSUNG_DMADEV 84 select SAMSUNG_DMADEV
91 help 85 help
@@ -96,8 +90,6 @@ config SOC_EXYNOS5420
96 default y 90 default y
97 depends on ARCH_EXYNOS5 91 depends on ARCH_EXYNOS5
98 select PM_GENERIC_DOMAINS if PM_RUNTIME 92 select PM_GENERIC_DOMAINS if PM_RUNTIME
99 select S5P_PM if PM_SLEEP
100 select S5P_SLEEP if PM_SLEEP
101 help 93 help
102 Enable EXYNOS5420 SoC support 94 Enable EXYNOS5420 SoC support
103 95
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 8930b66b4abd..58fe9e6f542f 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -14,7 +14,7 @@ obj- :=
14 14
15obj-$(CONFIG_ARCH_EXYNOS) += common.o 15obj-$(CONFIG_ARCH_EXYNOS) += common.o
16 16
17obj-$(CONFIG_S5P_PM) += pm.o 17obj-$(CONFIG_PM_SLEEP) += pm.o sleep.o
18obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o 18obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
19obj-$(CONFIG_CPU_IDLE) += cpuidle.o 19obj-$(CONFIG_CPU_IDLE) += cpuidle.o
20 20
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index 82e08fb83eae..aba6a2ad7d1b 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -27,12 +27,20 @@ void exynos_init_late(void);
27 27
28void exynos_firmware_init(void); 28void exynos_firmware_init(void);
29 29
30#ifdef CONFIG_PINCTRL_EXYNOS
31extern u32 exynos_get_eint_wake_mask(void);
32#else
33static inline u32 exynos_get_eint_wake_mask(void) { return 0xffffffff; }
34#endif
35
30#ifdef CONFIG_PM_SLEEP 36#ifdef CONFIG_PM_SLEEP
31extern void __init exynos_pm_init(void); 37extern void __init exynos_pm_init(void);
32#else 38#else
33static inline void exynos_pm_init(void) {} 39static inline void exynos_pm_init(void) {}
34#endif 40#endif
35 41
42extern void exynos_cpu_resume(void);
43
36extern struct smp_operations exynos_smp_ops; 44extern struct smp_operations exynos_smp_ops;
37 45
38extern void exynos_cpu_die(unsigned int cpu); 46extern void exynos_cpu_die(unsigned int cpu);
diff --git a/arch/arm/mach-exynos/include/mach/pm-core.h b/arch/arm/mach-exynos/include/mach/pm-core.h
deleted file mode 100644
index dc0697c2fa92..000000000000
--- a/arch/arm/mach-exynos/include/mach/pm-core.h
+++ /dev/null
@@ -1,75 +0,0 @@
1/* linux/arch/arm/mach-exynos4/include/mach/pm-core.h
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Based on arch/arm/mach-s3c2410/include/mach/pm-core.h,
7 * Copyright 2008 Simtec Electronics
8 * Ben Dooks <ben@simtec.co.uk>
9 * http://armlinux.simtec.co.uk/
10 *
11 * EXYNOS4210 - PM core support for arch/arm/plat-s5p/pm.c
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16*/
17
18#ifndef __ASM_ARCH_PM_CORE_H
19#define __ASM_ARCH_PM_CORE_H __FILE__
20
21#include <linux/of.h>
22#include <mach/map.h>
23
24#define S5P_EINT_WAKEUP_MASK (S5P_VA_PMU + 0x0604)
25#define S5P_WAKEUP_MASK (S5P_VA_PMU + 0x0608)
26
27#ifdef CONFIG_PINCTRL_EXYNOS
28extern u32 exynos_get_eint_wake_mask(void);
29#else
30static inline u32 exynos_get_eint_wake_mask(void) { return 0xffffffff; }
31#endif
32
33static inline void s3c_pm_debug_init_uart(void)
34{
35 /* nothing here yet */
36}
37
38static inline void s3c_pm_arch_prepare_irqs(void)
39{
40 __raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK);
41 __raw_writel(s3c_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK);
42}
43
44static inline void s3c_pm_arch_stop_clocks(void)
45{
46 /* nothing here yet */
47}
48
49static inline void s3c_pm_arch_show_resume_irqs(void)
50{
51 /* nothing here yet */
52}
53
54static inline void s3c_pm_arch_update_uart(void __iomem *regs,
55 struct pm_uart_save *save)
56{
57 /* nothing here yet */
58}
59
60static inline void s3c_pm_restored_gpios(void)
61{
62 /* nothing here yet */
63}
64
65static inline void samsung_pm_saved_gpios(void)
66{
67 /* nothing here yet */
68}
69
70/* Compatibility definitions to make plat-samsung/pm.c compile */
71#define IRQ_EINT_BIT(x) 1
72#define s3c_irqwake_intallow 0
73#define s3c_irqwake_eintallow 0
74
75#endif /* __ASM_ARCH_PM_CORE_H */
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index 596ed13c4166..ada1c8374b77 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -23,14 +23,14 @@
23#include <asm/cacheflush.h> 23#include <asm/cacheflush.h>
24#include <asm/hardware/cache-l2x0.h> 24#include <asm/hardware/cache-l2x0.h>
25#include <asm/smp_scu.h> 25#include <asm/smp_scu.h>
26#include <asm/suspend.h>
26 27
27#include <plat/cpu.h> 28#include <plat/cpu.h>
28#include <plat/pm.h> 29#include <plat/pm-common.h>
29#include <plat/pll.h> 30#include <plat/pll.h>
30#include <plat/regs-srom.h> 31#include <plat/regs-srom.h>
31 32
32#include <mach/map.h> 33#include <mach/map.h>
33#include <mach/pm-core.h>
34 34
35#include "common.h" 35#include "common.h"
36#include "regs-pmu.h" 36#include "regs-pmu.h"
@@ -48,6 +48,7 @@ static struct sleep_save exynos_core_save[] = {
48 SAVE_ITEM(S5P_SROM_BC3), 48 SAVE_ITEM(S5P_SROM_BC3),
49}; 49};
50 50
51static u32 exynos_irqwake_intmask = 0xffffffff;
51 52
52/* For Cortex-A9 Diagnostic and Power control register */ 53/* For Cortex-A9 Diagnostic and Power control register */
53static unsigned int save_arm_register[2]; 54static unsigned int save_arm_register[2];
@@ -72,6 +73,10 @@ static void exynos_pm_prepare(void)
72{ 73{
73 unsigned int tmp; 74 unsigned int tmp;
74 75
76 /* Set wake-up mask registers */
77 __raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK);
78 __raw_writel(exynos_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK);
79
75 s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save)); 80 s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
76 81
77 if (soc_is_exynos5250()) { 82 if (soc_is_exynos5250()) {
@@ -89,7 +94,7 @@ static void exynos_pm_prepare(void)
89 94
90 /* ensure at least INFORM0 has the resume address */ 95 /* ensure at least INFORM0 has the resume address */
91 96
92 __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0); 97 __raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
93} 98}
94 99
95static int exynos_pm_suspend(void) 100static int exynos_pm_suspend(void)
@@ -187,14 +192,71 @@ static struct syscore_ops exynos_pm_syscore_ops = {
187 .resume = exynos_pm_resume, 192 .resume = exynos_pm_resume,
188}; 193};
189 194
190void __init exynos_pm_init(void) 195/*
196 * Suspend Ops
197 */
198
199static int exynos_suspend_enter(suspend_state_t state)
191{ 200{
192 u32 tmp; 201 int ret;
202
203 s3c_pm_debug_init();
204
205 S3C_PMDBG("%s: suspending the system...\n", __func__);
206
207 S3C_PMDBG("%s: wakeup masks: %08x,%08x\n", __func__,
208 exynos_irqwake_intmask, exynos_get_eint_wake_mask());
193 209
194 pm_cpu_prep = exynos_pm_prepare; 210 if (exynos_irqwake_intmask == -1U
195 pm_cpu_sleep = exynos_cpu_suspend; 211 && exynos_get_eint_wake_mask() == -1U) {
212 pr_err("%s: No wake-up sources!\n", __func__);
213 pr_err("%s: Aborting sleep\n", __func__);
214 return -EINVAL;
215 }
216
217 s3c_pm_save_uarts();
218 exynos_pm_prepare();
219 flush_cache_all();
220 s3c_pm_check_store();
221
222 ret = cpu_suspend(0, exynos_cpu_suspend);
223 if (ret)
224 return ret;
225
226 s3c_pm_restore_uarts();
196 227
197 s3c_pm_init(); 228 S3C_PMDBG("%s: wakeup stat: %08x\n", __func__,
229 __raw_readl(S5P_WAKEUP_STAT));
230
231 s3c_pm_check_restore();
232
233 S3C_PMDBG("%s: resuming the system...\n", __func__);
234
235 return 0;
236}
237
238static int exynos_suspend_prepare(void)
239{
240 s3c_pm_check_prepare();
241
242 return 0;
243}
244
245static void exynos_suspend_finish(void)
246{
247 s3c_pm_check_cleanup();
248}
249
250static const struct platform_suspend_ops exynos_suspend_ops = {
251 .enter = exynos_suspend_enter,
252 .prepare = exynos_suspend_prepare,
253 .finish = exynos_suspend_finish,
254 .valid = suspend_valid_only_mem,
255};
256
257void __init exynos_pm_init(void)
258{
259 u32 tmp;
198 260
199 /* All wakeup disable */ 261 /* All wakeup disable */
200 tmp = __raw_readl(S5P_WAKEUP_MASK); 262 tmp = __raw_readl(S5P_WAKEUP_MASK);
@@ -202,4 +264,5 @@ void __init exynos_pm_init(void)
202 __raw_writel(tmp, S5P_WAKEUP_MASK); 264 __raw_writel(tmp, S5P_WAKEUP_MASK);
203 265
204 register_syscore_ops(&exynos_pm_syscore_ops); 266 register_syscore_ops(&exynos_pm_syscore_ops);
267 suspend_set_ops(&exynos_suspend_ops);
205} 268}
diff --git a/arch/arm/mach-exynos/regs-pmu.h b/arch/arm/mach-exynos/regs-pmu.h
index 7c029ce27711..2c15a8fbcb5a 100644
--- a/arch/arm/mach-exynos/regs-pmu.h
+++ b/arch/arm/mach-exynos/regs-pmu.h
@@ -31,6 +31,8 @@
31#define EXYNOS5440_SWRESET S5P_PMUREG(0x00C4) 31#define EXYNOS5440_SWRESET S5P_PMUREG(0x00C4)
32 32
33#define S5P_WAKEUP_STAT S5P_PMUREG(0x0600) 33#define S5P_WAKEUP_STAT S5P_PMUREG(0x0600)
34#define S5P_EINT_WAKEUP_MASK S5P_PMUREG(0x0604)
35#define S5P_WAKEUP_MASK S5P_PMUREG(0x0608)
34 36
35#define S5P_INFORM0 S5P_PMUREG(0x0800) 37#define S5P_INFORM0 S5P_PMUREG(0x0800)
36#define S5P_INFORM1 S5P_PMUREG(0x0804) 38#define S5P_INFORM1 S5P_PMUREG(0x0804)
diff --git a/arch/arm/mach-exynos/sleep.S b/arch/arm/mach-exynos/sleep.S
new file mode 100644
index 000000000000..a2613e944e10
--- /dev/null
+++ b/arch/arm/mach-exynos/sleep.S
@@ -0,0 +1,85 @@
1/*
2 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com
4 *
5 * Exynos low-level resume code
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/linkage.h>
19#include <asm/asm-offsets.h>
20#include <asm/hardware/cache-l2x0.h>
21
22#define CPU_MASK 0xff0ffff0
23#define CPU_CORTEX_A9 0x410fc090
24
25 /*
26 * The following code is located into the .data section. This is to
27 * allow l2x0_regs_phys to be accessed with a relative load while we
28 * can't rely on any MMU translation. We could have put l2x0_regs_phys
29 * in the .text section as well, but some setups might insist on it to
30 * be truly read-only. (Reference from: arch/arm/kernel/sleep.S)
31 */
32 .data
33 .align
34
35 /*
36 * sleep magic, to allow the bootloader to check for an valid
37 * image to resume to. Must be the first word before the
38 * exynos_cpu_resume entry.
39 */
40
41 .word 0x2bedf00d
42
43 /*
44 * exynos_cpu_resume
45 *
46 * resume code entry for bootloader to call
47 */
48
49ENTRY(exynos_cpu_resume)
50#ifdef CONFIG_CACHE_L2X0
51 mrc p15, 0, r0, c0, c0, 0
52 ldr r1, =CPU_MASK
53 and r0, r0, r1
54 ldr r1, =CPU_CORTEX_A9
55 cmp r0, r1
56 bne skip_l2_resume
57 adr r0, l2x0_regs_phys
58 ldr r0, [r0]
59 cmp r0, #0
60 beq skip_l2_resume
61 ldr r1, [r0, #L2X0_R_PHY_BASE]
62 ldr r2, [r1, #L2X0_CTRL]
63 tst r2, #0x1
64 bne skip_l2_resume
65 ldr r2, [r0, #L2X0_R_AUX_CTRL]
66 str r2, [r1, #L2X0_AUX_CTRL]
67 ldr r2, [r0, #L2X0_R_TAG_LATENCY]
68 str r2, [r1, #L2X0_TAG_LATENCY_CTRL]
69 ldr r2, [r0, #L2X0_R_DATA_LATENCY]
70 str r2, [r1, #L2X0_DATA_LATENCY_CTRL]
71 ldr r2, [r0, #L2X0_R_PREFETCH_CTRL]
72 str r2, [r1, #L2X0_PREFETCH_CTRL]
73 ldr r2, [r0, #L2X0_R_PWR_CTRL]
74 str r2, [r1, #L2X0_POWER_CTRL]
75 mov r2, #1
76 str r2, [r1, #L2X0_CTRL]
77skip_l2_resume:
78#endif
79 b cpu_resume
80ENDPROC(exynos_cpu_resume)
81#ifdef CONFIG_CACHE_L2X0
82 .globl l2x0_regs_phys
83l2x0_regs_phys:
84 .long 0
85#endif
diff --git a/arch/arm/plat-samsung/s5p-sleep.S b/arch/arm/plat-samsung/s5p-sleep.S
index 20764bd5518e..c5001659bdf8 100644
--- a/arch/arm/plat-samsung/s5p-sleep.S
+++ b/arch/arm/plat-samsung/s5p-sleep.S
@@ -23,18 +23,7 @@
23 23
24#include <linux/linkage.h> 24#include <linux/linkage.h>
25#include <asm/asm-offsets.h> 25#include <asm/asm-offsets.h>
26#include <asm/hardware/cache-l2x0.h>
27 26
28#define CPU_MASK 0xff0ffff0
29#define CPU_CORTEX_A9 0x410fc090
30
31/*
32 * The following code is located into the .data section. This is to
33 * allow l2x0_regs_phys to be accessed with a relative load while we
34 * can't rely on any MMU translation. We could have put l2x0_regs_phys
35 * in the .text section as well, but some setups might insist on it to
36 * be truly read-only. (Reference from: arch/arm/kernel/sleep.S)
37 */
38 .data 27 .data
39 .align 28 .align
40 29
@@ -53,39 +42,5 @@
53 */ 42 */
54 43
55ENTRY(s3c_cpu_resume) 44ENTRY(s3c_cpu_resume)
56#ifdef CONFIG_CACHE_L2X0
57 mrc p15, 0, r0, c0, c0, 0
58 ldr r1, =CPU_MASK
59 and r0, r0, r1
60 ldr r1, =CPU_CORTEX_A9
61 cmp r0, r1
62 bne skip_l2_resume
63 adr r0, l2x0_regs_phys
64 ldr r0, [r0]
65 cmp r0, #0
66 beq skip_l2_resume
67 ldr r1, [r0, #L2X0_R_PHY_BASE]
68 ldr r2, [r1, #L2X0_CTRL]
69 tst r2, #0x1
70 bne skip_l2_resume
71 ldr r2, [r0, #L2X0_R_AUX_CTRL]
72 str r2, [r1, #L2X0_AUX_CTRL]
73 ldr r2, [r0, #L2X0_R_TAG_LATENCY]
74 str r2, [r1, #L2X0_TAG_LATENCY_CTRL]
75 ldr r2, [r0, #L2X0_R_DATA_LATENCY]
76 str r2, [r1, #L2X0_DATA_LATENCY_CTRL]
77 ldr r2, [r0, #L2X0_R_PREFETCH_CTRL]
78 str r2, [r1, #L2X0_PREFETCH_CTRL]
79 ldr r2, [r0, #L2X0_R_PWR_CTRL]
80 str r2, [r1, #L2X0_POWER_CTRL]
81 mov r2, #1
82 str r2, [r1, #L2X0_CTRL]
83skip_l2_resume:
84#endif
85 b cpu_resume 45 b cpu_resume
86ENDPROC(s3c_cpu_resume) 46ENDPROC(s3c_cpu_resume)
87#ifdef CONFIG_CACHE_L2X0
88 .globl l2x0_regs_phys
89l2x0_regs_phys:
90 .long 0
91#endif