aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/pm34xx.c
diff options
context:
space:
mode:
authorRajendra Nayak <rnayak@ti.com>2008-09-26 08:20:07 -0400
committerKevin Hilman <khilman@deeprootsystems.com>2009-11-11 17:42:25 -0500
commit2f5939c3ec9440a9c3a0baf4d0e1b2cc043aad46 (patch)
tree2baf1e1e279817fd144a23eb3976964e1d43a0c6 /arch/arm/mach-omap2/pm34xx.c
parent61255ab9e853ddbbe092328c30921d2ba9434134 (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.c73
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
42struct power_state { 52struct 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
58static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state); 68static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
59 69
70static inline void omap3_per_save_context(void)
71{
72 omap_gpio_save_context();
73}
74
75static inline void omap3_per_restore_context(void)
76{
77 omap_gpio_restore_context();
78}
79
80static 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
100static 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,