diff options
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r-- | arch/arm/mach-omap2/pm.c | 270 |
1 files changed, 1 insertions, 269 deletions
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index baf7d82b458b..aad781dcf1b1 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/sysfs.h> | 23 | #include <linux/sysfs.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/clk.h> | ||
26 | 27 | ||
27 | #include <asm/io.h> | 28 | #include <asm/io.h> |
28 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
@@ -36,8 +37,6 @@ | |||
36 | #include <asm/arch/sram.h> | 37 | #include <asm/arch/sram.h> |
37 | #include <asm/arch/pm.h> | 38 | #include <asm/arch/pm.h> |
38 | 39 | ||
39 | #include "prcm-regs.h" | ||
40 | |||
41 | static struct clk *vclk; | 40 | static struct clk *vclk; |
42 | static void (*omap2_sram_idle)(void); | 41 | static void (*omap2_sram_idle)(void); |
43 | static void (*omap2_sram_suspend)(int dllctrl, int cpu_rev); | 42 | static void (*omap2_sram_suspend)(int dllctrl, int cpu_rev); |
@@ -78,251 +77,8 @@ static int omap2_pm_prepare(void) | |||
78 | return 0; | 77 | return 0; |
79 | } | 78 | } |
80 | 79 | ||
81 | #define INT0_WAKE_MASK (OMAP_IRQ_BIT(INT_24XX_GPIO_BANK1) | \ | ||
82 | OMAP_IRQ_BIT(INT_24XX_GPIO_BANK2) | \ | ||
83 | OMAP_IRQ_BIT(INT_24XX_GPIO_BANK3)) | ||
84 | |||
85 | #define INT1_WAKE_MASK (OMAP_IRQ_BIT(INT_24XX_GPIO_BANK4)) | ||
86 | |||
87 | #define INT2_WAKE_MASK (OMAP_IRQ_BIT(INT_24XX_UART1_IRQ) | \ | ||
88 | OMAP_IRQ_BIT(INT_24XX_UART2_IRQ) | \ | ||
89 | OMAP_IRQ_BIT(INT_24XX_UART3_IRQ)) | ||
90 | |||
91 | #define preg(reg) printk("%s\t(0x%p):\t0x%08x\n", #reg, ®, reg); | ||
92 | |||
93 | static void omap2_pm_debug(char * desc) | ||
94 | { | ||
95 | printk("%s:\n", desc); | ||
96 | |||
97 | preg(CM_CLKSTCTRL_MPU); | ||
98 | preg(CM_CLKSTCTRL_CORE); | ||
99 | preg(CM_CLKSTCTRL_GFX); | ||
100 | preg(CM_CLKSTCTRL_DSP); | ||
101 | preg(CM_CLKSTCTRL_MDM); | ||
102 | |||
103 | preg(PM_PWSTCTRL_MPU); | ||
104 | preg(PM_PWSTCTRL_CORE); | ||
105 | preg(PM_PWSTCTRL_GFX); | ||
106 | preg(PM_PWSTCTRL_DSP); | ||
107 | preg(PM_PWSTCTRL_MDM); | ||
108 | |||
109 | preg(PM_PWSTST_MPU); | ||
110 | preg(PM_PWSTST_CORE); | ||
111 | preg(PM_PWSTST_GFX); | ||
112 | preg(PM_PWSTST_DSP); | ||
113 | preg(PM_PWSTST_MDM); | ||
114 | |||
115 | preg(CM_AUTOIDLE1_CORE); | ||
116 | preg(CM_AUTOIDLE2_CORE); | ||
117 | preg(CM_AUTOIDLE3_CORE); | ||
118 | preg(CM_AUTOIDLE4_CORE); | ||
119 | preg(CM_AUTOIDLE_WKUP); | ||
120 | preg(CM_AUTOIDLE_PLL); | ||
121 | preg(CM_AUTOIDLE_DSP); | ||
122 | preg(CM_AUTOIDLE_MDM); | ||
123 | |||
124 | preg(CM_ICLKEN1_CORE); | ||
125 | preg(CM_ICLKEN2_CORE); | ||
126 | preg(CM_ICLKEN3_CORE); | ||
127 | preg(CM_ICLKEN4_CORE); | ||
128 | preg(CM_ICLKEN_GFX); | ||
129 | preg(CM_ICLKEN_WKUP); | ||
130 | preg(CM_ICLKEN_DSP); | ||
131 | preg(CM_ICLKEN_MDM); | ||
132 | |||
133 | preg(CM_IDLEST1_CORE); | ||
134 | preg(CM_IDLEST2_CORE); | ||
135 | preg(CM_IDLEST3_CORE); | ||
136 | preg(CM_IDLEST4_CORE); | ||
137 | preg(CM_IDLEST_GFX); | ||
138 | preg(CM_IDLEST_WKUP); | ||
139 | preg(CM_IDLEST_CKGEN); | ||
140 | preg(CM_IDLEST_DSP); | ||
141 | preg(CM_IDLEST_MDM); | ||
142 | |||
143 | preg(RM_RSTST_MPU); | ||
144 | preg(RM_RSTST_GFX); | ||
145 | preg(RM_RSTST_WKUP); | ||
146 | preg(RM_RSTST_DSP); | ||
147 | preg(RM_RSTST_MDM); | ||
148 | |||
149 | preg(PM_WKDEP_MPU); | ||
150 | preg(PM_WKDEP_CORE); | ||
151 | preg(PM_WKDEP_GFX); | ||
152 | preg(PM_WKDEP_DSP); | ||
153 | preg(PM_WKDEP_MDM); | ||
154 | |||
155 | preg(CM_FCLKEN_WKUP); | ||
156 | preg(CM_ICLKEN_WKUP); | ||
157 | preg(CM_IDLEST_WKUP); | ||
158 | preg(CM_AUTOIDLE_WKUP); | ||
159 | preg(CM_CLKSEL_WKUP); | ||
160 | |||
161 | preg(PM_WKEN_WKUP); | ||
162 | preg(PM_WKST_WKUP); | ||
163 | } | ||
164 | |||
165 | static inline void omap2_pm_save_registers(void) | ||
166 | { | ||
167 | /* Save interrupt registers */ | ||
168 | OMAP24XX_SAVE(INTC_MIR0); | ||
169 | OMAP24XX_SAVE(INTC_MIR1); | ||
170 | OMAP24XX_SAVE(INTC_MIR2); | ||
171 | |||
172 | /* Save power control registers */ | ||
173 | OMAP24XX_SAVE(CM_CLKSTCTRL_MPU); | ||
174 | OMAP24XX_SAVE(CM_CLKSTCTRL_CORE); | ||
175 | OMAP24XX_SAVE(CM_CLKSTCTRL_GFX); | ||
176 | OMAP24XX_SAVE(CM_CLKSTCTRL_DSP); | ||
177 | OMAP24XX_SAVE(CM_CLKSTCTRL_MDM); | ||
178 | |||
179 | /* Save power state registers */ | ||
180 | OMAP24XX_SAVE(PM_PWSTCTRL_MPU); | ||
181 | OMAP24XX_SAVE(PM_PWSTCTRL_CORE); | ||
182 | OMAP24XX_SAVE(PM_PWSTCTRL_GFX); | ||
183 | OMAP24XX_SAVE(PM_PWSTCTRL_DSP); | ||
184 | OMAP24XX_SAVE(PM_PWSTCTRL_MDM); | ||
185 | |||
186 | /* Save autoidle registers */ | ||
187 | OMAP24XX_SAVE(CM_AUTOIDLE1_CORE); | ||
188 | OMAP24XX_SAVE(CM_AUTOIDLE2_CORE); | ||
189 | OMAP24XX_SAVE(CM_AUTOIDLE3_CORE); | ||
190 | OMAP24XX_SAVE(CM_AUTOIDLE4_CORE); | ||
191 | OMAP24XX_SAVE(CM_AUTOIDLE_WKUP); | ||
192 | OMAP24XX_SAVE(CM_AUTOIDLE_PLL); | ||
193 | OMAP24XX_SAVE(CM_AUTOIDLE_DSP); | ||
194 | OMAP24XX_SAVE(CM_AUTOIDLE_MDM); | ||
195 | |||
196 | /* Save idle state registers */ | ||
197 | OMAP24XX_SAVE(CM_IDLEST1_CORE); | ||
198 | OMAP24XX_SAVE(CM_IDLEST2_CORE); | ||
199 | OMAP24XX_SAVE(CM_IDLEST3_CORE); | ||
200 | OMAP24XX_SAVE(CM_IDLEST4_CORE); | ||
201 | OMAP24XX_SAVE(CM_IDLEST_GFX); | ||
202 | OMAP24XX_SAVE(CM_IDLEST_WKUP); | ||
203 | OMAP24XX_SAVE(CM_IDLEST_CKGEN); | ||
204 | OMAP24XX_SAVE(CM_IDLEST_DSP); | ||
205 | OMAP24XX_SAVE(CM_IDLEST_MDM); | ||
206 | |||
207 | /* Save clock registers */ | ||
208 | OMAP24XX_SAVE(CM_FCLKEN1_CORE); | ||
209 | OMAP24XX_SAVE(CM_FCLKEN2_CORE); | ||
210 | OMAP24XX_SAVE(CM_ICLKEN1_CORE); | ||
211 | OMAP24XX_SAVE(CM_ICLKEN2_CORE); | ||
212 | OMAP24XX_SAVE(CM_ICLKEN3_CORE); | ||
213 | OMAP24XX_SAVE(CM_ICLKEN4_CORE); | ||
214 | } | ||
215 | |||
216 | static inline void omap2_pm_restore_registers(void) | ||
217 | { | ||
218 | /* Restore clock state registers */ | ||
219 | OMAP24XX_RESTORE(CM_CLKSTCTRL_MPU); | ||
220 | OMAP24XX_RESTORE(CM_CLKSTCTRL_CORE); | ||
221 | OMAP24XX_RESTORE(CM_CLKSTCTRL_GFX); | ||
222 | OMAP24XX_RESTORE(CM_CLKSTCTRL_DSP); | ||
223 | OMAP24XX_RESTORE(CM_CLKSTCTRL_MDM); | ||
224 | |||
225 | /* Restore power state registers */ | ||
226 | OMAP24XX_RESTORE(PM_PWSTCTRL_MPU); | ||
227 | OMAP24XX_RESTORE(PM_PWSTCTRL_CORE); | ||
228 | OMAP24XX_RESTORE(PM_PWSTCTRL_GFX); | ||
229 | OMAP24XX_RESTORE(PM_PWSTCTRL_DSP); | ||
230 | OMAP24XX_RESTORE(PM_PWSTCTRL_MDM); | ||
231 | |||
232 | /* Restore idle state registers */ | ||
233 | OMAP24XX_RESTORE(CM_IDLEST1_CORE); | ||
234 | OMAP24XX_RESTORE(CM_IDLEST2_CORE); | ||
235 | OMAP24XX_RESTORE(CM_IDLEST3_CORE); | ||
236 | OMAP24XX_RESTORE(CM_IDLEST4_CORE); | ||
237 | OMAP24XX_RESTORE(CM_IDLEST_GFX); | ||
238 | OMAP24XX_RESTORE(CM_IDLEST_WKUP); | ||
239 | OMAP24XX_RESTORE(CM_IDLEST_CKGEN); | ||
240 | OMAP24XX_RESTORE(CM_IDLEST_DSP); | ||
241 | OMAP24XX_RESTORE(CM_IDLEST_MDM); | ||
242 | |||
243 | /* Restore autoidle registers */ | ||
244 | OMAP24XX_RESTORE(CM_AUTOIDLE1_CORE); | ||
245 | OMAP24XX_RESTORE(CM_AUTOIDLE2_CORE); | ||
246 | OMAP24XX_RESTORE(CM_AUTOIDLE3_CORE); | ||
247 | OMAP24XX_RESTORE(CM_AUTOIDLE4_CORE); | ||
248 | OMAP24XX_RESTORE(CM_AUTOIDLE_WKUP); | ||
249 | OMAP24XX_RESTORE(CM_AUTOIDLE_PLL); | ||
250 | OMAP24XX_RESTORE(CM_AUTOIDLE_DSP); | ||
251 | OMAP24XX_RESTORE(CM_AUTOIDLE_MDM); | ||
252 | |||
253 | /* Restore clock registers */ | ||
254 | OMAP24XX_RESTORE(CM_FCLKEN1_CORE); | ||
255 | OMAP24XX_RESTORE(CM_FCLKEN2_CORE); | ||
256 | OMAP24XX_RESTORE(CM_ICLKEN1_CORE); | ||
257 | OMAP24XX_RESTORE(CM_ICLKEN2_CORE); | ||
258 | OMAP24XX_RESTORE(CM_ICLKEN3_CORE); | ||
259 | OMAP24XX_RESTORE(CM_ICLKEN4_CORE); | ||
260 | |||
261 | /* REVISIT: Clear interrupts here */ | ||
262 | |||
263 | /* Restore interrupt registers */ | ||
264 | OMAP24XX_RESTORE(INTC_MIR0); | ||
265 | OMAP24XX_RESTORE(INTC_MIR1); | ||
266 | OMAP24XX_RESTORE(INTC_MIR2); | ||
267 | } | ||
268 | |||
269 | static int omap2_pm_suspend(void) | 80 | static int omap2_pm_suspend(void) |
270 | { | 81 | { |
271 | int processor_type = 0; | ||
272 | |||
273 | /* REVISIT: 0x21 or 0x26? */ | ||
274 | if (cpu_is_omap2420()) | ||
275 | processor_type = 0x21; | ||
276 | |||
277 | if (!processor_type) | ||
278 | return -ENOTSUPP; | ||
279 | |||
280 | local_irq_disable(); | ||
281 | local_fiq_disable(); | ||
282 | |||
283 | omap2_pm_save_registers(); | ||
284 | |||
285 | /* Disable interrupts except for the wake events */ | ||
286 | INTC_MIR_SET0 = 0xffffffff & ~INT0_WAKE_MASK; | ||
287 | INTC_MIR_SET1 = 0xffffffff & ~INT1_WAKE_MASK; | ||
288 | INTC_MIR_SET2 = 0xffffffff & ~INT2_WAKE_MASK; | ||
289 | |||
290 | pmdomain_set_autoidle(); | ||
291 | |||
292 | /* Clear old wake-up events */ | ||
293 | PM_WKST1_CORE = 0; | ||
294 | PM_WKST2_CORE = 0; | ||
295 | PM_WKST_WKUP = 0; | ||
296 | |||
297 | /* Enable wake-up events */ | ||
298 | PM_WKEN1_CORE = (1 << 22) | (1 << 21); /* UART1 & 2 */ | ||
299 | PM_WKEN2_CORE = (1 << 2); /* UART3 */ | ||
300 | PM_WKEN_WKUP = (1 << 2) | (1 << 0); /* GPIO & GPT1 */ | ||
301 | |||
302 | /* Disable clocks except for CM_ICLKEN2_CORE. It gets disabled | ||
303 | * in the SRAM suspend code */ | ||
304 | CM_FCLKEN1_CORE = 0; | ||
305 | CM_FCLKEN2_CORE = 0; | ||
306 | CM_ICLKEN1_CORE = 0; | ||
307 | CM_ICLKEN3_CORE = 0; | ||
308 | CM_ICLKEN4_CORE = 0; | ||
309 | |||
310 | omap2_pm_debug("Status before suspend"); | ||
311 | |||
312 | /* Must wait for serial buffers to clear */ | ||
313 | mdelay(200); | ||
314 | |||
315 | /* Jump to SRAM suspend code | ||
316 | * REVISIT: When is this SDRC_DLLB_CTRL? | ||
317 | */ | ||
318 | omap2_sram_suspend(SDRC_DLLA_CTRL, processor_type); | ||
319 | |||
320 | /* Back from sleep */ | ||
321 | omap2_pm_restore_registers(); | ||
322 | |||
323 | local_fiq_enable(); | ||
324 | local_irq_enable(); | ||
325 | |||
326 | return 0; | 82 | return 0; |
327 | } | 83 | } |
328 | 84 | ||
@@ -357,30 +113,6 @@ static struct platform_suspend_ops omap_pm_ops = { | |||
357 | 113 | ||
358 | int __init omap2_pm_init(void) | 114 | int __init omap2_pm_init(void) |
359 | { | 115 | { |
360 | printk("Power Management for TI OMAP.\n"); | ||
361 | |||
362 | vclk = clk_get(NULL, "virt_prcm_set"); | ||
363 | if (IS_ERR(vclk)) { | ||
364 | printk(KERN_ERR "Could not get PM vclk\n"); | ||
365 | return -ENODEV; | ||
366 | } | ||
367 | |||
368 | /* | ||
369 | * We copy the assembler sleep/wakeup routines to SRAM. | ||
370 | * These routines need to be in SRAM as that's the only | ||
371 | * memory the MPU can see when it wakes up. | ||
372 | */ | ||
373 | omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend, | ||
374 | omap24xx_idle_loop_suspend_sz); | ||
375 | |||
376 | omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend, | ||
377 | omap24xx_cpu_suspend_sz); | ||
378 | |||
379 | suspend_set_ops(&omap_pm_ops); | ||
380 | pm_idle = omap2_pm_idle; | ||
381 | |||
382 | pmdomain_init(); | ||
383 | |||
384 | return 0; | 116 | return 0; |
385 | } | 117 | } |
386 | 118 | ||