]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/pm.c
ARM: OMAP: Fix warning in pm.c
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap2 / pm.c
1 /*
2  * linux/arch/arm/mach-omap2/pm.c
3  *
4  * OMAP2 Power Management Routines
5  *
6  * Copyright (C) 2006 Nokia Corporation
7  * Tony Lindgren <tony@atomide.com>
8  *
9  * Fixed suspend-resume/dynamic-idle to get OMAP to retention
10  * Amit Kucheria <amit.kucheria@nokia.com>
11  * Igor Stoppa <igor.stoppa@nokia.com>
12  *
13  * Fixed MPU sleep to get ARM idle
14  * Igor Stoppa <igor.stoppa@nokia.com>
15  *
16  * Fixed MPU sleep some more
17  * Juha Yrjola
18  *
19  * Copyright (C) 2005 Texas Instruments, Inc.
20  * Richard Woodruff <r-woodruff2@ti.com>
21  *
22  * Based on pm.c for omap1
23  *
24  * This program is free software; you can redistribute it and/or modify
25  * it under the terms of the GNU General Public License version 2 as
26  * published by the Free Software Foundation.
27  */
28
29 #include <linux/pm.h>
30 #include <linux/sched.h>
31 #include <linux/proc_fs.h>
32 #include <linux/pm.h>
33 #include <linux/interrupt.h>
34 #include <linux/sysfs.h>
35 #include <linux/module.h>
36 #include <linux/delay.h>
37 #include <linux/clk.h>
38
39 #include <asm/io.h>
40 #include <asm/irq.h>
41 #include <asm/atomic.h>
42 #include <asm/mach/time.h>
43 #include <asm/mach/irq.h>
44 #include <asm/mach-types.h>
45
46 #include <asm/arch/irqs.h>
47 #include <asm/arch/clock.h>
48 #include <asm/arch/sram.h>
49 #include <asm/arch/pm.h>
50 #include <asm/arch/mux.h>
51 #include <asm/arch/dma.h>
52 #include <asm/arch/board.h>
53
54 #define PRCM_BASE               0x48008000
55 #define PRCM_REVISION           0x000
56 #define PRCM_SYSCONFIG          0x010
57 #define PRCM_IRQSTATUS_MPU      0x018
58 #define PRCM_IRQENABLE_MPU      0x01c
59 #define PRCM_VOLTCTRL           0x050
60 #define         AUTO_EXTVOLT    (1 << 15)
61 #define         FORCE_EXTVOLT   (1 << 14)
62 #define         SETOFF_LEVEL(x) (((x) & 0x3) << 12)
63 #define         MEMRETCTRL      (1 << 8)
64 #define         SETRET_LEVEL(x) (((x) & 0x3) << 6)
65 #define         VOLT_LEVEL(x)   (((x) & 0x3) << 0)
66 #define PRCM_CLKSRC_CTRL        0x060
67 #define PRCM_CLKOUT_CTRL        0x070
68 #define PRCM_CLKEMUL_CTRL       0x078
69 #define PRCM_CLKCFG_CTRL        0x080
70 #define PRCM_VOLTSETUP          0x090
71 #define PRCM_CLKSSETUP          0x094
72
73
74 #define CM_CLKSEL_MPU           0x140
75 #define CM_CLKSTCTRL_MPU        0x148
76 #define         AUTOSTAT_MPU    (1 << 0)
77 #define PM_WKDEP_MPU            0x1c8
78 #define         EN_WKUP         (1 << 4)
79 #define         EN_GFX          (1 << 3)
80 #define         EN_DSP          (1 << 2)
81 #define         EN_MPU          (1 << 1)
82 #define         EN_CORE         (1 << 0)
83 #define PM_PWSTCTRL_MPU         0x1e0
84 #define PM_PWSTST_MPU           0x1e4
85
86
87 #define CM_FCLKEN1_CORE         0x200
88 #define CM_FCLKEN2_CORE         0x204
89 #define CM_ICLKEN1_CORE         0x210
90 #define CM_ICLKEN2_CORE         0x214
91 #define CM_ICLKEN4_CORE         0x21c
92 #define CM_IDLEST1_CORE         0x220
93 #define CM_IDLEST2_CORE         0x224
94 #define CM_AUTOIDLE1_CORE       0x230
95 #define CM_AUTOIDLE2_CORE       0x234
96 #define CM_AUTOIDLE3_CORE       0x238
97 #define CM_AUTOIDLE4_CORE       0x23c
98 #define CM_CLKSEL1_CORE         0x240
99 #define CM_CLKSEL2_CORE         0x244
100 #define CM_CLKSTCTRL_CORE       0x248
101 #define         AUTOSTAT_DSS    (1 << 2)
102 #define         AUTOSTAT_L4     (1 << 1)
103 #define         AUTOSTAT_L3     (1 << 0)
104 #define PM_WKEN1_CORE           0x2a0
105 #define PM_WKEN2_CORE           0x2a4
106 #define PM_WKST1_CORE           0x2b0
107 #define PM_WKST2_CORE           0x2b4
108 #define PM_WKDEP_CORE           0x2c8
109 #define PM_PWSTCTRL_CORE        0x2e0
110 #define PM_PWSTST_CORE          0x2e4
111
112
113 #define CM_CLKSTCTRL_GFX        0x348
114 #define         AUTOSTAT_GFX    (1 << 0)
115 #define PM_WKDEP_GFX            0x3c8
116 #define PM_PWSTCTRL_GFX         0x3e0
117
118
119 #define CM_FCLKEN_WKUP          0x400
120 #define CM_ICLKEN_WKUP          0x410
121 #define CM_AUTOIDLE_WKUP        0x430
122 #define PM_WKEN_WKUP            0x4a0
123 #define         EN_GPIOS        (1 << 2)
124 #define         EN_GPT1         (1 << 0)
125 #define PM_WKST_WKUP            0x4b0
126
127
128 #define CM_CLKEN_PLL            0x500
129 #define CM_IDLEST_CKGEN         0x520
130 #define CM_AUTOIDLE_PLL         0x530
131 #define CM_CLKSEL1_PLL          0x540
132 #define CM_CLKSEL2_PLL          0x544
133
134
135 #define CM_FCLKEN_DSP           0x800
136 #define CM_ICLKEN_DSP           0x810
137 #define CM_IDLEST_DSP           0x820
138 #define CM_AUTOIDLE_DSP         0x830
139 #define CM_CLKSEL_DSP           0x840
140 #define CM_CLKSTCTRL_DSP        0x848
141 #define         AUTOSTAT_IVA    (1 << 8)
142 #define         AUTOSTAT_DSP    (1 << 0)
143 #define RM_RSTCTRL_DSP          0x850
144 #define RM_RSTST_DSP            0x858
145 #define PM_WKDEP_DSP            0x8c8
146 #define PM_PWSTCTRL_DSP         0x8e0
147 #define PM_PWSTST_DSP           0x8e4
148
149 static void (*omap2_sram_idle)(void);
150 static void (*omap2_sram_suspend)(int dllctrl);
151 static void (*saved_idle)(void);
152
153 static u32 prcm_base = IO_ADDRESS(PRCM_BASE);
154
155 static inline void prcm_write_reg(int idx, u32 val)
156 {
157         __raw_writel(val, prcm_base + idx);
158 }
159
160 static inline u32 prcm_read_reg(int idx)
161 {
162         return __raw_readl(prcm_base + idx);
163 }
164
165 static u32 omap2_read_32k_sync_counter(void)
166 {
167         return omap_readl(0x48004010);
168 }
169
170 #ifdef CONFIG_PM_DEBUG
171 int omap2_pm_debug = 0;
172
173 static int serial_console_clock_disabled;
174 static int serial_console_uart;
175 static unsigned int serial_console_next_disable;
176
177 static struct clk *console_iclk, *console_fclk;
178
179 static void serial_console_kick(void)
180 {
181         serial_console_next_disable = omap2_read_32k_sync_counter();
182         /* Keep the clocks on for 4 secs */
183         serial_console_next_disable += 4 * 32768;
184 }
185
186 static void serial_wait_tx(void)
187 {
188         static const unsigned long uart_bases[3] = {
189                 0x4806a000, 0x4806c000, 0x4806e000
190         };
191         unsigned long lsr_reg;
192         int looped = 0;
193
194         /* Wait for TX FIFO and THR to get empty */
195         lsr_reg = IO_ADDRESS(uart_bases[serial_console_uart - 1] + (5 << 2));
196         while ((__raw_readb(lsr_reg) & 0x60) != 0x60)
197                 looped = 1;
198         if (looped)
199                 serial_console_kick();
200 }
201
202 static void serial_console_fclk_mask(u32 *f1, u32 *f2)
203 {
204         switch (serial_console_uart)  {
205         case 1:
206                 *f1 &= ~(1 << 21);
207                 break;
208         case 2:
209                 *f1 &= ~(1 << 22);
210                 break;
211         case 3:
212                 *f2 &= ~(1 << 2);
213                 break;
214         }
215 }
216
217 static void serial_console_sleep(int enable)
218 {
219         if (console_iclk == NULL || console_fclk == NULL)
220                 return;
221
222         if (enable) {
223                 BUG_ON(serial_console_clock_disabled);
224                 if (clk_get_usecount(console_fclk) == 0)
225                         return;
226                 if ((int) serial_console_next_disable - (int) omap2_read_32k_sync_counter() >= 0)
227                         return;
228                 serial_wait_tx();
229                 clk_disable(console_iclk);
230                 clk_disable(console_fclk);
231                 serial_console_clock_disabled = 1;
232         } else {
233                 int serial_wakeup = 0;
234                 u32 l;
235
236                 switch (serial_console_uart)  {
237                 case 1:
238                         l = prcm_read_reg(PM_WKST1_CORE);
239                         if (l & (1 << 21))
240                                 serial_wakeup = 1;
241                         break;
242                 case 2:
243                         l = prcm_read_reg(PM_WKST1_CORE);
244                         if (l & (1 << 22))
245                                 serial_wakeup = 1;
246                         break;
247                 case 3:
248                         l = prcm_read_reg(PM_WKST2_CORE);
249                         if (l & (1 << 2))
250                                 serial_wakeup = 1;
251                         break;
252                 }
253                 if (serial_wakeup)
254                         serial_console_kick();
255                 if (!serial_console_clock_disabled)
256                         return;
257                 clk_enable(console_iclk);
258                 clk_enable(console_fclk);
259                 serial_console_clock_disabled = 0;
260         }
261 }
262
263 static void pm_init_serial_console(void)
264 {
265         const struct omap_serial_console_config *conf;
266         char name[16];
267         u32 l;
268
269         conf = omap_get_config(OMAP_TAG_SERIAL_CONSOLE,
270                                struct omap_serial_console_config);
271         if (conf == NULL)
272                 return;
273         if (conf->console_uart > 3 || conf->console_uart < 1)
274                 return;
275         serial_console_uart = conf->console_uart;
276         sprintf(name, "uart%d_fck", conf->console_uart);
277         console_fclk = clk_get(NULL, name);
278         if (IS_ERR(console_fclk))
279                 console_fclk = NULL;
280         name[6] = 'i';
281         console_iclk = clk_get(NULL, name);
282         if (IS_ERR(console_fclk))
283                 console_iclk = NULL;
284         if (console_fclk == NULL || console_iclk == NULL) {
285                 serial_console_uart = 0;
286                 return;
287         }
288         switch (serial_console_uart) {
289         case 1:
290                 l = prcm_read_reg(PM_WKEN1_CORE);
291                 l |= 1 << 21;
292                 prcm_write_reg(PM_WKEN1_CORE, l);
293                 break;
294         case 2:
295                 l = prcm_read_reg(PM_WKEN1_CORE);
296                 l |= 1 << 22;
297                 prcm_write_reg(PM_WKEN1_CORE, l);
298                 break;
299         case 3:
300                 l = prcm_read_reg(PM_WKEN2_CORE);
301                 l |= 1 << 2;
302                 prcm_write_reg(PM_WKEN2_CORE, l);
303                 break;
304         }
305 }
306
307 #define DUMP_REG(reg) \
308         regs[reg_count].name = #reg; \
309         regs[reg_count++].val = prcm_read_reg(reg)
310 #define DUMP_INTC_REG(reg, off) \
311         regs[reg_count].name = #reg; \
312         regs[reg_count++].val = __raw_readl(IO_ADDRESS(0x480fe000 + (off)))
313
314 static void omap2_pm_dump(int mode, int resume, unsigned int us)
315 {
316         struct reg {
317                 const char *name;
318                 u32 val;
319         } regs[32];
320         int reg_count = 0, i;
321         const char *s1 = NULL, *s2 = NULL;
322
323         if (!resume) {
324 #if 0
325                 /* MPU */
326                 DUMP_REG(PRCM_IRQENABLE_MPU);
327                 DUMP_REG(CM_CLKSTCTRL_MPU);
328                 DUMP_REG(PM_PWSTCTRL_MPU);
329                 DUMP_REG(PM_PWSTST_MPU);
330                 DUMP_REG(PM_WKDEP_MPU);
331 #endif
332 #if 0
333                 /* INTC */
334                 DUMP_INTC_REG(INTC_MIR0, 0x0084);
335                 DUMP_INTC_REG(INTC_MIR1, 0x00a4);
336                 DUMP_INTC_REG(INTC_MIR2, 0x00c4);
337 #endif
338 #if 0
339                 DUMP_REG(CM_FCLKEN1_CORE);
340                 DUMP_REG(CM_FCLKEN2_CORE);
341                 DUMP_REG(CM_FCLKEN_WKUP);
342                 DUMP_REG(CM_ICLKEN1_CORE);
343                 DUMP_REG(CM_ICLKEN2_CORE);
344                 DUMP_REG(CM_ICLKEN_WKUP);
345                 DUMP_REG(CM_CLKEN_PLL);
346                 DUMP_REG(PRCM_CLKEMUL_CTRL);
347                 DUMP_REG(CM_AUTOIDLE_PLL);
348                 DUMP_REG(PM_PWSTST_CORE);
349                 DUMP_REG(PRCM_CLKSRC_CTRL);
350 #endif
351 #if 0
352                 /* DSP */
353                 DUMP_REG(CM_FCLKEN_DSP);
354                 DUMP_REG(CM_ICLKEN_DSP);
355                 DUMP_REG(CM_IDLEST_DSP);
356                 DUMP_REG(CM_AUTOIDLE_DSP);
357                 DUMP_REG(CM_CLKSEL_DSP);
358                 DUMP_REG(CM_CLKSTCTRL_DSP);
359                 DUMP_REG(RM_RSTCTRL_DSP);
360                 DUMP_REG(RM_RSTST_DSP);
361                 DUMP_REG(PM_PWSTCTRL_DSP);
362                 DUMP_REG(PM_PWSTST_DSP);
363 #endif
364         } else {
365                 DUMP_REG(PM_WKST1_CORE);
366                 DUMP_REG(PM_WKST2_CORE);
367                 DUMP_REG(PM_WKST_WKUP);
368                 DUMP_REG(PRCM_IRQSTATUS_MPU);
369 #if 1
370                 DUMP_INTC_REG(INTC_PENDING_IRQ0, 0x0098);
371                 DUMP_INTC_REG(INTC_PENDING_IRQ1, 0x00b8);
372                 DUMP_INTC_REG(INTC_PENDING_IRQ2, 0x00d8);
373 #endif
374         }
375
376         switch (mode) {
377         case 0:
378                 s1 = "full";
379                 s2 = "retention";
380                 break;
381         case 1:
382                 s1 = "MPU";
383                 s2 = "retention";
384                 break;
385         case 2:
386                 s1 = "MPU";
387                 s2 = "idle";
388                 break;
389         }
390
391         if (!resume)
392                 printk("--- Going to %s %s (next timer after %u ms)\n", s1, s2,
393                        jiffies_to_msecs(next_timer_interrupt() - jiffies));
394         else
395                 printk("--- Woke up (slept for %u.%03u ms)\n", us / 1000, us % 1000);
396         for (i = 0; i < reg_count; i++)
397                 printk("%-20s: 0x%08x\n", regs[i].name, regs[i].val);
398 }
399
400 #else
401 static inline void serial_console_sleep(int enable) {}
402 static inline void pm_init_serial_console(void) {}
403 static inline void omap2_pm_dump(int mode, int resume, unsigned int us) {}
404 static inline void serial_console_fclk_mask(u32 *f1, u32 *f2) {}
405
406 #define omap2_pm_debug 0
407
408 #endif
409
410 static unsigned short enable_dyn_sleep = 0; /* disabled till drivers are fixed */
411
412 static ssize_t omap_pm_sleep_while_idle_show(struct subsystem * subsys, char *buf)
413 {
414         return sprintf(buf, "%hu\n", enable_dyn_sleep);
415 }
416
417 static ssize_t omap_pm_sleep_while_idle_store(struct subsystem * subsys,
418                                               const char * buf,
419                                               size_t n)
420 {
421         unsigned short value;
422         if (sscanf(buf, "%hu", &value) != 1 ||
423             (value != 0 && value != 1)) {
424                 printk(KERN_ERR "idle_sleep_store: Invalid value\n");
425                 return -EINVAL;
426         }
427         enable_dyn_sleep = value;
428         return n;
429 }
430
431 static struct subsys_attribute sleep_while_idle_attr = {
432         .attr   = {
433                 .name = __stringify(sleep_while_idle),
434                 .mode = 0644,
435         },
436         .show   = omap_pm_sleep_while_idle_show,
437         .store  = omap_pm_sleep_while_idle_store,
438 };
439
440 extern struct subsystem power_subsys;
441
442 static struct clk *osc_ck, *emul_ck;
443
444 #define CONTROL_DEVCONF         __REG32(0x48000274)
445 #define SDRC_DLLA_CTRL          __REG32(0x68009060)
446
447 static int omap2_fclks_active(void)
448 {
449         u32 f1, f2;
450
451         f1 = prcm_read_reg(CM_FCLKEN1_CORE);
452         f2 = prcm_read_reg(CM_FCLKEN2_CORE);
453         serial_console_fclk_mask(&f1, &f2);
454         if (f1 | f2)
455                 return 1;
456         return 0;
457 }
458
459 static int omap2_irq_pending(void)
460 {
461         u32 pending_reg = IO_ADDRESS(0x480fe098);
462         int i;
463
464         for (i = 0; i < 4; i++) {
465                 if (__raw_readl(pending_reg))
466                         return 1;
467                 pending_reg += 0x20;
468         }
469         return 0;
470 }
471
472 static atomic_t sleep_block = ATOMIC_INIT(0);
473
474 void omap2_block_sleep(void)
475 {
476         atomic_inc(&sleep_block);
477 }
478
479 void omap2_allow_sleep(void)
480 {
481         int i;
482
483         i = atomic_dec_return(&sleep_block);
484         BUG_ON(i < 0);
485 }
486
487 extern void omap2_gpio_prepare_for_retention(void);
488 extern void omap2_gpio_resume_after_retention(void);
489
490 static void omap2_enter_full_retention(void)
491 {
492         u32 sleep_time = 0;
493
494         /* There is 1 reference hold for all children of the oscillator
495          * clock, the following will remove it. If no one else uses the
496          * oscillator itself it will be disabled if/when we enter retention
497          * mode.
498          */
499         clk_disable(osc_ck);
500
501         /* Clear old wake-up events */
502         prcm_write_reg(PM_WKST1_CORE, 0xffffffff);
503         prcm_write_reg(PM_WKST2_CORE, 0xffffffff);
504         prcm_write_reg(PM_WKST_WKUP, 0xffffffff);
505
506         /* Try to enter retention */
507         prcm_write_reg(PM_PWSTCTRL_MPU, (0x01 << 0) | (1 << 2));
508
509         /* Workaround to kill USB */
510         CONTROL_DEVCONF |= 0x00008000;
511
512         omap2_gpio_prepare_for_retention();
513
514         if (omap2_pm_debug) {
515                 omap2_pm_dump(0, 0, 0);
516                 sleep_time = omap2_read_32k_sync_counter();
517         }
518
519         /* One last check for pending IRQs to avoid extra latency due
520          * to sleeping unnecessarily. */
521         if (omap2_irq_pending())
522                 goto no_sleep;
523
524         serial_console_sleep(1);
525         /* Jump to SRAM suspend code */
526         omap2_sram_suspend(SDRC_DLLA_CTRL);
527 no_sleep:
528         serial_console_sleep(0);
529
530         if (omap2_pm_debug) {
531                 unsigned long long tmp;
532                 u32 resume_time;
533
534                 resume_time = omap2_read_32k_sync_counter();
535                 tmp = resume_time - sleep_time;
536                 tmp *= 1000000;
537                 omap2_pm_dump(0, 1, tmp / 32768);
538         }
539         omap2_gpio_resume_after_retention();
540
541         clk_enable(osc_ck);
542
543 }
544
545 static int omap2_i2c_active(void)
546 {
547         u32 l;
548
549         l = prcm_read_reg(CM_FCLKEN1_CORE);
550         return l & ((1 << 19) | (1 << 20));
551 }
552
553 static int sti_console_enabled;
554
555 static int omap2_allow_mpu_retention(void)
556 {
557         u32 l;
558
559         if (atomic_read(&sleep_block))
560                 return 0;
561
562         /* Check for UART2, UART1, McSPI2, McSPI1 and DSS1. */
563         l = prcm_read_reg(CM_FCLKEN1_CORE);
564         if (l & 0x04660001)
565                 return 0;
566         /* Check for UART3. */
567         l = prcm_read_reg(CM_FCLKEN2_CORE);
568         if (l & (1 << 2))
569                 return 0;
570         if (sti_console_enabled)
571                 return 0;
572
573         /* FIXME: Enable soon */
574         return 0;
575 }
576
577 static void omap2_enter_mpu_retention(void)
578 {
579         u32 sleep_time = 0;
580         int only_idle = 0;
581
582         /* Putting MPU into the WFI state while a transfer is active
583          * seems to cause the I2C block to timeout. Why? Good question. */
584         if (omap2_i2c_active())
585                 return;
586
587         /* The peripherals seem not to be able to wake up the MPU when
588          * it is in retention mode. */
589         if (omap2_allow_mpu_retention()) {
590                 prcm_write_reg(PM_WKST1_CORE, 0xffffffff);
591                 prcm_write_reg(PM_WKST2_CORE, 0xffffffff);
592                 prcm_write_reg(PM_WKST_WKUP, 0xffffffff);
593
594                 /* Try to enter MPU retention */
595                 prcm_write_reg(PM_PWSTCTRL_MPU, (0x01 << 0) | (1 << 2));
596         } else {
597                 /* Block MPU retention */
598                 prcm_write_reg(PM_PWSTCTRL_MPU, 1 << 2);
599                 only_idle = 1;
600         }
601
602         if (omap2_pm_debug) {
603                 omap2_pm_dump(only_idle ? 2 : 1, 0, 0);
604                 sleep_time = omap2_read_32k_sync_counter();
605         }
606
607         omap2_sram_idle();
608
609         if (omap2_pm_debug) {
610                 unsigned long long tmp;
611                 u32 resume_time;
612
613                 resume_time = omap2_read_32k_sync_counter();
614                 tmp = resume_time - sleep_time;
615                 tmp *= 1000000;
616                 omap2_pm_dump(only_idle ? 2 : 1, 1, tmp / 32768);
617         }
618 }
619
620 static int omap2_can_sleep(void)
621 {
622         if (!enable_dyn_sleep)
623                 return 0;
624         if (omap2_fclks_active())
625                 return 0;
626         if (atomic_read(&sleep_block) > 0)
627                 return 0;
628         if (clk_get_usecount(osc_ck) > 1)
629                 return 0;
630         if (omap_dma_running())
631                 return 0;
632
633         return 1;
634 }
635
636 static void omap2_pm_idle(void)
637 {
638         local_irq_disable();
639         local_fiq_disable();
640
641         if (!omap2_can_sleep()) {
642                 /* timer_dyn_reprogram() takes about 100-200 us to complete.
643                  * In some contexts (e.g. when waiting for a GPMC-SDRAM DMA
644                  * transfer to complete), the increased latency is too much.
645                  *
646                  * omap2_block_sleep() and omap2_allow_sleep() can be used
647                  * to indicate this.
648                  */
649                 if (atomic_read(&sleep_block) == 0) {
650                         timer_dyn_reprogram();
651                         if (omap2_irq_pending())
652                                 goto out;
653                 }
654                 omap2_enter_mpu_retention();
655                 goto out;
656         }
657
658         /*
659          * Since an interrupt may set up a timer, we don't want to
660          * reprogram the hardware timer with interrupts enabled.
661          * Re-enable interrupts only after returning from idle.
662          */
663         timer_dyn_reprogram();
664
665         if (omap2_irq_pending())
666                 goto out;
667
668         omap2_enter_full_retention();
669
670 out:
671         local_fiq_enable();
672         local_irq_enable();
673 }
674
675 static int omap2_pm_prepare(suspend_state_t state)
676 {
677         int error = 0;
678
679         /* We cannot sleep in idle until we have resumed */
680         saved_idle = pm_idle;
681         pm_idle = NULL;
682
683         switch (state) {
684         case PM_SUSPEND_STANDBY:
685         case PM_SUSPEND_MEM:
686                 break;
687         case PM_SUSPEND_DISK:
688                 return -ENOTSUPP;
689         default:
690                 return -EINVAL;
691         }
692
693         return error;
694 }
695
696 static int omap2_pm_suspend(void)
697 {
698         u32 wken_wkup, mir1;
699
700         wken_wkup = prcm_read_reg(PM_WKEN_WKUP);
701         prcm_write_reg(PM_WKEN_WKUP, wken_wkup & ~EN_GPT1);
702
703         /* Mask GPT1 */
704         mir1 = omap_readl(0x480fe0a4);
705         omap_writel(1 << 5, 0x480fe0ac);
706
707         omap2_enter_full_retention();
708
709         omap_writel(mir1, 0x480fe0a4);
710         prcm_write_reg(PM_WKEN_WKUP, wken_wkup);
711
712         return 0;
713 }
714
715 static int omap2_pm_enter(suspend_state_t state)
716 {
717         int ret = 0;
718
719         switch (state) {
720         case PM_SUSPEND_STANDBY:
721         case PM_SUSPEND_MEM:
722                 ret = omap2_pm_suspend();
723                 break;
724         case PM_SUSPEND_DISK:
725                 ret = -ENOTSUPP;
726                 break;
727         default:
728                 ret = -EINVAL;
729         }
730
731         return ret;
732 }
733
734 static int omap2_pm_finish(suspend_state_t state)
735 {
736         pm_idle = saved_idle;
737         return 0;
738 }
739
740 static struct pm_ops omap_pm_ops = {
741         .pm_disk_mode   = 0,
742         .prepare        = omap2_pm_prepare,
743         .enter          = omap2_pm_enter,
744         .finish         = omap2_pm_finish,
745 };
746
747 static void __init prcm_setup_regs(void)
748 {
749         u32 l;
750
751         /* Enable autoidle */
752         prcm_write_reg(PRCM_SYSCONFIG, 1 << 0);
753
754         /* Set all domain wakeup dependencies */
755         prcm_write_reg(PM_WKDEP_MPU, EN_WKUP);
756         prcm_write_reg(PM_WKDEP_DSP, 0);
757         prcm_write_reg(PM_WKDEP_GFX, 0);
758
759         l = prcm_read_reg(PM_PWSTCTRL_CORE);
760         /* Enable retention for all memory blocks */
761         l |= (1 << 3) | (1 << 4) | (1 << 5);
762         /* Set power state to RETENTION */
763         l &= ~0x03;
764         l |= 0x01 << 0;
765         prcm_write_reg(PM_PWSTCTRL_CORE, l);
766
767         prcm_write_reg(PM_PWSTCTRL_MPU, (0x01 << 0) | (1 << 2));
768
769         /* Power down DSP and GFX */
770         prcm_write_reg(PM_PWSTCTRL_DSP, (1 << 18) | 0x03);
771         prcm_write_reg(PM_PWSTCTRL_GFX, (1 << 18) | 0x03);
772
773         /* Enable clock auto control for all domains */
774         prcm_write_reg(CM_CLKSTCTRL_MPU, AUTOSTAT_MPU);
775         prcm_write_reg(CM_CLKSTCTRL_CORE, AUTOSTAT_DSS | AUTOSTAT_L4 | AUTOSTAT_L3);
776         prcm_write_reg(CM_CLKSTCTRL_GFX, AUTOSTAT_GFX);
777         prcm_write_reg(CM_CLKSTCTRL_DSP, AUTOSTAT_IVA | AUTOSTAT_DSP);
778
779         /* Enable clock autoidle for all domains */
780         prcm_write_reg(CM_AUTOIDLE1_CORE, 0xfffffff9);
781         prcm_write_reg(CM_AUTOIDLE2_CORE, 0x07);
782         prcm_write_reg(CM_AUTOIDLE3_CORE, 0x07);
783         prcm_write_reg(CM_AUTOIDLE4_CORE, 0x1f);
784
785         prcm_write_reg(CM_AUTOIDLE_DSP, 0x02);
786
787         /* Put DPLL and both APLLs into autoidle mode */
788         prcm_write_reg(CM_AUTOIDLE_PLL, (0x03 << 0) | (0x03 << 2) | (0x03 << 6));
789
790         prcm_write_reg(CM_AUTOIDLE_WKUP, 0x3f);
791
792         /* REVISIT: Configure number of 32 kHz clock cycles for sys_clk
793          * stabilisation */
794         prcm_write_reg(PRCM_CLKSSETUP, 15);
795
796         /* Configure automatic voltage transition */
797         prcm_write_reg(PRCM_VOLTSETUP, 2);
798         l = AUTO_EXTVOLT | SETOFF_LEVEL(1) | MEMRETCTRL | \
799                 SETRET_LEVEL(1) | VOLT_LEVEL(0);
800         prcm_write_reg(PRCM_VOLTCTRL, l);
801
802         /* Enable wake-up events */
803         prcm_write_reg(PM_WKEN_WKUP, EN_GPIOS | EN_GPT1);
804 }
805
806 int __init omap2_pm_init(void)
807 {
808         u32 l;
809
810         printk(KERN_INFO "Power Management for OMAP2 initializing\n");
811         l = prcm_read_reg(PRCM_REVISION);
812         printk(KERN_INFO "PRCM revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
813
814         osc_ck = clk_get(NULL, "osc_ck");
815         if (IS_ERR(osc_ck)) {
816                 printk(KERN_ERR "could not get osc_ck\n");
817                 return -ENODEV;
818         }
819
820         emul_ck = clk_get(NULL, "emul_ck");
821         if (IS_ERR(emul_ck)) {
822                 printk(KERN_ERR "could not get emul_ck\n");
823                 clk_put(osc_ck);
824                 return -ENODEV;
825         }
826
827         prcm_setup_regs();
828
829         pm_init_serial_console();
830
831         /* Hack to prevent MPU retention when STI console is enabled. */
832         {
833                 const struct omap_sti_console_config *sti;
834
835                 sti = omap_get_config(OMAP_TAG_STI_CONSOLE,
836                                       struct omap_sti_console_config);
837                 if (sti != NULL && sti->enable)
838                         sti_console_enabled = 1;
839         }
840
841         /*
842          * We copy the assembler sleep/wakeup routines to SRAM.
843          * These routines need to be in SRAM as that's the only
844          * memory the MPU can see when it wakes up.
845          */
846         omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend,
847                                          omap24xx_idle_loop_suspend_sz);
848         omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,
849                                             omap24xx_cpu_suspend_sz);
850
851         pm_set_ops(&omap_pm_ops);
852         pm_idle = omap2_pm_idle;
853
854         l = subsys_create_file(&power_subsys, &sleep_while_idle_attr);
855         if (l)
856                 printk(KERN_ERR "subsys_create_file failed: %d\n", l);
857
858         return 0;
859 }
860
861 late_initcall(omap2_pm_init);