diff options
Diffstat (limited to 'arch/arm/mach-exynos/pm.c')
-rw-r--r-- | arch/arm/mach-exynos/pm.c | 148 |
1 files changed, 2 insertions, 146 deletions
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index e00025bbbe89..ba18214c9aca 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c | |||
@@ -35,56 +35,6 @@ | |||
35 | #include "common.h" | 35 | #include "common.h" |
36 | #include "regs-pmu.h" | 36 | #include "regs-pmu.h" |
37 | 37 | ||
38 | #define EXYNOS4_EPLL_LOCK (S5P_VA_CMU + 0x0C010) | ||
39 | #define EXYNOS4_VPLL_LOCK (S5P_VA_CMU + 0x0C020) | ||
40 | |||
41 | #define EXYNOS4_EPLL_CON0 (S5P_VA_CMU + 0x0C110) | ||
42 | #define EXYNOS4_EPLL_CON1 (S5P_VA_CMU + 0x0C114) | ||
43 | #define EXYNOS4_VPLL_CON0 (S5P_VA_CMU + 0x0C120) | ||
44 | #define EXYNOS4_VPLL_CON1 (S5P_VA_CMU + 0x0C124) | ||
45 | |||
46 | #define EXYNOS4_CLKSRC_MASK_TOP (S5P_VA_CMU + 0x0C310) | ||
47 | #define EXYNOS4_CLKSRC_MASK_CAM (S5P_VA_CMU + 0x0C320) | ||
48 | #define EXYNOS4_CLKSRC_MASK_TV (S5P_VA_CMU + 0x0C324) | ||
49 | #define EXYNOS4_CLKSRC_MASK_LCD0 (S5P_VA_CMU + 0x0C334) | ||
50 | #define EXYNOS4_CLKSRC_MASK_MAUDIO (S5P_VA_CMU + 0x0C33C) | ||
51 | #define EXYNOS4_CLKSRC_MASK_FSYS (S5P_VA_CMU + 0x0C340) | ||
52 | #define EXYNOS4_CLKSRC_MASK_PERIL0 (S5P_VA_CMU + 0x0C350) | ||
53 | #define EXYNOS4_CLKSRC_MASK_PERIL1 (S5P_VA_CMU + 0x0C354) | ||
54 | |||
55 | #define EXYNOS4_CLKSRC_MASK_DMC (S5P_VA_CMU + 0x10300) | ||
56 | |||
57 | #define EXYNOS4_EPLLCON0_LOCKED_SHIFT (29) | ||
58 | #define EXYNOS4_VPLLCON0_LOCKED_SHIFT (29) | ||
59 | |||
60 | #define EXYNOS4210_CLKSRC_MASK_LCD1 (S5P_VA_CMU + 0x0C338) | ||
61 | |||
62 | static const struct sleep_save exynos4_set_clksrc[] = { | ||
63 | { .reg = EXYNOS4_CLKSRC_MASK_TOP , .val = 0x00000001, }, | ||
64 | { .reg = EXYNOS4_CLKSRC_MASK_CAM , .val = 0x11111111, }, | ||
65 | { .reg = EXYNOS4_CLKSRC_MASK_TV , .val = 0x00000111, }, | ||
66 | { .reg = EXYNOS4_CLKSRC_MASK_LCD0 , .val = 0x00001111, }, | ||
67 | { .reg = EXYNOS4_CLKSRC_MASK_MAUDIO , .val = 0x00000001, }, | ||
68 | { .reg = EXYNOS4_CLKSRC_MASK_FSYS , .val = 0x01011111, }, | ||
69 | { .reg = EXYNOS4_CLKSRC_MASK_PERIL0 , .val = 0x01111111, }, | ||
70 | { .reg = EXYNOS4_CLKSRC_MASK_PERIL1 , .val = 0x01110111, }, | ||
71 | { .reg = EXYNOS4_CLKSRC_MASK_DMC , .val = 0x00010000, }, | ||
72 | }; | ||
73 | |||
74 | static const struct sleep_save exynos4210_set_clksrc[] = { | ||
75 | { .reg = EXYNOS4210_CLKSRC_MASK_LCD1 , .val = 0x00001111, }, | ||
76 | }; | ||
77 | |||
78 | static struct sleep_save exynos4_epll_save[] = { | ||
79 | SAVE_ITEM(EXYNOS4_EPLL_CON0), | ||
80 | SAVE_ITEM(EXYNOS4_EPLL_CON1), | ||
81 | }; | ||
82 | |||
83 | static struct sleep_save exynos4_vpll_save[] = { | ||
84 | SAVE_ITEM(EXYNOS4_VPLL_CON0), | ||
85 | SAVE_ITEM(EXYNOS4_VPLL_CON1), | ||
86 | }; | ||
87 | |||
88 | static struct sleep_save exynos5_sys_save[] = { | 38 | static struct sleep_save exynos5_sys_save[] = { |
89 | SAVE_ITEM(EXYNOS5_SYS_I2C_CFG), | 39 | SAVE_ITEM(EXYNOS5_SYS_I2C_CFG), |
90 | }; | 40 | }; |
@@ -124,10 +74,7 @@ static void exynos_pm_prepare(void) | |||
124 | 74 | ||
125 | s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save)); | 75 | s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save)); |
126 | 76 | ||
127 | if (!soc_is_exynos5250()) { | 77 | if (soc_is_exynos5250()) { |
128 | s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save)); | ||
129 | s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save)); | ||
130 | } else { | ||
131 | s3c_pm_do_save(exynos5_sys_save, ARRAY_SIZE(exynos5_sys_save)); | 78 | s3c_pm_do_save(exynos5_sys_save, ARRAY_SIZE(exynos5_sys_save)); |
132 | /* Disable USE_RETENTION of JPEG_MEM_OPTION */ | 79 | /* Disable USE_RETENTION of JPEG_MEM_OPTION */ |
133 | tmp = __raw_readl(EXYNOS5_JPEG_MEM_OPTION); | 80 | tmp = __raw_readl(EXYNOS5_JPEG_MEM_OPTION); |
@@ -143,15 +90,6 @@ static void exynos_pm_prepare(void) | |||
143 | /* ensure at least INFORM0 has the resume address */ | 90 | /* ensure at least INFORM0 has the resume address */ |
144 | 91 | ||
145 | __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0); | 92 | __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0); |
146 | |||
147 | /* Before enter central sequence mode, clock src register have to set */ | ||
148 | |||
149 | if (!soc_is_exynos5250()) | ||
150 | s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc)); | ||
151 | |||
152 | if (soc_is_exynos4210()) | ||
153 | s3c_pm_do_restore_core(exynos4210_set_clksrc, ARRAY_SIZE(exynos4210_set_clksrc)); | ||
154 | |||
155 | } | 93 | } |
156 | 94 | ||
157 | static int exynos_pm_add(struct device *dev, struct subsys_interface *sif) | 95 | static int exynos_pm_add(struct device *dev, struct subsys_interface *sif) |
@@ -162,73 +100,6 @@ static int exynos_pm_add(struct device *dev, struct subsys_interface *sif) | |||
162 | return 0; | 100 | return 0; |
163 | } | 101 | } |
164 | 102 | ||
165 | static unsigned long pll_base_rate; | ||
166 | |||
167 | static void exynos4_restore_pll(void) | ||
168 | { | ||
169 | unsigned long pll_con, locktime, lockcnt; | ||
170 | unsigned long pll_in_rate; | ||
171 | unsigned int p_div, epll_wait = 0, vpll_wait = 0; | ||
172 | |||
173 | if (pll_base_rate == 0) | ||
174 | return; | ||
175 | |||
176 | pll_in_rate = pll_base_rate; | ||
177 | |||
178 | /* EPLL */ | ||
179 | pll_con = exynos4_epll_save[0].val; | ||
180 | |||
181 | if (pll_con & (1 << 31)) { | ||
182 | pll_con &= (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT); | ||
183 | p_div = (pll_con >> PLL46XX_PDIV_SHIFT); | ||
184 | |||
185 | pll_in_rate /= 1000000; | ||
186 | |||
187 | locktime = (3000 / pll_in_rate) * p_div; | ||
188 | lockcnt = locktime * 10000 / (10000 / pll_in_rate); | ||
189 | |||
190 | __raw_writel(lockcnt, EXYNOS4_EPLL_LOCK); | ||
191 | |||
192 | s3c_pm_do_restore_core(exynos4_epll_save, | ||
193 | ARRAY_SIZE(exynos4_epll_save)); | ||
194 | epll_wait = 1; | ||
195 | } | ||
196 | |||
197 | pll_in_rate = pll_base_rate; | ||
198 | |||
199 | /* VPLL */ | ||
200 | pll_con = exynos4_vpll_save[0].val; | ||
201 | |||
202 | if (pll_con & (1 << 31)) { | ||
203 | pll_in_rate /= 1000000; | ||
204 | /* 750us */ | ||
205 | locktime = 750; | ||
206 | lockcnt = locktime * 10000 / (10000 / pll_in_rate); | ||
207 | |||
208 | __raw_writel(lockcnt, EXYNOS4_VPLL_LOCK); | ||
209 | |||
210 | s3c_pm_do_restore_core(exynos4_vpll_save, | ||
211 | ARRAY_SIZE(exynos4_vpll_save)); | ||
212 | vpll_wait = 1; | ||
213 | } | ||
214 | |||
215 | /* Wait PLL locking */ | ||
216 | |||
217 | do { | ||
218 | if (epll_wait) { | ||
219 | pll_con = __raw_readl(EXYNOS4_EPLL_CON0); | ||
220 | if (pll_con & (1 << EXYNOS4_EPLLCON0_LOCKED_SHIFT)) | ||
221 | epll_wait = 0; | ||
222 | } | ||
223 | |||
224 | if (vpll_wait) { | ||
225 | pll_con = __raw_readl(EXYNOS4_VPLL_CON0); | ||
226 | if (pll_con & (1 << EXYNOS4_VPLLCON0_LOCKED_SHIFT)) | ||
227 | vpll_wait = 0; | ||
228 | } | ||
229 | } while (epll_wait || vpll_wait); | ||
230 | } | ||
231 | |||
232 | static struct subsys_interface exynos_pm_interface = { | 103 | static struct subsys_interface exynos_pm_interface = { |
233 | .name = "exynos_pm", | 104 | .name = "exynos_pm", |
234 | .subsys = &exynos_subsys, | 105 | .subsys = &exynos_subsys, |
@@ -237,7 +108,6 @@ static struct subsys_interface exynos_pm_interface = { | |||
237 | 108 | ||
238 | static __init int exynos_pm_drvinit(void) | 109 | static __init int exynos_pm_drvinit(void) |
239 | { | 110 | { |
240 | struct clk *pll_base; | ||
241 | unsigned int tmp; | 111 | unsigned int tmp; |
242 | 112 | ||
243 | if (soc_is_exynos5440()) | 113 | if (soc_is_exynos5440()) |
@@ -251,15 +121,6 @@ static __init int exynos_pm_drvinit(void) | |||
251 | tmp |= ((0xFF << 8) | (0x1F << 1)); | 121 | tmp |= ((0xFF << 8) | (0x1F << 1)); |
252 | __raw_writel(tmp, S5P_WAKEUP_MASK); | 122 | __raw_writel(tmp, S5P_WAKEUP_MASK); |
253 | 123 | ||
254 | if (!soc_is_exynos5250()) { | ||
255 | pll_base = clk_get(NULL, "xtal"); | ||
256 | |||
257 | if (!IS_ERR(pll_base)) { | ||
258 | pll_base_rate = clk_get_rate(pll_base); | ||
259 | clk_put(pll_base); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | return subsys_interface_register(&exynos_pm_interface); | 124 | return subsys_interface_register(&exynos_pm_interface); |
264 | } | 125 | } |
265 | arch_initcall(exynos_pm_drvinit); | 126 | arch_initcall(exynos_pm_drvinit); |
@@ -343,13 +204,8 @@ static void exynos_pm_resume(void) | |||
343 | 204 | ||
344 | s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); | 205 | s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); |
345 | 206 | ||
346 | if (!soc_is_exynos5250()) { | 207 | if (IS_ENABLED(CONFIG_SMP) && !soc_is_exynos5250()) |
347 | exynos4_restore_pll(); | ||
348 | |||
349 | #ifdef CONFIG_SMP | ||
350 | scu_enable(S5P_VA_SCU); | 208 | scu_enable(S5P_VA_SCU); |
351 | #endif | ||
352 | } | ||
353 | 209 | ||
354 | early_wakeup: | 210 | early_wakeup: |
355 | 211 | ||