1 /* linux/arch/arm/mach-exynos4/pm.c
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
6 * EXYNOS4210 - Power Management support
8 * Based on arch/arm/mach-s3c2410/pm.c
9 * Copyright (c) 2006 Simtec Electronics
10 * Ben Dooks <ben@simtec.co.uk>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
17 #include <linux/init.h>
18 #include <linux/suspend.h>
21 #include <asm/cacheflush.h>
22 #include <asm/hardware/cache-l2x0.h>
27 #include <mach/regs-irq.h>
28 #include <mach/regs-gpio.h>
29 #include <mach/regs-clock.h>
30 #include <mach/regs-pmu.h>
31 #include <mach/pm-core.h>
33 static struct sleep_save exynos4_sleep
[] = {
34 { .reg
= S5P_ARM_CORE0_LOWPWR
, .val
= 0x2, },
35 { .reg
= S5P_DIS_IRQ_CORE0
, .val
= 0x0, },
36 { .reg
= S5P_DIS_IRQ_CENTRAL0
, .val
= 0x0, },
37 { .reg
= S5P_ARM_CORE1_LOWPWR
, .val
= 0x2, },
38 { .reg
= S5P_DIS_IRQ_CORE1
, .val
= 0x0, },
39 { .reg
= S5P_DIS_IRQ_CENTRAL1
, .val
= 0x0, },
40 { .reg
= S5P_ARM_COMMON_LOWPWR
, .val
= 0x2, },
41 { .reg
= S5P_L2_0_LOWPWR
, .val
= 0x3, },
42 { .reg
= S5P_L2_1_LOWPWR
, .val
= 0x3, },
43 { .reg
= S5P_CMU_ACLKSTOP_LOWPWR
, .val
= 0x0, },
44 { .reg
= S5P_CMU_SCLKSTOP_LOWPWR
, .val
= 0x0, },
45 { .reg
= S5P_CMU_RESET_LOWPWR
, .val
= 0x0, },
46 { .reg
= S5P_APLL_SYSCLK_LOWPWR
, .val
= 0x0, },
47 { .reg
= S5P_MPLL_SYSCLK_LOWPWR
, .val
= 0x0, },
48 { .reg
= S5P_VPLL_SYSCLK_LOWPWR
, .val
= 0x0, },
49 { .reg
= S5P_EPLL_SYSCLK_LOWPWR
, .val
= 0x0, },
50 { .reg
= S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR
, .val
= 0x0, },
51 { .reg
= S5P_CMU_RESET_GPSALIVE_LOWPWR
, .val
= 0x0, },
52 { .reg
= S5P_CMU_CLKSTOP_CAM_LOWPWR
, .val
= 0x0, },
53 { .reg
= S5P_CMU_CLKSTOP_TV_LOWPWR
, .val
= 0x0, },
54 { .reg
= S5P_CMU_CLKSTOP_MFC_LOWPWR
, .val
= 0x0, },
55 { .reg
= S5P_CMU_CLKSTOP_G3D_LOWPWR
, .val
= 0x0, },
56 { .reg
= S5P_CMU_CLKSTOP_LCD0_LOWPWR
, .val
= 0x0, },
57 { .reg
= S5P_CMU_CLKSTOP_LCD1_LOWPWR
, .val
= 0x0, },
58 { .reg
= S5P_CMU_CLKSTOP_MAUDIO_LOWPWR
, .val
= 0x0, },
59 { .reg
= S5P_CMU_CLKSTOP_GPS_LOWPWR
, .val
= 0x0, },
60 { .reg
= S5P_CMU_RESET_CAM_LOWPWR
, .val
= 0x0, },
61 { .reg
= S5P_CMU_RESET_TV_LOWPWR
, .val
= 0x0, },
62 { .reg
= S5P_CMU_RESET_MFC_LOWPWR
, .val
= 0x0, },
63 { .reg
= S5P_CMU_RESET_G3D_LOWPWR
, .val
= 0x0, },
64 { .reg
= S5P_CMU_RESET_LCD0_LOWPWR
, .val
= 0x0, },
65 { .reg
= S5P_CMU_RESET_LCD1_LOWPWR
, .val
= 0x0, },
66 { .reg
= S5P_CMU_RESET_MAUDIO_LOWPWR
, .val
= 0x0, },
67 { .reg
= S5P_CMU_RESET_GPS_LOWPWR
, .val
= 0x0, },
68 { .reg
= S5P_TOP_BUS_LOWPWR
, .val
= 0x0, },
69 { .reg
= S5P_TOP_RETENTION_LOWPWR
, .val
= 0x1, },
70 { .reg
= S5P_TOP_PWR_LOWPWR
, .val
= 0x3, },
71 { .reg
= S5P_LOGIC_RESET_LOWPWR
, .val
= 0x0, },
72 { .reg
= S5P_ONENAND_MEM_LOWPWR
, .val
= 0x0, },
73 { .reg
= S5P_MODIMIF_MEM_LOWPWR
, .val
= 0x0, },
74 { .reg
= S5P_G2D_ACP_MEM_LOWPWR
, .val
= 0x0, },
75 { .reg
= S5P_USBOTG_MEM_LOWPWR
, .val
= 0x0, },
76 { .reg
= S5P_HSMMC_MEM_LOWPWR
, .val
= 0x0, },
77 { .reg
= S5P_CSSYS_MEM_LOWPWR
, .val
= 0x0, },
78 { .reg
= S5P_SECSS_MEM_LOWPWR
, .val
= 0x0, },
79 { .reg
= S5P_PCIE_MEM_LOWPWR
, .val
= 0x0, },
80 { .reg
= S5P_SATA_MEM_LOWPWR
, .val
= 0x0, },
81 { .reg
= S5P_PAD_RETENTION_DRAM_LOWPWR
, .val
= 0x0, },
82 { .reg
= S5P_PAD_RETENTION_MAUDIO_LOWPWR
, .val
= 0x0, },
83 { .reg
= S5P_PAD_RETENTION_GPIO_LOWPWR
, .val
= 0x0, },
84 { .reg
= S5P_PAD_RETENTION_UART_LOWPWR
, .val
= 0x0, },
85 { .reg
= S5P_PAD_RETENTION_MMCA_LOWPWR
, .val
= 0x0, },
86 { .reg
= S5P_PAD_RETENTION_MMCB_LOWPWR
, .val
= 0x0, },
87 { .reg
= S5P_PAD_RETENTION_EBIA_LOWPWR
, .val
= 0x0, },
88 { .reg
= S5P_PAD_RETENTION_EBIB_LOWPWR
, .val
= 0x0, },
89 { .reg
= S5P_PAD_RETENTION_ISOLATION_LOWPWR
, .val
= 0x0, },
90 { .reg
= S5P_PAD_RETENTION_ALV_SEL_LOWPWR
, .val
= 0x0, },
91 { .reg
= S5P_XUSBXTI_LOWPWR
, .val
= 0x0, },
92 { .reg
= S5P_XXTI_LOWPWR
, .val
= 0x0, },
93 { .reg
= S5P_EXT_REGULATOR_LOWPWR
, .val
= 0x0, },
94 { .reg
= S5P_GPIO_MODE_LOWPWR
, .val
= 0x0, },
95 { .reg
= S5P_GPIO_MODE_MAUDIO_LOWPWR
, .val
= 0x0, },
96 { .reg
= S5P_CAM_LOWPWR
, .val
= 0x0, },
97 { .reg
= S5P_TV_LOWPWR
, .val
= 0x0, },
98 { .reg
= S5P_MFC_LOWPWR
, .val
= 0x0, },
99 { .reg
= S5P_G3D_LOWPWR
, .val
= 0x0, },
100 { .reg
= S5P_LCD0_LOWPWR
, .val
= 0x0, },
101 { .reg
= S5P_LCD1_LOWPWR
, .val
= 0x0, },
102 { .reg
= S5P_MAUDIO_LOWPWR
, .val
= 0x0, },
103 { .reg
= S5P_GPS_LOWPWR
, .val
= 0x0, },
104 { .reg
= S5P_GPS_ALIVE_LOWPWR
, .val
= 0x0, },
107 static struct sleep_save exynos4_set_clksrc
[] = {
108 { .reg
= S5P_CLKSRC_MASK_TOP
, .val
= 0x00000001, },
109 { .reg
= S5P_CLKSRC_MASK_CAM
, .val
= 0x11111111, },
110 { .reg
= S5P_CLKSRC_MASK_TV
, .val
= 0x00000111, },
111 { .reg
= S5P_CLKSRC_MASK_LCD0
, .val
= 0x00001111, },
112 { .reg
= S5P_CLKSRC_MASK_LCD1
, .val
= 0x00001111, },
113 { .reg
= S5P_CLKSRC_MASK_MAUDIO
, .val
= 0x00000001, },
114 { .reg
= S5P_CLKSRC_MASK_FSYS
, .val
= 0x01011111, },
115 { .reg
= S5P_CLKSRC_MASK_PERIL0
, .val
= 0x01111111, },
116 { .reg
= S5P_CLKSRC_MASK_PERIL1
, .val
= 0x01110111, },
117 { .reg
= S5P_CLKSRC_MASK_DMC
, .val
= 0x00010000, },
120 static struct sleep_save exynos4_core_save
[] = {
122 SAVE_ITEM(S5P_CLKDIV_LEFTBUS
),
123 SAVE_ITEM(S5P_CLKGATE_IP_LEFTBUS
),
124 SAVE_ITEM(S5P_CLKDIV_RIGHTBUS
),
125 SAVE_ITEM(S5P_CLKGATE_IP_RIGHTBUS
),
126 SAVE_ITEM(S5P_EPLL_CON0
),
127 SAVE_ITEM(S5P_EPLL_CON1
),
128 SAVE_ITEM(S5P_VPLL_CON0
),
129 SAVE_ITEM(S5P_VPLL_CON1
),
130 SAVE_ITEM(S5P_CLKSRC_TOP0
),
131 SAVE_ITEM(S5P_CLKSRC_TOP1
),
132 SAVE_ITEM(S5P_CLKSRC_CAM
),
133 SAVE_ITEM(S5P_CLKSRC_MFC
),
134 SAVE_ITEM(S5P_CLKSRC_IMAGE
),
135 SAVE_ITEM(S5P_CLKSRC_LCD0
),
136 SAVE_ITEM(S5P_CLKSRC_LCD1
),
137 SAVE_ITEM(S5P_CLKSRC_MAUDIO
),
138 SAVE_ITEM(S5P_CLKSRC_FSYS
),
139 SAVE_ITEM(S5P_CLKSRC_PERIL0
),
140 SAVE_ITEM(S5P_CLKSRC_PERIL1
),
141 SAVE_ITEM(S5P_CLKDIV_CAM
),
142 SAVE_ITEM(S5P_CLKDIV_TV
),
143 SAVE_ITEM(S5P_CLKDIV_MFC
),
144 SAVE_ITEM(S5P_CLKDIV_G3D
),
145 SAVE_ITEM(S5P_CLKDIV_IMAGE
),
146 SAVE_ITEM(S5P_CLKDIV_LCD0
),
147 SAVE_ITEM(S5P_CLKDIV_LCD1
),
148 SAVE_ITEM(S5P_CLKDIV_MAUDIO
),
149 SAVE_ITEM(S5P_CLKDIV_FSYS0
),
150 SAVE_ITEM(S5P_CLKDIV_FSYS1
),
151 SAVE_ITEM(S5P_CLKDIV_FSYS2
),
152 SAVE_ITEM(S5P_CLKDIV_FSYS3
),
153 SAVE_ITEM(S5P_CLKDIV_PERIL0
),
154 SAVE_ITEM(S5P_CLKDIV_PERIL1
),
155 SAVE_ITEM(S5P_CLKDIV_PERIL2
),
156 SAVE_ITEM(S5P_CLKDIV_PERIL3
),
157 SAVE_ITEM(S5P_CLKDIV_PERIL4
),
158 SAVE_ITEM(S5P_CLKDIV_PERIL5
),
159 SAVE_ITEM(S5P_CLKDIV_TOP
),
160 SAVE_ITEM(S5P_CLKSRC_MASK_CAM
),
161 SAVE_ITEM(S5P_CLKSRC_MASK_TV
),
162 SAVE_ITEM(S5P_CLKSRC_MASK_LCD0
),
163 SAVE_ITEM(S5P_CLKSRC_MASK_LCD1
),
164 SAVE_ITEM(S5P_CLKSRC_MASK_MAUDIO
),
165 SAVE_ITEM(S5P_CLKSRC_MASK_FSYS
),
166 SAVE_ITEM(S5P_CLKSRC_MASK_PERIL0
),
167 SAVE_ITEM(S5P_CLKSRC_MASK_PERIL1
),
168 SAVE_ITEM(S5P_CLKGATE_SCLKCAM
),
169 SAVE_ITEM(S5P_CLKGATE_IP_CAM
),
170 SAVE_ITEM(S5P_CLKGATE_IP_TV
),
171 SAVE_ITEM(S5P_CLKGATE_IP_MFC
),
172 SAVE_ITEM(S5P_CLKGATE_IP_G3D
),
173 SAVE_ITEM(S5P_CLKGATE_IP_IMAGE
),
174 SAVE_ITEM(S5P_CLKGATE_IP_LCD0
),
175 SAVE_ITEM(S5P_CLKGATE_IP_LCD1
),
176 SAVE_ITEM(S5P_CLKGATE_IP_FSYS
),
177 SAVE_ITEM(S5P_CLKGATE_IP_GPS
),
178 SAVE_ITEM(S5P_CLKGATE_IP_PERIL
),
179 SAVE_ITEM(S5P_CLKGATE_IP_PERIR
),
180 SAVE_ITEM(S5P_CLKGATE_BLOCK
),
181 SAVE_ITEM(S5P_CLKSRC_MASK_DMC
),
182 SAVE_ITEM(S5P_CLKSRC_DMC
),
183 SAVE_ITEM(S5P_CLKDIV_DMC0
),
184 SAVE_ITEM(S5P_CLKDIV_DMC1
),
185 SAVE_ITEM(S5P_CLKGATE_IP_DMC
),
186 SAVE_ITEM(S5P_CLKSRC_CPU
),
187 SAVE_ITEM(S5P_CLKDIV_CPU
),
188 SAVE_ITEM(S5P_CLKGATE_SCLKCPU
),
189 SAVE_ITEM(S5P_CLKGATE_IP_CPU
),
191 SAVE_ITEM(S5P_VA_GIC_CPU
+ 0x000),
192 SAVE_ITEM(S5P_VA_GIC_CPU
+ 0x004),
193 SAVE_ITEM(S5P_VA_GIC_CPU
+ 0x008),
194 SAVE_ITEM(S5P_VA_GIC_CPU
+ 0x00C),
195 SAVE_ITEM(S5P_VA_GIC_CPU
+ 0x014),
196 SAVE_ITEM(S5P_VA_GIC_CPU
+ 0x018),
197 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x000),
198 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x004),
199 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x100),
200 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x104),
201 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x108),
202 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x300),
203 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x304),
204 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x308),
205 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x400),
206 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x404),
207 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x408),
208 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x40C),
209 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x410),
210 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x414),
211 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x418),
212 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x41C),
213 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x420),
214 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x424),
215 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x428),
216 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x42C),
217 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x430),
218 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x434),
219 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x438),
220 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x43C),
221 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x440),
222 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x444),
223 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x448),
224 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x44C),
225 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x450),
226 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x454),
227 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x458),
228 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x45C),
230 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x800),
231 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x804),
232 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x808),
233 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x80C),
234 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x810),
235 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x814),
236 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x818),
237 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x81C),
238 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x820),
239 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x824),
240 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x828),
241 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x82C),
242 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x830),
243 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x834),
244 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x838),
245 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x83C),
246 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x840),
247 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x844),
248 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x848),
249 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x84C),
250 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x850),
251 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x854),
252 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x858),
253 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0x85C),
255 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0xC00),
256 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0xC04),
257 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0xC08),
258 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0xC0C),
259 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0xC10),
260 SAVE_ITEM(S5P_VA_GIC_DIST
+ 0xC14),
262 SAVE_ITEM(S5P_VA_COMBINER_BASE
+ 0x000),
263 SAVE_ITEM(S5P_VA_COMBINER_BASE
+ 0x010),
264 SAVE_ITEM(S5P_VA_COMBINER_BASE
+ 0x020),
265 SAVE_ITEM(S5P_VA_COMBINER_BASE
+ 0x030),
266 SAVE_ITEM(S5P_VA_COMBINER_BASE
+ 0x040),
267 SAVE_ITEM(S5P_VA_COMBINER_BASE
+ 0x050),
268 SAVE_ITEM(S5P_VA_COMBINER_BASE
+ 0x060),
269 SAVE_ITEM(S5P_VA_COMBINER_BASE
+ 0x070),
270 SAVE_ITEM(S5P_VA_COMBINER_BASE
+ 0x080),
271 SAVE_ITEM(S5P_VA_COMBINER_BASE
+ 0x090),
274 static struct sleep_save exynos4_l2cc_save
[] = {
275 SAVE_ITEM(S5P_VA_L2CC
+ L2X0_TAG_LATENCY_CTRL
),
276 SAVE_ITEM(S5P_VA_L2CC
+ L2X0_DATA_LATENCY_CTRL
),
277 SAVE_ITEM(S5P_VA_L2CC
+ L2X0_PREFETCH_CTRL
),
278 SAVE_ITEM(S5P_VA_L2CC
+ L2X0_POWER_CTRL
),
279 SAVE_ITEM(S5P_VA_L2CC
+ L2X0_AUX_CTRL
),
282 void exynos4_cpu_suspend(void)
285 unsigned long mask
= 0xFFFFFFFF;
287 /* Setting Central Sequence Register for power down mode */
289 tmp
= __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION
);
290 tmp
&= ~(S5P_CENTRAL_LOWPWR_CFG
);
291 __raw_writel(tmp
, S5P_CENTRAL_SEQ_CONFIGURATION
);
293 /* Setting Central Sequence option Register */
295 tmp
= __raw_readl(S5P_CENTRAL_SEQ_OPTION
);
296 tmp
&= ~(S5P_USE_MASK
);
297 tmp
|= S5P_USE_STANDBY_WFI0
;
298 __raw_writel(tmp
, S5P_CENTRAL_SEQ_OPTION
);
300 /* Clear all interrupt pending to avoid early wakeup */
302 __raw_writel(mask
, (S5P_VA_GIC_DIST
+ 0x280));
303 __raw_writel(mask
, (S5P_VA_GIC_DIST
+ 0x284));
304 __raw_writel(mask
, (S5P_VA_GIC_DIST
+ 0x288));
306 /* Disable all interrupt */
308 __raw_writel(0x0, (S5P_VA_GIC_CPU
+ 0x000));
309 __raw_writel(0x0, (S5P_VA_GIC_DIST
+ 0x000));
310 __raw_writel(mask
, (S5P_VA_GIC_DIST
+ 0x184));
311 __raw_writel(mask
, (S5P_VA_GIC_DIST
+ 0x188));
315 /* issue the standby signal into the pm unit. */
318 /* we should never get past here */
319 panic("sleep resumed to originator?");
322 static void exynos4_pm_prepare(void)
326 s3c_pm_do_save(exynos4_core_save
, ARRAY_SIZE(exynos4_core_save
));
327 s3c_pm_do_save(exynos4_l2cc_save
, ARRAY_SIZE(exynos4_l2cc_save
));
329 tmp
= __raw_readl(S5P_INFORM1
);
331 /* Set value of power down register for sleep mode */
333 s3c_pm_do_restore_core(exynos4_sleep
, ARRAY_SIZE(exynos4_sleep
));
334 __raw_writel(S5P_CHECK_SLEEP
, S5P_INFORM1
);
336 /* ensure at least INFORM0 has the resume address */
338 __raw_writel(virt_to_phys(s3c_cpu_resume
), S5P_INFORM0
);
340 /* Before enter central sequence mode, clock src register have to set */
342 s3c_pm_do_restore_core(exynos4_set_clksrc
, ARRAY_SIZE(exynos4_set_clksrc
));
346 static int exynos4_pm_add(struct sys_device
*sysdev
)
348 pm_cpu_prep
= exynos4_pm_prepare
;
349 pm_cpu_sleep
= exynos4_cpu_suspend
;
354 /* This function copy from linux/arch/arm/kernel/smp_scu.c */
356 void exynos4_scu_enable(void __iomem
*scu_base
)
360 scu_ctrl
= __raw_readl(scu_base
);
361 /* already enabled? */
366 __raw_writel(scu_ctrl
, scu_base
);
369 * Ensure that the data accessed by CPU0 before the SCU was
370 * initialised is visible to the other CPUs.
375 static int exynos4_pm_resume(struct sys_device
*dev
)
377 /* For release retention */
379 __raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION
);
380 __raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION
);
381 __raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION
);
382 __raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION
);
383 __raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION
);
384 __raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION
);
385 __raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION
);
387 s3c_pm_do_restore_core(exynos4_core_save
, ARRAY_SIZE(exynos4_core_save
));
389 exynos4_scu_enable(S5P_VA_SCU
);
391 #ifdef CONFIG_CACHE_L2X0
392 s3c_pm_do_restore_core(exynos4_l2cc_save
, ARRAY_SIZE(exynos4_l2cc_save
));
395 writel_relaxed(1, S5P_VA_L2CC
+ L2X0_CTRL
);
401 static struct sysdev_driver exynos4_pm_driver
= {
402 .add
= exynos4_pm_add
,
403 .resume
= exynos4_pm_resume
,
406 static __init
int exynos4_pm_drvinit(void)
412 /* All wakeup disable */
414 tmp
= __raw_readl(S5P_WAKEUP_MASK
);
415 tmp
|= ((0xFF << 8) | (0x1F << 1));
416 __raw_writel(tmp
, S5P_WAKEUP_MASK
);
418 return sysdev_driver_register(&exynos4_sysclass
, &exynos4_pm_driver
);
420 arch_initcall(exynos4_pm_drvinit
);