diff options
author | Rajendra Nayak <rnayak@ti.com> | 2008-10-08 08:01:22 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2009-11-11 17:42:48 -0500 |
commit | 20b01669885483ba2102d5a71c662bb6ae1bed0b (patch) | |
tree | 95e71bcf90bcb81e97b5be95383bccf310cb8ad0 /arch/arm/mach-omap2 | |
parent | 99e6a4d22f7c7bda0cd8978333c2e85fba02f181 (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.c | 28 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 6 |
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 | ||
51 | struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES]; | 53 | struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES]; |
52 | struct omap3_processor_cx current_cx_state; | 54 | struct omap3_processor_cx current_cx_state; |
53 | struct powerdomain *mpu_pd; | 55 | struct powerdomain *mpu_pd, *core_pd; |
54 | 56 | ||
55 | static int omap3_idle_bm_check(void) | 57 | static 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 */ | 95 | return_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; | |||
19 | extern void *omap3_secure_ram_storage; | 19 | extern void *omap3_secure_ram_storage; |
20 | extern void omap3_pm_off_mode_enable(int); | 20 | extern void omap3_pm_off_mode_enable(int); |
21 | extern void omap_sram_idle(void); | 21 | extern void omap_sram_idle(void); |
22 | extern int omap3_can_sleep(void); | ||
23 | extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state); | ||
22 | 24 | ||
23 | extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); | 25 | extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); |
24 | extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); | 26 | extern 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; | |||
76 | static struct powerdomain *core_pwrdm, *per_pwrdm; | 76 | static struct powerdomain *core_pwrdm, *per_pwrdm; |
77 | static struct powerdomain *cam_pwrdm; | 77 | static struct powerdomain *cam_pwrdm; |
78 | 78 | ||
79 | static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state); | ||
80 | |||
81 | static inline void omap3_per_save_context(void) | 79 | static 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 | ||
506 | static int omap3_can_sleep(void) | 504 | int 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. */ |
520 | static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state) | 518 | int 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; |