aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2
diff options
context:
space:
mode:
authorRajendra Nayak <rnayak@ti.com>2008-10-08 08:01:22 -0400
committerKevin Hilman <khilman@deeprootsystems.com>2009-11-11 17:42:48 -0500
commit20b01669885483ba2102d5a71c662bb6ae1bed0b (patch)
tree95e71bcf90bcb81e97b5be95383bccf310cb8ad0 /arch/arm/mach-omap2
parent99e6a4d22f7c7bda0cd8978333c2e85fba02f181 (diff)
OMAP3: PM: CPUidle: support retention and off-mode C-states
This patch adds support and enables state C4(MPU RET + CORE RET) and MPU OFF states (C3 and C5.) Signed-off-by: Rajendra Nayak <rnayak@ti.com> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c28
-rw-r--r--arch/arm/mach-omap2/pm.h2
-rw-r--r--arch/arm/mach-omap2/pm34xx.c6
3 files changed, 20 insertions, 16 deletions
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 858b216b63b6..0bf1bc359ea8 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -26,6 +26,8 @@
26 26
27#include <plat/prcm.h> 27#include <plat/prcm.h>
28#include <plat/powerdomain.h> 28#include <plat/powerdomain.h>
29#include <plat/irqs.h>
30#include <plat/control.h>
29 31
30#ifdef CONFIG_CPU_IDLE 32#ifdef CONFIG_CPU_IDLE
31 33
@@ -50,10 +52,12 @@ struct omap3_processor_cx {
50 52
51struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES]; 53struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
52struct omap3_processor_cx current_cx_state; 54struct omap3_processor_cx current_cx_state;
53struct powerdomain *mpu_pd; 55struct powerdomain *mpu_pd, *core_pd;
54 56
55static int omap3_idle_bm_check(void) 57static int omap3_idle_bm_check(void)
56{ 58{
59 if (!omap3_can_sleep())
60 return 1;
57 return 0; 61 return 0;
58} 62}
59 63
@@ -79,24 +83,23 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
79 local_irq_disable(); 83 local_irq_disable();
80 local_fiq_disable(); 84 local_fiq_disable();
81 85
82 /* Program MPU to target state */ 86 set_pwrdm_state(mpu_pd, cx->mpu_state);
83 if (cx->mpu_state < PWRDM_POWER_ON) 87 set_pwrdm_state(core_pd, cx->core_state);
84 pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state); 88
89 if (omap_irq_pending())
90 goto return_sleep_time;
85 91
86 /* Execute ARM wfi */ 92 /* Execute ARM wfi */
87 omap_sram_idle(); 93 omap_sram_idle();
88 94
89 /* Program MPU to ON */ 95return_sleep_time:
90 if (cx->mpu_state < PWRDM_POWER_ON)
91 pwrdm_set_next_pwrst(mpu_pd, PWRDM_POWER_ON);
92
93 getnstimeofday(&ts_postidle); 96 getnstimeofday(&ts_postidle);
94 ts_idle = timespec_sub(ts_postidle, ts_preidle); 97 ts_idle = timespec_sub(ts_postidle, ts_preidle);
95 98
96 local_irq_enable(); 99 local_irq_enable();
97 local_fiq_enable(); 100 local_fiq_enable();
98 101
99 return timespec_to_ns(&ts_idle); 102 return (u32)timespec_to_ns(&ts_idle)/1000;
100} 103}
101 104
102/** 105/**
@@ -153,7 +156,7 @@ void omap_init_power_states(void)
153 omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID; 156 omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID;
154 157
155 /* C3 . MPU OFF + Core active */ 158 /* C3 . MPU OFF + Core active */
156 omap3_power_states[OMAP3_STATE_C3].valid = 0; 159 omap3_power_states[OMAP3_STATE_C3].valid = 1;
157 omap3_power_states[OMAP3_STATE_C3].type = OMAP3_STATE_C3; 160 omap3_power_states[OMAP3_STATE_C3].type = OMAP3_STATE_C3;
158 omap3_power_states[OMAP3_STATE_C3].sleep_latency = 1500; 161 omap3_power_states[OMAP3_STATE_C3].sleep_latency = 1500;
159 omap3_power_states[OMAP3_STATE_C3].wakeup_latency = 1800; 162 omap3_power_states[OMAP3_STATE_C3].wakeup_latency = 1800;
@@ -163,7 +166,7 @@ void omap_init_power_states(void)
163 omap3_power_states[OMAP3_STATE_C3].flags = CPUIDLE_FLAG_TIME_VALID; 166 omap3_power_states[OMAP3_STATE_C3].flags = CPUIDLE_FLAG_TIME_VALID;
164 167
165 /* C4 . MPU CSWR + Core CSWR*/ 168 /* C4 . MPU CSWR + Core CSWR*/
166 omap3_power_states[OMAP3_STATE_C4].valid = 0; 169 omap3_power_states[OMAP3_STATE_C4].valid = 1;
167 omap3_power_states[OMAP3_STATE_C4].type = OMAP3_STATE_C4; 170 omap3_power_states[OMAP3_STATE_C4].type = OMAP3_STATE_C4;
168 omap3_power_states[OMAP3_STATE_C4].sleep_latency = 2500; 171 omap3_power_states[OMAP3_STATE_C4].sleep_latency = 2500;
169 omap3_power_states[OMAP3_STATE_C4].wakeup_latency = 7500; 172 omap3_power_states[OMAP3_STATE_C4].wakeup_latency = 7500;
@@ -174,7 +177,7 @@ void omap_init_power_states(void)
174 CPUIDLE_FLAG_CHECK_BM; 177 CPUIDLE_FLAG_CHECK_BM;
175 178
176 /* C5 . MPU OFF + Core CSWR */ 179 /* C5 . MPU OFF + Core CSWR */
177 omap3_power_states[OMAP3_STATE_C5].valid = 0; 180 omap3_power_states[OMAP3_STATE_C5].valid = 1;
178 omap3_power_states[OMAP3_STATE_C5].type = OMAP3_STATE_C5; 181 omap3_power_states[OMAP3_STATE_C5].type = OMAP3_STATE_C5;
179 omap3_power_states[OMAP3_STATE_C5].sleep_latency = 3000; 182 omap3_power_states[OMAP3_STATE_C5].sleep_latency = 3000;
180 omap3_power_states[OMAP3_STATE_C5].wakeup_latency = 8500; 183 omap3_power_states[OMAP3_STATE_C5].wakeup_latency = 8500;
@@ -215,6 +218,7 @@ int omap3_idle_init(void)
215 struct cpuidle_device *dev; 218 struct cpuidle_device *dev;
216 219
217 mpu_pd = pwrdm_lookup("mpu_pwrdm"); 220 mpu_pd = pwrdm_lookup("mpu_pwrdm");
221 core_pd = pwrdm_lookup("core_pwrdm");
218 222
219 omap_init_power_states(); 223 omap_init_power_states();
220 cpuidle_register_driver(&omap3_idle_driver); 224 cpuidle_register_driver(&omap3_idle_driver);
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 2edf1ba12dca..379e35034ccc 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -19,6 +19,8 @@ extern u32 sleep_while_idle;
19extern void *omap3_secure_ram_storage; 19extern void *omap3_secure_ram_storage;
20extern void omap3_pm_off_mode_enable(int); 20extern void omap3_pm_off_mode_enable(int);
21extern void omap_sram_idle(void); 21extern void omap_sram_idle(void);
22extern int omap3_can_sleep(void);
23extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
22 24
23extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); 25extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm);
24extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); 26extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 0c49db8afa99..69c47edcc0f2 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -76,8 +76,6 @@ static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
76static struct powerdomain *core_pwrdm, *per_pwrdm; 76static struct powerdomain *core_pwrdm, *per_pwrdm;
77static struct powerdomain *cam_pwrdm; 77static struct powerdomain *cam_pwrdm;
78 78
79static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
80
81static inline void omap3_per_save_context(void) 79static inline void omap3_per_save_context(void)
82{ 80{
83 omap_gpio_save_context(); 81 omap_gpio_save_context();
@@ -503,7 +501,7 @@ static int omap3_fclks_active(void)
503 return 0; 501 return 0;
504} 502}
505 503
506static int omap3_can_sleep(void) 504int omap3_can_sleep(void)
507{ 505{
508 if (!sleep_while_idle) 506 if (!sleep_while_idle)
509 return 0; 507 return 0;
@@ -517,7 +515,7 @@ static int omap3_can_sleep(void)
517/* This sets pwrdm state (other than mpu & core. Currently only ON & 515/* This sets pwrdm state (other than mpu & core. Currently only ON &
518 * RET are supported. Function is assuming that clkdm doesn't have 516 * RET are supported. Function is assuming that clkdm doesn't have
519 * hw_sup mode enabled. */ 517 * hw_sup mode enabled. */
520static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state) 518int set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
521{ 519{
522 u32 cur_state; 520 u32 cur_state;
523 int sleep_switch = 0; 521 int sleep_switch = 0;