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