]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/pm34xx.c
da112b8b08a1ff79cfe79977c382b0ac765f1ec7
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap2 / pm34xx.c
1 /*
2  * linux/arch/arm/mach-omap2/pm34xx.c
3  *
4  * OMAP3 Power Management Routines
5  *
6  * Copyright (C) 2006-2008 Nokia Corporation
7  * Tony Lindgren <tony@atomide.com>
8  * Jouni Hogander
9  *
10  * Copyright (C) 2005 Texas Instruments, Inc.
11  * Richard Woodruff <r-woodruff2@ti.com>
12  *
13  * Based on pm.c for omap1
14  *
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License version 2 as
17  * published by the Free Software Foundation.
18  */
19
20 #include <linux/pm.h>
21 #include <linux/suspend.h>
22 #include <linux/interrupt.h>
23 #include <linux/module.h>
24 #include <linux/list.h>
25 #include <linux/err.h>
26
27 #include <mach/gpio.h>
28 #include <mach/sram.h>
29 #include <mach/pm.h>
30 #include <mach/clockdomain.h>
31 #include <mach/powerdomain.h>
32 #include <mach/serial.h>
33
34 #include "cm.h"
35 #include "cm-regbits-34xx.h"
36 #include "prm-regbits-34xx.h"
37
38 #include "prm.h"
39 #include "pm.h"
40 #include "smartreflex.h"
41
42 struct power_state {
43         struct powerdomain *pwrdm;
44         u32 next_state;
45         u32 saved_state;
46         struct list_head node;
47 };
48
49 static LIST_HEAD(pwrst_list);
50
51 static void (*_omap_sram_idle)(u32 *addr, int save_state);
52
53 static void (*saved_idle)(void);
54
55 static struct powerdomain *mpu_pwrdm;
56
57 /* PRCM Interrupt Handler for wakeups */
58 static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
59 {
60         u32 wkst, irqstatus_mpu;
61         u32 fclk, iclk;
62
63         /* WKUP */
64         wkst = prm_read_mod_reg(WKUP_MOD, PM_WKST);
65         if (wkst) {
66                 iclk = cm_read_mod_reg(WKUP_MOD, CM_ICLKEN);
67                 fclk = cm_read_mod_reg(WKUP_MOD, CM_FCLKEN);
68                 cm_set_mod_reg_bits(wkst, WKUP_MOD, CM_ICLKEN);
69                 cm_set_mod_reg_bits(wkst, WKUP_MOD, CM_FCLKEN);
70                 prm_write_mod_reg(wkst, WKUP_MOD, PM_WKST);
71                 while (prm_read_mod_reg(WKUP_MOD, PM_WKST));
72                 cm_write_mod_reg(iclk, WKUP_MOD, CM_ICLKEN);
73                 cm_write_mod_reg(fclk, WKUP_MOD, CM_FCLKEN);
74         }
75
76         /* CORE */
77         wkst = prm_read_mod_reg(CORE_MOD, PM_WKST1);
78         if (wkst) {
79                 iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
80                 fclk = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
81                 cm_set_mod_reg_bits(wkst, CORE_MOD, CM_ICLKEN1);
82                 cm_set_mod_reg_bits(wkst, CORE_MOD, CM_FCLKEN1);
83                 prm_write_mod_reg(wkst, CORE_MOD, PM_WKST1);
84                 while (prm_read_mod_reg(CORE_MOD, PM_WKST1));
85                 cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN1);
86                 cm_write_mod_reg(fclk, CORE_MOD, CM_FCLKEN1);
87         }
88         wkst = prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3);
89         if (wkst) {
90                 iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
91                 fclk = cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
92                 cm_set_mod_reg_bits(wkst, CORE_MOD, CM_ICLKEN3);
93                 cm_set_mod_reg_bits(wkst, CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
94                 prm_write_mod_reg(wkst, CORE_MOD, OMAP3430ES2_PM_WKST3);
95                 while (prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3));
96                 cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN3);
97                 cm_write_mod_reg(fclk, CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
98         }
99
100         /* PER */
101         wkst = prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKST);
102         if (wkst) {
103                 iclk = cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
104                 fclk = cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
105                 cm_set_mod_reg_bits(wkst, OMAP3430_PER_MOD, CM_ICLKEN);
106                 cm_set_mod_reg_bits(wkst, OMAP3430_PER_MOD, CM_FCLKEN);
107                 prm_write_mod_reg(wkst, OMAP3430_PER_MOD, PM_WKST);
108                 while (prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKST));
109                 cm_write_mod_reg(iclk, OMAP3430_PER_MOD, CM_ICLKEN);
110                 cm_write_mod_reg(fclk, OMAP3430_PER_MOD, CM_FCLKEN);
111         }
112
113         if (omap_rev() > OMAP3430_REV_ES1_0) {
114                 /* USBHOST */
115                 wkst = prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, PM_WKST);
116                 if (wkst) {
117                         iclk = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
118                                                CM_ICLKEN);
119                         fclk = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
120                                                CM_FCLKEN);
121                         cm_set_mod_reg_bits(wkst, OMAP3430ES2_USBHOST_MOD,
122                                          CM_ICLKEN);
123                         cm_set_mod_reg_bits(wkst, OMAP3430ES2_USBHOST_MOD,
124                                          CM_FCLKEN);
125                         prm_write_mod_reg(wkst, OMAP3430ES2_USBHOST_MOD,
126                                           PM_WKST);
127                         while (prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
128                                                 PM_WKST));
129                         cm_write_mod_reg(iclk, OMAP3430ES2_USBHOST_MOD,
130                                          CM_ICLKEN);
131                         cm_write_mod_reg(fclk, OMAP3430ES2_USBHOST_MOD,
132                                          CM_FCLKEN);
133                 }
134         }
135
136         irqstatus_mpu = prm_read_mod_reg(OCP_MOD,
137                                         OMAP2_PRM_IRQSTATUS_MPU_OFFSET);
138         prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
139                                         OMAP2_PRM_IRQSTATUS_MPU_OFFSET);
140
141         while (prm_read_mod_reg(OCP_MOD, OMAP2_PRM_IRQSTATUS_MPU_OFFSET));
142
143         return IRQ_HANDLED;
144 }
145
146 static void omap_sram_idle(void)
147 {
148         /* Variable to tell what needs to be saved and restored
149          * in omap_sram_idle*/
150         /* save_state = 0 => Nothing to save and restored */
151         /* save_state = 1 => Only L1 and logic lost */
152         /* save_state = 2 => Only L2 lost */
153         /* save_state = 3 => L1, L2 and logic lost */
154         int save_state = 0, mpu_next_state;
155
156         if (!_omap_sram_idle)
157                 return;
158
159         mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
160         switch (mpu_next_state) {
161         case PWRDM_POWER_RET:
162                 /* No need to save context */
163                 save_state = 0;
164                 break;
165         default:
166                 /* Invalid state */
167                 printk(KERN_ERR "Invalid mpu state in sram_idle\n");
168                 return;
169         }
170         /* Disable smartreflex before entering WFI */
171         disable_smartreflex(SR1);
172         disable_smartreflex(SR2);
173
174         omap2_gpio_prepare_for_retention();
175         omap_uart_prepare_idle(0);
176         omap_uart_prepare_idle(1);
177         omap_uart_prepare_idle(2);
178
179         _omap_sram_idle(NULL, save_state);
180
181         omap_uart_resume_idle(2);
182         omap_uart_resume_idle(1);
183         omap_uart_resume_idle(0);
184         omap2_gpio_resume_after_retention();
185
186         /* Enable smartreflex after WFI */
187         enable_smartreflex(SR1);
188         enable_smartreflex(SR2);
189 }
190
191 /*
192  * Check if functional clocks are enabled before entering
193  * sleep. This function could be behind CONFIG_PM_DEBUG
194  * when all drivers are configuring their sysconfig registers
195  * properly and using their clocks properly.
196  */
197 static int omap3_fclks_active(void)
198 {
199         u32 fck_core1 = 0, fck_core3 = 0, fck_sgx = 0, fck_dss = 0,
200                 fck_cam = 0, fck_per = 0, fck_usbhost = 0;
201
202         fck_core1 = cm_read_mod_reg(CORE_MOD,
203                                     CM_FCLKEN1);
204         if (omap_rev() > OMAP3430_REV_ES1_0) {
205                 fck_core3 = cm_read_mod_reg(CORE_MOD,
206                                             OMAP3430ES2_CM_FCLKEN3);
207                 fck_sgx = cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
208                                           CM_FCLKEN);
209                 fck_usbhost = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
210                                               CM_FCLKEN);
211         } else
212                 fck_sgx = cm_read_mod_reg(GFX_MOD,
213                                           OMAP3430ES2_CM_FCLKEN3);
214         fck_dss = cm_read_mod_reg(OMAP3430_DSS_MOD,
215                                   CM_FCLKEN);
216         fck_cam = cm_read_mod_reg(OMAP3430_CAM_MOD,
217                                   CM_FCLKEN);
218         fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
219                                   CM_FCLKEN);
220
221         /* Ignore UART clocks.  These are handled by UART core (serial.c) */
222         fck_core1 &= ~(OMAP3430_EN_UART1 | OMAP3430_EN_UART2);
223         fck_per &= ~OMAP3430_EN_UART3;
224
225         if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
226             fck_cam | fck_per | fck_usbhost)
227                 return 1;
228         return 0;
229 }
230
231 static int omap3_can_sleep(void)
232 {
233         if (!enable_dyn_sleep)
234                 return 0;
235         if (!omap_uart_can_sleep())
236                 return 0;
237         if (omap3_fclks_active())
238                 return 0;
239         if (atomic_read(&sleep_block) > 0)
240                 return 0;
241         return 1;
242 }
243
244 /* This sets pwrdm state (other than mpu & core. Currently only ON &
245  * RET are supported. Function is assuming that clkdm doesn't have
246  * hw_sup mode enabled. */
247 static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
248 {
249         u32 cur_state;
250         int sleep_switch = 0;
251         int ret = 0;
252
253         if (pwrdm == NULL || IS_ERR(pwrdm))
254                 return -EINVAL;
255
256         while (!(pwrdm->pwrsts & (1 << state))) {
257                 if (state == PWRDM_POWER_OFF)
258                         return ret;
259                 state--;
260         }
261
262         cur_state = pwrdm_read_next_pwrst(pwrdm);
263         if (cur_state == state)
264                 return ret;
265
266         if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) {
267                 omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
268                 sleep_switch = 1;
269                 pwrdm_wait_transition(pwrdm);
270         }
271
272         ret = pwrdm_set_next_pwrst(pwrdm, state);
273         if (ret) {
274                 printk(KERN_ERR "Unable to set state of powerdomain: %s\n",
275                        pwrdm->name);
276                 goto err;
277         }
278
279         if (sleep_switch) {
280                 omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
281                 pwrdm_wait_transition(pwrdm);
282         }
283
284 err:
285         return ret;
286 }
287
288 static void omap3_pm_idle(void)
289 {
290         local_irq_disable();
291         local_fiq_disable();
292
293         if (!omap3_can_sleep())
294                 goto out;
295
296         if (omap_irq_pending())
297                 goto out;
298
299         omap_sram_idle();
300
301 out:
302         local_fiq_enable();
303         local_irq_enable();
304 }
305
306 static int omap3_pm_prepare(void)
307 {
308         saved_idle = pm_idle;
309         pm_idle = NULL;
310         return 0;
311 }
312
313 static int omap3_pm_suspend(void)
314 {
315         struct power_state *pwrst;
316         int state, ret = 0;
317
318         /* Read current next_pwrsts */
319         list_for_each_entry(pwrst, &pwrst_list, node)
320                 pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
321         /* Set ones wanted by suspend */
322         list_for_each_entry(pwrst, &pwrst_list, node) {
323                 if (set_pwrdm_state(pwrst->pwrdm, pwrst->next_state))
324                         goto restore;
325                 if (pwrdm_clear_all_prev_pwrst(pwrst->pwrdm))
326                         goto restore;
327         }
328
329         omap_uart_prepare_suspend();
330         omap_sram_idle();
331
332 restore:
333         /* Restore next_pwrsts */
334         list_for_each_entry(pwrst, &pwrst_list, node) {
335                 set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
336                 state = pwrdm_read_prev_pwrst(pwrst->pwrdm);
337                 if (state > pwrst->next_state) {
338                         printk(KERN_INFO "Powerdomain (%s) didn't enter "
339                                "target state %d\n",
340                                pwrst->pwrdm->name, pwrst->next_state);
341                         ret = -1;
342                 }
343         }
344         if (ret)
345                 printk(KERN_ERR "Could not enter target state in pm_suspend\n");
346         else
347                 printk(KERN_INFO "Successfully put all powerdomains "
348                        "to target state\n");
349
350         return ret;
351 }
352
353 static int omap3_pm_enter(suspend_state_t state)
354 {
355         int ret = 0;
356
357         switch (state) {
358         case PM_SUSPEND_STANDBY:
359         case PM_SUSPEND_MEM:
360                 ret = omap3_pm_suspend();
361                 break;
362         default:
363                 ret = -EINVAL;
364         }
365
366         return ret;
367 }
368
369 static void omap3_pm_finish(void)
370 {
371         pm_idle = saved_idle;
372 }
373
374 static struct platform_suspend_ops omap_pm_ops = {
375         .prepare        = omap3_pm_prepare,
376         .enter          = omap3_pm_enter,
377         .finish         = omap3_pm_finish,
378         .valid          = suspend_valid_only_mem,
379 };
380
381 static void __init prcm_setup_regs(void)
382 {
383         /* XXX Reset all wkdeps. This should be done when initializing
384          * powerdomains */
385         prm_write_mod_reg(0, OMAP3430_IVA2_MOD, PM_WKDEP);
386         prm_write_mod_reg(0, MPU_MOD, PM_WKDEP);
387         prm_write_mod_reg(0, OMAP3430_DSS_MOD, PM_WKDEP);
388         prm_write_mod_reg(0, OMAP3430_NEON_MOD, PM_WKDEP);
389         prm_write_mod_reg(0, OMAP3430_CAM_MOD, PM_WKDEP);
390         prm_write_mod_reg(0, OMAP3430_PER_MOD, PM_WKDEP);
391         if (omap_rev() > OMAP3430_REV_ES1_0) {
392                 prm_write_mod_reg(0, OMAP3430ES2_SGX_MOD, PM_WKDEP);
393                 prm_write_mod_reg(0, OMAP3430ES2_USBHOST_MOD, PM_WKDEP);
394         } else
395                 prm_write_mod_reg(0, GFX_MOD, PM_WKDEP);
396
397         /*
398          * Enable interface clock autoidle for all modules.
399          * Note that in the long run this should be done by clockfw
400          */
401         cm_write_mod_reg(
402                 OMAP3430ES2_AUTO_MMC3 |
403                 OMAP3430ES2_AUTO_ICR |
404                 OMAP3430_AUTO_AES2 |
405                 OMAP3430_AUTO_SHA12 |
406                 OMAP3430_AUTO_DES2 |
407                 OMAP3430_AUTO_MMC2 |
408                 OMAP3430_AUTO_MMC1 |
409                 OMAP3430_AUTO_MSPRO |
410                 OMAP3430_AUTO_HDQ |
411                 OMAP3430_AUTO_MCSPI4 |
412                 OMAP3430_AUTO_MCSPI3 |
413                 OMAP3430_AUTO_MCSPI2 |
414                 OMAP3430_AUTO_MCSPI1 |
415                 OMAP3430_AUTO_I2C3 |
416                 OMAP3430_AUTO_I2C2 |
417                 OMAP3430_AUTO_I2C1 |
418                 OMAP3430_AUTO_UART2 |
419                 OMAP3430_AUTO_UART1 |
420                 OMAP3430_AUTO_GPT11 |
421                 OMAP3430_AUTO_GPT10 |
422                 OMAP3430_AUTO_MCBSP5 |
423                 OMAP3430_AUTO_MCBSP1 |
424                 OMAP3430ES1_AUTO_FAC | /* This is es1 only */
425                 OMAP3430_AUTO_MAILBOXES |
426                 OMAP3430_AUTO_OMAPCTRL |
427                 OMAP3430ES1_AUTO_FSHOSTUSB |
428                 OMAP3430_AUTO_HSOTGUSB |
429                 OMAP3430ES1_AUTO_D2D | /* This is es1 only */
430                 OMAP3430_AUTO_SSI,
431                 CORE_MOD, CM_AUTOIDLE1);
432
433         cm_write_mod_reg(
434                 OMAP3430_AUTO_PKA |
435                 OMAP3430_AUTO_AES1 |
436                 OMAP3430_AUTO_RNG |
437                 OMAP3430_AUTO_SHA11 |
438                 OMAP3430_AUTO_DES1,
439                 CORE_MOD, CM_AUTOIDLE2);
440
441         if (omap_rev() > OMAP3430_REV_ES1_0) {
442                 cm_write_mod_reg(
443                         OMAP3430ES2_AUTO_USBTLL,
444                         CORE_MOD, CM_AUTOIDLE3);
445         }
446
447         cm_write_mod_reg(
448                 OMAP3430_AUTO_WDT2 |
449                 OMAP3430_AUTO_WDT1 |
450                 OMAP3430_AUTO_GPIO1 |
451                 OMAP3430_AUTO_32KSYNC |
452                 OMAP3430_AUTO_GPT12 |
453                 OMAP3430_AUTO_GPT1 ,
454                 WKUP_MOD, CM_AUTOIDLE);
455
456         cm_write_mod_reg(
457                 OMAP3430_AUTO_DSS,
458                 OMAP3430_DSS_MOD,
459                 CM_AUTOIDLE);
460
461         cm_write_mod_reg(
462                 OMAP3430_AUTO_CAM,
463                 OMAP3430_CAM_MOD,
464                 CM_AUTOIDLE);
465
466         cm_write_mod_reg(
467                 OMAP3430_AUTO_GPIO6 |
468                 OMAP3430_AUTO_GPIO5 |
469                 OMAP3430_AUTO_GPIO4 |
470                 OMAP3430_AUTO_GPIO3 |
471                 OMAP3430_AUTO_GPIO2 |
472                 OMAP3430_AUTO_WDT3 |
473                 OMAP3430_AUTO_UART3 |
474                 OMAP3430_AUTO_GPT9 |
475                 OMAP3430_AUTO_GPT8 |
476                 OMAP3430_AUTO_GPT7 |
477                 OMAP3430_AUTO_GPT6 |
478                 OMAP3430_AUTO_GPT5 |
479                 OMAP3430_AUTO_GPT4 |
480                 OMAP3430_AUTO_GPT3 |
481                 OMAP3430_AUTO_GPT2 |
482                 OMAP3430_AUTO_MCBSP4 |
483                 OMAP3430_AUTO_MCBSP3 |
484                 OMAP3430_AUTO_MCBSP2,
485                 OMAP3430_PER_MOD,
486                 CM_AUTOIDLE);
487
488         if (omap_rev() > OMAP3430_REV_ES1_0) {
489                 cm_write_mod_reg(
490                         OMAP3430ES2_AUTO_USBHOST,
491                         OMAP3430ES2_USBHOST_MOD,
492                         CM_AUTOIDLE);
493         }
494
495         /*
496          * Set all plls to autoidle. This is needed until autoidle is
497          * enabled by clockfw
498          */
499         cm_write_mod_reg(1 << OMAP3430_AUTO_IVA2_DPLL_SHIFT,
500                          OMAP3430_IVA2_MOD, CM_AUTOIDLE2);
501         cm_write_mod_reg(1 << OMAP3430_AUTO_MPU_DPLL_SHIFT,
502                          MPU_MOD,
503                          CM_AUTOIDLE2);
504         cm_write_mod_reg((1 << OMAP3430_AUTO_PERIPH_DPLL_SHIFT) |
505                          (1 << OMAP3430_AUTO_CORE_DPLL_SHIFT),
506                          PLL_MOD,
507                          CM_AUTOIDLE);
508         cm_write_mod_reg(1 << OMAP3430ES2_AUTO_PERIPH2_DPLL_SHIFT,
509                          PLL_MOD,
510                          CM_AUTOIDLE2);
511
512         /*
513          * Enable control of expternal oscillator through
514          * sys_clkreq. In the long run clock framework should
515          * take care of this.
516          */
517         prm_rmw_mod_reg_bits(OMAP_AUTOEXTCLKMODE_MASK,
518                              1 << OMAP_AUTOEXTCLKMODE_SHIFT,
519                              OMAP3430_GR_MOD,
520                              OMAP3_PRM_CLKSRC_CTRL_OFFSET);
521
522         /* setup wakup source */
523         prm_write_mod_reg(OMAP3430_EN_IO | OMAP3430_EN_GPIO1 |
524                           OMAP3430_EN_GPT1 | OMAP3430_EN_GPT12,
525                           WKUP_MOD, PM_WKEN);
526         /* No need to write EN_IO, that is always enabled */
527         prm_write_mod_reg(OMAP3430_EN_GPIO1 | OMAP3430_EN_GPT1 |
528                           OMAP3430_EN_GPT12,
529                           WKUP_MOD, OMAP3430_PM_MPUGRPSEL);
530         /* For some reason IO doesn't generate wakeup event even if
531          * it is selected to mpu wakeup goup */
532         prm_write_mod_reg(OMAP3430_IO_EN | OMAP3430_WKUP_EN,
533                         OCP_MOD, OMAP2_PRM_IRQENABLE_MPU_OFFSET);
534 }
535
536 static int __init pwrdms_setup(struct powerdomain *pwrdm)
537 {
538         struct power_state *pwrst;
539
540         if (!pwrdm->pwrsts)
541                 return 0;
542
543         pwrst = kmalloc(sizeof(struct power_state), GFP_KERNEL);
544         if (!pwrst)
545                 return -ENOMEM;
546         pwrst->pwrdm = pwrdm;
547         pwrst->next_state = PWRDM_POWER_RET;
548         list_add(&pwrst->node, &pwrst_list);
549
550         if (pwrdm_has_hdwr_sar(pwrdm))
551                 pwrdm_enable_hdwr_sar(pwrdm);
552
553         return set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
554 }
555
556 static int __init clkdms_setup(struct clockdomain *clkdm)
557 {
558         omap2_clkdm_allow_idle(clkdm);
559         return 0;
560 }
561
562 int __init omap3_pm_init(void)
563 {
564         struct power_state *pwrst, *tmp;
565         int ret;
566
567         printk(KERN_ERR "Power Management for TI OMAP3.\n");
568
569         /* XXX prcm_setup_regs needs to be before enabling hw
570          * supervised mode for powerdomains */
571         prcm_setup_regs();
572
573         ret = request_irq(INT_34XX_PRCM_MPU_IRQ,
574                           (irq_handler_t)prcm_interrupt_handler,
575                           IRQF_DISABLED, "prcm", NULL);
576         if (ret) {
577                 printk(KERN_ERR "request_irq failed to register for 0x%x\n",
578                        INT_34XX_PRCM_MPU_IRQ);
579                 goto err1;
580         }
581
582         ret = pwrdm_for_each(pwrdms_setup);
583         if (ret) {
584                 printk(KERN_ERR "Failed to setup powerdomains\n");
585                 goto err2;
586         }
587
588         (void) clkdm_for_each(clkdms_setup);
589
590         mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
591         if (mpu_pwrdm == NULL) {
592                 printk(KERN_ERR "Failed to get mpu_pwrdm\n");
593                 goto err2;
594         }
595
596         _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
597                                         omap34xx_cpu_suspend_sz);
598
599         suspend_set_ops(&omap_pm_ops);
600
601         pm_idle = omap3_pm_idle;
602
603 err1:
604         return ret;
605 err2:
606         free_irq(INT_34XX_PRCM_MPU_IRQ, NULL);
607         list_for_each_entry_safe(pwrst, tmp, &pwrst_list, node) {
608                 list_del(&pwrst->node);
609                 kfree(pwrst);
610         }
611         return ret;
612 }
613
614 static void __init configure_vc(void)
615 {
616         prm_write_mod_reg((R_SRI2C_SLAVE_ADDR << OMAP3430_SMPS_SA1_SHIFT) |
617                         (R_SRI2C_SLAVE_ADDR << OMAP3430_SMPS_SA0_SHIFT),
618                         OMAP3430_GR_MOD, OMAP3_PRM_VC_SMPS_SA_OFFSET);
619         prm_write_mod_reg((R_VDD2_SR_CONTROL << OMAP3430_VOLRA1_SHIFT) |
620                         (R_VDD1_SR_CONTROL << OMAP3430_VOLRA0_SHIFT),
621                         OMAP3430_GR_MOD, OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET);
622
623         prm_write_mod_reg((OMAP3430_VC_CMD_VAL0_ON <<
624                 OMAP3430_VC_CMD_ON_SHIFT) |
625                 (OMAP3430_VC_CMD_VAL0_ONLP << OMAP3430_VC_CMD_ONLP_SHIFT) |
626                 (OMAP3430_VC_CMD_VAL0_RET << OMAP3430_VC_CMD_RET_SHIFT) |
627                 (OMAP3430_VC_CMD_VAL0_OFF << OMAP3430_VC_CMD_OFF_SHIFT),
628                 OMAP3430_GR_MOD, OMAP3_PRM_VC_CMD_VAL_0_OFFSET);
629
630         prm_write_mod_reg((OMAP3430_VC_CMD_VAL1_ON <<
631                 OMAP3430_VC_CMD_ON_SHIFT) |
632                 (OMAP3430_VC_CMD_VAL1_ONLP << OMAP3430_VC_CMD_ONLP_SHIFT) |
633                 (OMAP3430_VC_CMD_VAL1_RET << OMAP3430_VC_CMD_RET_SHIFT) |
634                 (OMAP3430_VC_CMD_VAL1_OFF << OMAP3430_VC_CMD_OFF_SHIFT),
635                 OMAP3430_GR_MOD, OMAP3_PRM_VC_CMD_VAL_1_OFFSET);
636
637         prm_write_mod_reg(OMAP3430_CMD1 | OMAP3430_RAV1,
638                                 OMAP3430_GR_MOD,
639                                 OMAP3_PRM_VC_CH_CONF_OFFSET);
640
641         prm_write_mod_reg(OMAP3430_MCODE_SHIFT | OMAP3430_HSEN | OMAP3430_SREN,
642                                 OMAP3430_GR_MOD,
643                                 OMAP3_PRM_VC_I2C_CFG_OFFSET);
644
645         /* Setup voltctrl and other setup times */
646         prm_write_mod_reg(OMAP3430_AUTO_RET, OMAP3430_GR_MOD,
647                         OMAP3_PRM_VOLTCTRL_OFFSET);
648
649         prm_write_mod_reg(OMAP3430_CLKSETUP_DURATION, OMAP3430_GR_MOD,
650                         OMAP3_PRM_CLKSETUP_OFFSET);
651         prm_write_mod_reg((OMAP3430_VOLTSETUP_TIME2 <<
652                         OMAP3430_SETUP_TIME2_SHIFT) |
653                         (OMAP3430_VOLTSETUP_TIME1 <<
654                         OMAP3430_SETUP_TIME1_SHIFT),
655                         OMAP3430_GR_MOD, OMAP3_PRM_VOLTSETUP1_OFFSET);
656
657         prm_write_mod_reg(OMAP3430_VOLTOFFSET_DURATION, OMAP3430_GR_MOD,
658                         OMAP3_PRM_VOLTOFFSET_OFFSET);
659         prm_write_mod_reg(OMAP3430_VOLTSETUP2_DURATION, OMAP3430_GR_MOD,
660                         OMAP3_PRM_VOLTSETUP2_OFFSET);
661 }
662
663 static int __init omap3_pm_early_init(void)
664 {
665         prm_clear_mod_reg_bits(OMAP3430_OFFMODE_POL, OMAP3430_GR_MOD,
666                                 OMAP3_PRM_POLCTRL_OFFSET);
667
668         configure_vc();
669
670         return 0;
671 }
672
673 arch_initcall(omap3_pm_early_init);