diff options
author | Rajendra Nayak <rnayak@ti.com> | 2008-09-26 08:20:07 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2009-11-11 17:42:25 -0500 |
commit | 2f5939c3ec9440a9c3a0baf4d0e1b2cc043aad46 (patch) | |
tree | 2baf1e1e279817fd144a23eb3976964e1d43a0c6 /arch/arm/mach-omap2/pm34xx.c | |
parent | 61255ab9e853ddbbe092328c30921d2ba9434134 (diff) |
OMAP3: PM: CORE domain off-mode support
Add context save and restore for CORE powerdomain resources in order
to support off-mode.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'arch/arm/mach-omap2/pm34xx.c')
-rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 9fb087607e76..bab9b480a089 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -5,6 +5,9 @@ | |||
5 | * Tony Lindgren <tony@atomide.com> | 5 | * Tony Lindgren <tony@atomide.com> |
6 | * Jouni Hogander | 6 | * Jouni Hogander |
7 | * | 7 | * |
8 | * Copyright (C) 2007 Texas Instruments, Inc. | ||
9 | * Rajendra Nayak <rnayak@ti.com> | ||
10 | * | ||
8 | * Copyright (C) 2005 Texas Instruments, Inc. | 11 | * Copyright (C) 2005 Texas Instruments, Inc. |
9 | * Richard Woodruff <r-woodruff2@ti.com> | 12 | * Richard Woodruff <r-woodruff2@ti.com> |
10 | * | 13 | * |
@@ -29,6 +32,8 @@ | |||
29 | #include <plat/control.h> | 32 | #include <plat/control.h> |
30 | #include <plat/serial.h> | 33 | #include <plat/serial.h> |
31 | #include <plat/sdrc.h> | 34 | #include <plat/sdrc.h> |
35 | #include <plat/prcm.h> | ||
36 | #include <plat/gpmc.h> | ||
32 | 37 | ||
33 | #include <asm/tlbflush.h> | 38 | #include <asm/tlbflush.h> |
34 | 39 | ||
@@ -39,6 +44,11 @@ | |||
39 | #include "prm.h" | 44 | #include "prm.h" |
40 | #include "pm.h" | 45 | #include "pm.h" |
41 | 46 | ||
47 | /* Scratchpad offsets */ | ||
48 | #define OMAP343X_TABLE_ADDRESS_OFFSET 0x31 | ||
49 | #define OMAP343X_TABLE_VALUE_OFFSET 0x30 | ||
50 | #define OMAP343X_CONTROL_REG_VALUE_OFFSET 0x32 | ||
51 | |||
42 | struct power_state { | 52 | struct power_state { |
43 | struct powerdomain *pwrdm; | 53 | struct powerdomain *pwrdm; |
44 | u32 next_state; | 54 | u32 next_state; |
@@ -57,6 +67,46 @@ static struct powerdomain *core_pwrdm, *per_pwrdm; | |||
57 | 67 | ||
58 | static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state); | 68 | static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state); |
59 | 69 | ||
70 | static inline void omap3_per_save_context(void) | ||
71 | { | ||
72 | omap_gpio_save_context(); | ||
73 | } | ||
74 | |||
75 | static inline void omap3_per_restore_context(void) | ||
76 | { | ||
77 | omap_gpio_restore_context(); | ||
78 | } | ||
79 | |||
80 | static void omap3_core_save_context(void) | ||
81 | { | ||
82 | u32 control_padconf_off; | ||
83 | |||
84 | /* Save the padconf registers */ | ||
85 | control_padconf_off = omap_ctrl_readl(OMAP343X_CONTROL_PADCONF_OFF); | ||
86 | control_padconf_off |= START_PADCONF_SAVE; | ||
87 | omap_ctrl_writel(control_padconf_off, OMAP343X_CONTROL_PADCONF_OFF); | ||
88 | /* wait for the save to complete */ | ||
89 | while (!omap_ctrl_readl(OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS) | ||
90 | & PADCONF_SAVE_DONE) | ||
91 | ; | ||
92 | /* Save the Interrupt controller context */ | ||
93 | omap_intc_save_context(); | ||
94 | /* Save the GPMC context */ | ||
95 | omap3_gpmc_save_context(); | ||
96 | /* Save the system control module context, padconf already save above*/ | ||
97 | omap3_control_save_context(); | ||
98 | } | ||
99 | |||
100 | static void omap3_core_restore_context(void) | ||
101 | { | ||
102 | /* Restore the control module context, padconf restored by h/w */ | ||
103 | omap3_control_restore_context(); | ||
104 | /* Restore the GPMC context */ | ||
105 | omap3_gpmc_restore_context(); | ||
106 | /* Restore the interrupt controller context */ | ||
107 | omap_intc_restore_context(); | ||
108 | } | ||
109 | |||
60 | /* | 110 | /* |
61 | * PRCM Interrupt Handler Helper Function | 111 | * PRCM Interrupt Handler Helper Function |
62 | * | 112 | * |
@@ -208,6 +258,7 @@ static void omap_sram_idle(void) | |||
208 | int mpu_next_state = PWRDM_POWER_ON; | 258 | int mpu_next_state = PWRDM_POWER_ON; |
209 | int per_next_state = PWRDM_POWER_ON; | 259 | int per_next_state = PWRDM_POWER_ON; |
210 | int core_next_state = PWRDM_POWER_ON; | 260 | int core_next_state = PWRDM_POWER_ON; |
261 | int core_prev_state, per_prev_state; | ||
211 | 262 | ||
212 | if (!_omap_sram_idle) | 263 | if (!_omap_sram_idle) |
213 | return; | 264 | return; |
@@ -246,8 +297,15 @@ static void omap_sram_idle(void) | |||
246 | omap_uart_prepare_idle(1); | 297 | omap_uart_prepare_idle(1); |
247 | /* PER changes only with core */ | 298 | /* PER changes only with core */ |
248 | per_next_state = pwrdm_read_next_pwrst(per_pwrdm); | 299 | per_next_state = pwrdm_read_next_pwrst(per_pwrdm); |
249 | if (per_next_state < PWRDM_POWER_ON) | 300 | if (per_next_state < PWRDM_POWER_ON) { |
250 | omap_uart_prepare_idle(2); | 301 | omap_uart_prepare_idle(2); |
302 | if (per_next_state == PWRDM_POWER_OFF) | ||
303 | omap3_per_save_context(); | ||
304 | } | ||
305 | if (core_next_state == PWRDM_POWER_OFF) { | ||
306 | omap3_core_save_context(); | ||
307 | omap3_prcm_save_context(); | ||
308 | } | ||
251 | /* Enable IO-PAD wakeup */ | 309 | /* Enable IO-PAD wakeup */ |
252 | prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); | 310 | prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); |
253 | } | 311 | } |
@@ -272,6 +330,18 @@ static void omap_sram_idle(void) | |||
272 | 330 | ||
273 | /* Disable IO-PAD wakeup */ | 331 | /* Disable IO-PAD wakeup */ |
274 | prm_clear_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); | 332 | prm_clear_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); |
333 | core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm); | ||
334 | if (core_prev_state == PWRDM_POWER_OFF) { | ||
335 | omap3_core_restore_context(); | ||
336 | omap3_prcm_restore_context(); | ||
337 | omap3_sram_restore_context(); | ||
338 | } | ||
339 | if (per_next_state < PWRDM_POWER_ON) { | ||
340 | per_prev_state = | ||
341 | pwrdm_read_prev_pwrst(per_pwrdm); | ||
342 | if (per_prev_state == PWRDM_POWER_OFF) | ||
343 | omap3_per_restore_context(); | ||
344 | } | ||
275 | omap2_gpio_resume_after_retention(); | 345 | omap2_gpio_resume_after_retention(); |
276 | } | 346 | } |
277 | 347 | ||
@@ -843,6 +913,7 @@ static int __init omap3_pm_init(void) | |||
843 | /* XXX prcm_setup_regs needs to be before enabling hw | 913 | /* XXX prcm_setup_regs needs to be before enabling hw |
844 | * supervised mode for powerdomains */ | 914 | * supervised mode for powerdomains */ |
845 | prcm_setup_regs(); | 915 | prcm_setup_regs(); |
916 | omap3_save_scratchpad_contents(); | ||
846 | 917 | ||
847 | ret = request_irq(INT_34XX_PRCM_MPU_IRQ, | 918 | ret = request_irq(INT_34XX_PRCM_MPU_IRQ, |
848 | (irq_handler_t)prcm_interrupt_handler, | 919 | (irq_handler_t)prcm_interrupt_handler, |