diff options
Diffstat (limited to 'arch/arm/plat-omap/pm.c')
-rw-r--r-- | arch/arm/plat-omap/pm.c | 255 |
1 files changed, 116 insertions, 139 deletions
diff --git a/arch/arm/plat-omap/pm.c b/arch/arm/plat-omap/pm.c index e6536b16c385..e15c6c1ddec9 100644 --- a/arch/arm/plat-omap/pm.c +++ b/arch/arm/plat-omap/pm.c | |||
@@ -39,24 +39,32 @@ | |||
39 | #include <linux/sched.h> | 39 | #include <linux/sched.h> |
40 | #include <linux/proc_fs.h> | 40 | #include <linux/proc_fs.h> |
41 | #include <linux/pm.h> | 41 | #include <linux/pm.h> |
42 | #include <linux/interrupt.h> | ||
42 | 43 | ||
43 | #include <asm/io.h> | 44 | #include <asm/io.h> |
45 | #include <asm/irq.h> | ||
44 | #include <asm/mach/time.h> | 46 | #include <asm/mach/time.h> |
45 | #include <asm/mach-types.h> | 47 | #include <asm/mach/irq.h> |
46 | 48 | ||
47 | #include <asm/arch/omap16xx.h> | 49 | #include <asm/mach-types.h> |
50 | #include <asm/arch/irqs.h> | ||
51 | #include <asm/arch/tc.h> | ||
48 | #include <asm/arch/pm.h> | 52 | #include <asm/arch/pm.h> |
49 | #include <asm/arch/mux.h> | 53 | #include <asm/arch/mux.h> |
50 | #include <asm/arch/tc.h> | ||
51 | #include <asm/arch/tps65010.h> | 54 | #include <asm/arch/tps65010.h> |
55 | #include <asm/arch/dsp_common.h> | ||
52 | 56 | ||
53 | #include "clock.h" | 57 | #include "clock.h" |
58 | #include "sram.h" | ||
54 | 59 | ||
55 | static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE]; | 60 | static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE]; |
56 | static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE]; | 61 | static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE]; |
57 | static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE]; | 62 | static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE]; |
58 | static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; | 63 | static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; |
59 | 64 | ||
65 | static void (*omap_sram_idle)(void) = NULL; | ||
66 | static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL; | ||
67 | |||
60 | /* | 68 | /* |
61 | * Let's power down on idle, but only if we are really | 69 | * Let's power down on idle, but only if we are really |
62 | * idle, because once we start down the path of | 70 | * idle, because once we start down the path of |
@@ -65,7 +73,6 @@ static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; | |||
65 | */ | 73 | */ |
66 | void omap_pm_idle(void) | 74 | void omap_pm_idle(void) |
67 | { | 75 | { |
68 | int (*func_ptr)(void) = 0; | ||
69 | unsigned int mask32 = 0; | 76 | unsigned int mask32 = 0; |
70 | 77 | ||
71 | /* | 78 | /* |
@@ -84,6 +91,13 @@ void omap_pm_idle(void) | |||
84 | mask32 = omap_readl(ARM_SYSST); | 91 | mask32 = omap_readl(ARM_SYSST); |
85 | 92 | ||
86 | /* | 93 | /* |
94 | * Prevent the ULPD from entering low power state by setting | ||
95 | * POWER_CTRL_REG:4 = 0 | ||
96 | */ | ||
97 | omap_writew(omap_readw(ULPD_POWER_CTRL) & | ||
98 | ~ULPD_DEEP_SLEEP_TRANSITION_EN, ULPD_POWER_CTRL); | ||
99 | |||
100 | /* | ||
87 | * Since an interrupt may set up a timer, we don't want to | 101 | * Since an interrupt may set up a timer, we don't want to |
88 | * reprogram the hardware timer with interrupts enabled. | 102 | * reprogram the hardware timer with interrupts enabled. |
89 | * Re-enable interrupts only after returning from idle. | 103 | * Re-enable interrupts only after returning from idle. |
@@ -92,18 +106,9 @@ void omap_pm_idle(void) | |||
92 | 106 | ||
93 | if ((mask32 & DSP_IDLE) == 0) { | 107 | if ((mask32 & DSP_IDLE) == 0) { |
94 | __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4"); | 108 | __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4"); |
95 | } else { | 109 | } else |
96 | 110 | omap_sram_idle(); | |
97 | if (cpu_is_omap1510()) { | ||
98 | func_ptr = (void *)(OMAP1510_SRAM_IDLE_SUSPEND); | ||
99 | } else if (cpu_is_omap1610() || cpu_is_omap1710()) { | ||
100 | func_ptr = (void *)(OMAP1610_SRAM_IDLE_SUSPEND); | ||
101 | } else if (cpu_is_omap5912()) { | ||
102 | func_ptr = (void *)(OMAP5912_SRAM_IDLE_SUSPEND); | ||
103 | } | ||
104 | 111 | ||
105 | func_ptr(); | ||
106 | } | ||
107 | local_fiq_enable(); | 112 | local_fiq_enable(); |
108 | local_irq_enable(); | 113 | local_irq_enable(); |
109 | } | 114 | } |
@@ -115,58 +120,55 @@ void omap_pm_idle(void) | |||
115 | */ | 120 | */ |
116 | static void omap_pm_wakeup_setup(void) | 121 | static void omap_pm_wakeup_setup(void) |
117 | { | 122 | { |
118 | /* | 123 | u32 level1_wake = OMAP_IRQ_BIT(INT_IH2_IRQ); |
119 | * Enable ARM XOR clock and release peripheral from reset by | 124 | u32 level2_wake = OMAP_IRQ_BIT(INT_UART2) | OMAP_IRQ_BIT(INT_KEYBOARD); |
120 | * writing 1 to PER_EN bit in ARM_RSTCT2, this is required | ||
121 | * for UART configuration to use UART2 to wake up. | ||
122 | */ | ||
123 | |||
124 | omap_writel(omap_readl(ARM_IDLECT2) | ENABLE_XORCLK, ARM_IDLECT2); | ||
125 | omap_writel(omap_readl(ARM_RSTCT2) | PER_EN, ARM_RSTCT2); | ||
126 | omap_writew(MODEM_32K_EN, ULPD_CLOCK_CTRL); | ||
127 | 125 | ||
128 | /* | 126 | /* |
129 | * Turn off all interrupts except L1-2nd level cascade, | 127 | * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade, |
130 | * and the L2 wakeup interrupts: keypad and UART2. | 128 | * and the L2 wakeup interrupts: keypad and UART2. Note that the |
129 | * drivers must still separately call omap_set_gpio_wakeup() to | ||
130 | * wake up to a GPIO interrupt. | ||
131 | */ | 131 | */ |
132 | if (cpu_is_omap1510() || cpu_is_omap16xx()) | ||
133 | level1_wake |= OMAP_IRQ_BIT(INT_GPIO_BANK1); | ||
134 | else if (cpu_is_omap730()) | ||
135 | level1_wake |= OMAP_IRQ_BIT(INT_730_GPIO_BANK1); | ||
132 | 136 | ||
133 | omap_writel(~IRQ_LEVEL2, OMAP_IH1_MIR); | 137 | omap_writel(~level1_wake, OMAP_IH1_MIR); |
134 | 138 | ||
135 | if (cpu_is_omap1510()) { | 139 | if (cpu_is_omap1510()) |
136 | omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD), OMAP_IH2_MIR); | 140 | omap_writel(~level2_wake, OMAP_IH2_MIR); |
137 | } | ||
138 | 141 | ||
142 | /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */ | ||
139 | if (cpu_is_omap16xx()) { | 143 | if (cpu_is_omap16xx()) { |
140 | omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD), OMAP_IH2_0_MIR); | 144 | omap_writel(~level2_wake, OMAP_IH2_0_MIR); |
141 | 145 | omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), OMAP_IH2_1_MIR); | |
142 | omap_writel(~0x0, OMAP_IH2_1_MIR); | ||
143 | omap_writel(~0x0, OMAP_IH2_2_MIR); | 146 | omap_writel(~0x0, OMAP_IH2_2_MIR); |
144 | omap_writel(~0x0, OMAP_IH2_3_MIR); | 147 | omap_writel(~0x0, OMAP_IH2_3_MIR); |
145 | } | 148 | } |
146 | 149 | ||
147 | /* New IRQ agreement */ | 150 | /* New IRQ agreement, recalculate in cascade order */ |
151 | omap_writel(1, OMAP_IH2_CONTROL); | ||
148 | omap_writel(1, OMAP_IH1_CONTROL); | 152 | omap_writel(1, OMAP_IH1_CONTROL); |
149 | |||
150 | /* external PULL to down, bit 22 = 0 */ | ||
151 | omap_writel(omap_readl(PULL_DWN_CTRL_2) & ~(1<<22), PULL_DWN_CTRL_2); | ||
152 | } | 153 | } |
153 | 154 | ||
154 | void omap_pm_suspend(void) | 155 | void omap_pm_suspend(void) |
155 | { | 156 | { |
156 | unsigned int mask32 = 0; | ||
157 | unsigned long arg0 = 0, arg1 = 0; | 157 | unsigned long arg0 = 0, arg1 = 0; |
158 | int (*func_ptr)(unsigned short, unsigned short) = 0; | ||
159 | unsigned short save_dsp_idlect2; | ||
160 | 158 | ||
161 | printk("PM: OMAP%x is entering deep sleep now ...\n", system_rev); | 159 | printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev); |
160 | |||
161 | omap_serial_wake_trigger(1); | ||
162 | 162 | ||
163 | if (machine_is_omap_osk()) { | 163 | if (machine_is_omap_osk()) { |
164 | /* Stop LED1 (D9) blink */ | 164 | /* Stop LED1 (D9) blink */ |
165 | tps65010_set_led(LED1, OFF); | 165 | tps65010_set_led(LED1, OFF); |
166 | } | 166 | } |
167 | 167 | ||
168 | omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG); | ||
169 | |||
168 | /* | 170 | /* |
169 | * Step 1: turn off interrupts | 171 | * Step 1: turn off interrupts (FIXME: NOTE: already disabled) |
170 | */ | 172 | */ |
171 | 173 | ||
172 | local_irq_disable(); | 174 | local_irq_disable(); |
@@ -207,6 +209,8 @@ void omap_pm_suspend(void) | |||
207 | ARM_SAVE(ARM_CKCTL); | 209 | ARM_SAVE(ARM_CKCTL); |
208 | ARM_SAVE(ARM_IDLECT1); | 210 | ARM_SAVE(ARM_IDLECT1); |
209 | ARM_SAVE(ARM_IDLECT2); | 211 | ARM_SAVE(ARM_IDLECT2); |
212 | if (!(cpu_is_omap1510())) | ||
213 | ARM_SAVE(ARM_IDLECT3); | ||
210 | ARM_SAVE(ARM_EWUPCT); | 214 | ARM_SAVE(ARM_EWUPCT); |
211 | ARM_SAVE(ARM_RSTCT1); | 215 | ARM_SAVE(ARM_RSTCT1); |
212 | ARM_SAVE(ARM_RSTCT2); | 216 | ARM_SAVE(ARM_RSTCT2); |
@@ -214,42 +218,12 @@ void omap_pm_suspend(void) | |||
214 | ULPD_SAVE(ULPD_CLOCK_CTRL); | 218 | ULPD_SAVE(ULPD_CLOCK_CTRL); |
215 | ULPD_SAVE(ULPD_STATUS_REQ); | 219 | ULPD_SAVE(ULPD_STATUS_REQ); |
216 | 220 | ||
217 | /* | 221 | /* (Step 3 removed - we now allow deep sleep by default) */ |
218 | * Step 3: LOW_PWR signal enabling | ||
219 | * | ||
220 | * Allow the LOW_PWR signal to be visible on MPUIO5 ball. | ||
221 | */ | ||
222 | if (cpu_is_omap1510()) { | ||
223 | /* POWER_CTRL_REG = 0x1 (LOW_POWER is available) */ | ||
224 | omap_writew(omap_readw(ULPD_POWER_CTRL) | | ||
225 | OMAP1510_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL); | ||
226 | } else if (cpu_is_omap16xx()) { | ||
227 | /* POWER_CTRL_REG = 0x1 (LOW_POWER is available) */ | ||
228 | omap_writew(omap_readw(ULPD_POWER_CTRL) | | ||
229 | OMAP1610_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL); | ||
230 | } | ||
231 | |||
232 | /* configure LOW_PWR pin */ | ||
233 | omap_cfg_reg(T20_1610_LOW_PWR); | ||
234 | 222 | ||
235 | /* | 223 | /* |
236 | * Step 4: OMAP DSP Shutdown | 224 | * Step 4: OMAP DSP Shutdown |
237 | */ | 225 | */ |
238 | 226 | ||
239 | /* Set DSP_RST = 1 and DSP_EN = 0, put DSP block into reset */ | ||
240 | omap_writel((omap_readl(ARM_RSTCT1) | DSP_RST) & ~DSP_ENABLE, | ||
241 | ARM_RSTCT1); | ||
242 | |||
243 | /* Set DSP boot mode to DSP-IDLE, DSP_BOOT_MODE = 0x2 */ | ||
244 | omap_writel(DSP_IDLE_MODE, MPUI_DSP_BOOT_CONFIG); | ||
245 | |||
246 | /* Set EN_DSPCK = 0, stop DSP block clock */ | ||
247 | omap_writel(omap_readl(ARM_CKCTL) & ~DSP_CLOCK_ENABLE, ARM_CKCTL); | ||
248 | |||
249 | /* Stop any DSP domain clocks */ | ||
250 | omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2); | ||
251 | save_dsp_idlect2 = __raw_readw(DSP_IDLECT2); | ||
252 | __raw_writew(0, DSP_IDLECT2); | ||
253 | 227 | ||
254 | /* | 228 | /* |
255 | * Step 5: Wakeup Event Setup | 229 | * Step 5: Wakeup Event Setup |
@@ -258,24 +232,9 @@ void omap_pm_suspend(void) | |||
258 | omap_pm_wakeup_setup(); | 232 | omap_pm_wakeup_setup(); |
259 | 233 | ||
260 | /* | 234 | /* |
261 | * Step 6a: ARM and Traffic controller shutdown | 235 | * Step 6: ARM and Traffic controller shutdown |
262 | * | ||
263 | * Step 6 starts here with clock and watchdog disable | ||
264 | */ | 236 | */ |
265 | 237 | ||
266 | /* stop clocks */ | ||
267 | mask32 = omap_readl(ARM_IDLECT2); | ||
268 | mask32 &= ~(1<<EN_WDTCK); /* bit 0 -> 0 (WDT clock) */ | ||
269 | mask32 |= (1<<EN_XORPCK); /* bit 1 -> 1 (XORPCK clock) */ | ||
270 | mask32 &= ~(1<<EN_PERCK); /* bit 2 -> 0 (MPUPER_CK clock) */ | ||
271 | mask32 &= ~(1<<EN_LCDCK); /* bit 3 -> 0 (LCDC clock) */ | ||
272 | mask32 &= ~(1<<EN_LBCK); /* bit 4 -> 0 (local bus clock) */ | ||
273 | mask32 |= (1<<EN_APICK); /* bit 6 -> 1 (MPUI clock) */ | ||
274 | mask32 &= ~(1<<EN_TIMCK); /* bit 7 -> 0 (MPU timer clock) */ | ||
275 | mask32 &= ~(1<<DMACK_REQ); /* bit 8 -> 0 (DMAC clock) */ | ||
276 | mask32 &= ~(1<<EN_GPIOCK); /* bit 9 -> 0 (GPIO clock) */ | ||
277 | omap_writel(mask32, ARM_IDLECT2); | ||
278 | |||
279 | /* disable ARM watchdog */ | 238 | /* disable ARM watchdog */ |
280 | omap_writel(0x00F5, OMAP_WDT_TIMER_MODE); | 239 | omap_writel(0x00F5, OMAP_WDT_TIMER_MODE); |
281 | omap_writel(0x00A0, OMAP_WDT_TIMER_MODE); | 240 | omap_writel(0x00A0, OMAP_WDT_TIMER_MODE); |
@@ -295,47 +254,24 @@ void omap_pm_suspend(void) | |||
295 | arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1]; | 254 | arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1]; |
296 | arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2]; | 255 | arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2]; |
297 | 256 | ||
298 | if (cpu_is_omap1510()) { | ||
299 | func_ptr = (void *)(OMAP1510_SRAM_API_SUSPEND); | ||
300 | } else if (cpu_is_omap1610() || cpu_is_omap1710()) { | ||
301 | func_ptr = (void *)(OMAP1610_SRAM_API_SUSPEND); | ||
302 | } else if (cpu_is_omap5912()) { | ||
303 | func_ptr = (void *)(OMAP5912_SRAM_API_SUSPEND); | ||
304 | } | ||
305 | |||
306 | /* | 257 | /* |
307 | * Step 6c: ARM and Traffic controller shutdown | 258 | * Step 6c: ARM and Traffic controller shutdown |
308 | * | 259 | * |
309 | * Jump to assembly code. The processor will stay there | 260 | * Jump to assembly code. The processor will stay there |
310 | * until wake up. | 261 | * until wake up. |
311 | */ | 262 | */ |
312 | 263 | omap_sram_suspend(arg0, arg1); | |
313 | func_ptr(arg0, arg1); | ||
314 | 264 | ||
315 | /* | 265 | /* |
316 | * If we are here, processor is woken up! | 266 | * If we are here, processor is woken up! |
317 | */ | 267 | */ |
318 | 268 | ||
319 | if (cpu_is_omap1510()) { | ||
320 | /* POWER_CTRL_REG = 0x0 (LOW_POWER is disabled) */ | ||
321 | omap_writew(omap_readw(ULPD_POWER_CTRL) & | ||
322 | ~OMAP1510_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL); | ||
323 | } else if (cpu_is_omap16xx()) { | ||
324 | /* POWER_CTRL_REG = 0x0 (LOW_POWER is disabled) */ | ||
325 | omap_writew(omap_readw(ULPD_POWER_CTRL) & | ||
326 | ~OMAP1610_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL); | ||
327 | } | ||
328 | |||
329 | |||
330 | /* Restore DSP clocks */ | ||
331 | omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2); | ||
332 | __raw_writew(save_dsp_idlect2, DSP_IDLECT2); | ||
333 | ARM_RESTORE(ARM_IDLECT2); | ||
334 | |||
335 | /* | 269 | /* |
336 | * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did | 270 | * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did |
337 | */ | 271 | */ |
338 | 272 | ||
273 | if (!(cpu_is_omap1510())) | ||
274 | ARM_RESTORE(ARM_IDLECT3); | ||
339 | ARM_RESTORE(ARM_CKCTL); | 275 | ARM_RESTORE(ARM_CKCTL); |
340 | ARM_RESTORE(ARM_EWUPCT); | 276 | ARM_RESTORE(ARM_EWUPCT); |
341 | ARM_RESTORE(ARM_RSTCT1); | 277 | ARM_RESTORE(ARM_RSTCT1); |
@@ -366,6 +302,8 @@ void omap_pm_suspend(void) | |||
366 | MPUI1610_RESTORE(OMAP_IH2_3_MIR); | 302 | MPUI1610_RESTORE(OMAP_IH2_3_MIR); |
367 | } | 303 | } |
368 | 304 | ||
305 | omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG); | ||
306 | |||
369 | /* | 307 | /* |
370 | * Reenable interrupts | 308 | * Reenable interrupts |
371 | */ | 309 | */ |
@@ -373,6 +311,8 @@ void omap_pm_suspend(void) | |||
373 | local_irq_enable(); | 311 | local_irq_enable(); |
374 | local_fiq_enable(); | 312 | local_fiq_enable(); |
375 | 313 | ||
314 | omap_serial_wake_trigger(0); | ||
315 | |||
376 | printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev); | 316 | printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev); |
377 | 317 | ||
378 | if (machine_is_omap_osk()) { | 318 | if (machine_is_omap_osk()) { |
@@ -401,6 +341,8 @@ static int omap_pm_read_proc( | |||
401 | ARM_SAVE(ARM_CKCTL); | 341 | ARM_SAVE(ARM_CKCTL); |
402 | ARM_SAVE(ARM_IDLECT1); | 342 | ARM_SAVE(ARM_IDLECT1); |
403 | ARM_SAVE(ARM_IDLECT2); | 343 | ARM_SAVE(ARM_IDLECT2); |
344 | if (!(cpu_is_omap1510())) | ||
345 | ARM_SAVE(ARM_IDLECT3); | ||
404 | ARM_SAVE(ARM_EWUPCT); | 346 | ARM_SAVE(ARM_EWUPCT); |
405 | ARM_SAVE(ARM_RSTCT1); | 347 | ARM_SAVE(ARM_RSTCT1); |
406 | ARM_SAVE(ARM_RSTCT2); | 348 | ARM_SAVE(ARM_RSTCT2); |
@@ -436,6 +378,7 @@ static int omap_pm_read_proc( | |||
436 | "ARM_CKCTL_REG: 0x%-8x \n" | 378 | "ARM_CKCTL_REG: 0x%-8x \n" |
437 | "ARM_IDLECT1_REG: 0x%-8x \n" | 379 | "ARM_IDLECT1_REG: 0x%-8x \n" |
438 | "ARM_IDLECT2_REG: 0x%-8x \n" | 380 | "ARM_IDLECT2_REG: 0x%-8x \n" |
381 | "ARM_IDLECT3_REG: 0x%-8x \n" | ||
439 | "ARM_EWUPCT_REG: 0x%-8x \n" | 382 | "ARM_EWUPCT_REG: 0x%-8x \n" |
440 | "ARM_RSTCT1_REG: 0x%-8x \n" | 383 | "ARM_RSTCT1_REG: 0x%-8x \n" |
441 | "ARM_RSTCT2_REG: 0x%-8x \n" | 384 | "ARM_RSTCT2_REG: 0x%-8x \n" |
@@ -449,6 +392,7 @@ static int omap_pm_read_proc( | |||
449 | ARM_SHOW(ARM_CKCTL), | 392 | ARM_SHOW(ARM_CKCTL), |
450 | ARM_SHOW(ARM_IDLECT1), | 393 | ARM_SHOW(ARM_IDLECT1), |
451 | ARM_SHOW(ARM_IDLECT2), | 394 | ARM_SHOW(ARM_IDLECT2), |
395 | ARM_SHOW(ARM_IDLECT3), | ||
452 | ARM_SHOW(ARM_EWUPCT), | 396 | ARM_SHOW(ARM_EWUPCT), |
453 | ARM_SHOW(ARM_RSTCT1), | 397 | ARM_SHOW(ARM_RSTCT1), |
454 | ARM_SHOW(ARM_RSTCT2), | 398 | ARM_SHOW(ARM_RSTCT2), |
@@ -507,7 +451,7 @@ static void omap_pm_init_proc(void) | |||
507 | 451 | ||
508 | entry = create_proc_read_entry("driver/omap_pm", | 452 | entry = create_proc_read_entry("driver/omap_pm", |
509 | S_IWUSR | S_IRUGO, NULL, | 453 | S_IWUSR | S_IRUGO, NULL, |
510 | omap_pm_read_proc, 0); | 454 | omap_pm_read_proc, NULL); |
511 | } | 455 | } |
512 | 456 | ||
513 | #endif /* DEBUG && CONFIG_PROC_FS */ | 457 | #endif /* DEBUG && CONFIG_PROC_FS */ |
@@ -580,7 +524,21 @@ static int omap_pm_finish(suspend_state_t state) | |||
580 | } | 524 | } |
581 | 525 | ||
582 | 526 | ||
583 | struct pm_ops omap_pm_ops ={ | 527 | static irqreturn_t omap_wakeup_interrupt(int irq, void * dev, |
528 | struct pt_regs * regs) | ||
529 | { | ||
530 | return IRQ_HANDLED; | ||
531 | } | ||
532 | |||
533 | static struct irqaction omap_wakeup_irq = { | ||
534 | .name = "peripheral wakeup", | ||
535 | .flags = SA_INTERRUPT, | ||
536 | .handler = omap_wakeup_interrupt | ||
537 | }; | ||
538 | |||
539 | |||
540 | |||
541 | static struct pm_ops omap_pm_ops ={ | ||
584 | .pm_disk_mode = 0, | 542 | .pm_disk_mode = 0, |
585 | .prepare = omap_pm_prepare, | 543 | .prepare = omap_pm_prepare, |
586 | .enter = omap_pm_enter, | 544 | .enter = omap_pm_enter, |
@@ -590,42 +548,61 @@ struct pm_ops omap_pm_ops ={ | |||
590 | static int __init omap_pm_init(void) | 548 | static int __init omap_pm_init(void) |
591 | { | 549 | { |
592 | printk("Power Management for TI OMAP.\n"); | 550 | printk("Power Management for TI OMAP.\n"); |
593 | pm_idle = omap_pm_idle; | ||
594 | /* | 551 | /* |
595 | * We copy the assembler sleep/wakeup routines to SRAM. | 552 | * We copy the assembler sleep/wakeup routines to SRAM. |
596 | * These routines need to be in SRAM as that's the only | 553 | * These routines need to be in SRAM as that's the only |
597 | * memory the MPU can see when it wakes up. | 554 | * memory the MPU can see when it wakes up. |
598 | */ | 555 | */ |
599 | |||
600 | #ifdef CONFIG_ARCH_OMAP1510 | ||
601 | if (cpu_is_omap1510()) { | 556 | if (cpu_is_omap1510()) { |
602 | memcpy((void *)OMAP1510_SRAM_IDLE_SUSPEND, | 557 | omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend, |
603 | omap1510_idle_loop_suspend, | 558 | omap1510_idle_loop_suspend_sz); |
604 | omap1510_idle_loop_suspend_sz); | 559 | omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend, |
605 | memcpy((void *)OMAP1510_SRAM_API_SUSPEND, omap1510_cpu_suspend, | 560 | omap1510_cpu_suspend_sz); |
606 | omap1510_cpu_suspend_sz); | 561 | } else if (cpu_is_omap16xx()) { |
607 | } else | 562 | omap_sram_idle = omap_sram_push(omap1610_idle_loop_suspend, |
608 | #endif | 563 | omap1610_idle_loop_suspend_sz); |
609 | if (cpu_is_omap1610() || cpu_is_omap1710()) { | 564 | omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend, |
610 | memcpy((void *)OMAP1610_SRAM_IDLE_SUSPEND, | 565 | omap1610_cpu_suspend_sz); |
611 | omap1610_idle_loop_suspend, | ||
612 | omap1610_idle_loop_suspend_sz); | ||
613 | memcpy((void *)OMAP1610_SRAM_API_SUSPEND, omap1610_cpu_suspend, | ||
614 | omap1610_cpu_suspend_sz); | ||
615 | } else if (cpu_is_omap5912()) { | ||
616 | memcpy((void *)OMAP5912_SRAM_IDLE_SUSPEND, | ||
617 | omap1610_idle_loop_suspend, | ||
618 | omap1610_idle_loop_suspend_sz); | ||
619 | memcpy((void *)OMAP5912_SRAM_API_SUSPEND, omap1610_cpu_suspend, | ||
620 | omap1610_cpu_suspend_sz); | ||
621 | } | 566 | } |
622 | 567 | ||
568 | if (omap_sram_idle == NULL || omap_sram_suspend == NULL) { | ||
569 | printk(KERN_ERR "PM not initialized: Missing SRAM support\n"); | ||
570 | return -ENODEV; | ||
571 | } | ||
572 | |||
573 | pm_idle = omap_pm_idle; | ||
574 | |||
575 | setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq); | ||
576 | #if 0 | ||
577 | /* --- BEGIN BOARD-DEPENDENT CODE --- */ | ||
578 | /* Sleepx mask direction */ | ||
579 | omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008); | ||
580 | /* Unmask sleepx signal */ | ||
581 | omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004); | ||
582 | /* --- END BOARD-DEPENDENT CODE --- */ | ||
583 | #endif | ||
584 | |||
585 | /* Program new power ramp-up time | ||
586 | * (0 for most boards since we don't lower voltage when in deep sleep) | ||
587 | */ | ||
588 | omap_writew(ULPD_SETUP_ANALOG_CELL_3_VAL, ULPD_SETUP_ANALOG_CELL_3); | ||
589 | |||
590 | /* Setup ULPD POWER_CTRL_REG - enter deep sleep whenever possible */ | ||
591 | omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL); | ||
592 | |||
593 | /* Configure IDLECT3 */ | ||
594 | if (cpu_is_omap16xx()) | ||
595 | omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3); | ||
596 | |||
623 | pm_set_ops(&omap_pm_ops); | 597 | pm_set_ops(&omap_pm_ops); |
624 | 598 | ||
625 | #if defined(DEBUG) && defined(CONFIG_PROC_FS) | 599 | #if defined(DEBUG) && defined(CONFIG_PROC_FS) |
626 | omap_pm_init_proc(); | 600 | omap_pm_init_proc(); |
627 | #endif | 601 | #endif |
628 | 602 | ||
603 | /* configure LOW_PWR pin */ | ||
604 | omap_cfg_reg(T20_1610_LOW_PWR); | ||
605 | |||
629 | return 0; | 606 | return 0; |
630 | } | 607 | } |
631 | __initcall(omap_pm_init); | 608 | __initcall(omap_pm_init); |