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