summaryrefslogtreecommitdiff
path: root/arch/arm/mach-omap2/cpuidle34xx.c
diff options
context:
space:
mode:
authorRajendra Nayak <rnayak@ti.com>2008-10-08 17:31:22 +0530
committerKevin Hilman <khilman@deeprootsystems.com>2009-11-11 14:42:48 -0800
commit20b01669885483ba2102d5a71c662bb6ae1bed0b (patch)
tree95e71bcf90bcb81e97b5be95383bccf310cb8ad0 /arch/arm/mach-omap2/cpuidle34xx.c
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/cpuidle34xx.c')
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c28
1 files changed, 16 insertions, 12 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 @@
#include <plat/prcm.h>
#include <plat/powerdomain.h>
+#include <plat/irqs.h>
+#include <plat/control.h>
#ifdef CONFIG_CPU_IDLE
@@ -50,10 +52,12 @@ struct omap3_processor_cx {
struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
struct omap3_processor_cx current_cx_state;
-struct powerdomain *mpu_pd;
+struct powerdomain *mpu_pd, *core_pd;
static int omap3_idle_bm_check(void)
{
+ if (!omap3_can_sleep())
+ return 1;
return 0;
}
@@ -79,24 +83,23 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
local_irq_disable();
local_fiq_disable();
- /* Program MPU to target state */
- if (cx->mpu_state < PWRDM_POWER_ON)
- pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state);
+ set_pwrdm_state(mpu_pd, cx->mpu_state);
+ set_pwrdm_state(core_pd, cx->core_state);
+
+ if (omap_irq_pending())
+ goto return_sleep_time;
/* Execute ARM wfi */
omap_sram_idle();
- /* Program MPU to ON */
- if (cx->mpu_state < PWRDM_POWER_ON)
- pwrdm_set_next_pwrst(mpu_pd, PWRDM_POWER_ON);
-
+return_sleep_time:
getnstimeofday(&ts_postidle);
ts_idle = timespec_sub(ts_postidle, ts_preidle);
local_irq_enable();
local_fiq_enable();
- return timespec_to_ns(&ts_idle);
+ return (u32)timespec_to_ns(&ts_idle)/1000;
}
/**
@@ -153,7 +156,7 @@ void omap_init_power_states(void)
omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID;
/* C3 . MPU OFF + Core active */
- omap3_power_states[OMAP3_STATE_C3].valid = 0;
+ omap3_power_states[OMAP3_STATE_C3].valid = 1;
omap3_power_states[OMAP3_STATE_C3].type = OMAP3_STATE_C3;
omap3_power_states[OMAP3_STATE_C3].sleep_latency = 1500;
omap3_power_states[OMAP3_STATE_C3].wakeup_latency = 1800;
@@ -163,7 +166,7 @@ void omap_init_power_states(void)
omap3_power_states[OMAP3_STATE_C3].flags = CPUIDLE_FLAG_TIME_VALID;
/* C4 . MPU CSWR + Core CSWR*/
- omap3_power_states[OMAP3_STATE_C4].valid = 0;
+ omap3_power_states[OMAP3_STATE_C4].valid = 1;
omap3_power_states[OMAP3_STATE_C4].type = OMAP3_STATE_C4;
omap3_power_states[OMAP3_STATE_C4].sleep_latency = 2500;
omap3_power_states[OMAP3_STATE_C4].wakeup_latency = 7500;
@@ -174,7 +177,7 @@ void omap_init_power_states(void)
CPUIDLE_FLAG_CHECK_BM;
/* C5 . MPU OFF + Core CSWR */
- omap3_power_states[OMAP3_STATE_C5].valid = 0;
+ omap3_power_states[OMAP3_STATE_C5].valid = 1;
omap3_power_states[OMAP3_STATE_C5].type = OMAP3_STATE_C5;
omap3_power_states[OMAP3_STATE_C5].sleep_latency = 3000;
omap3_power_states[OMAP3_STATE_C5].wakeup_latency = 8500;
@@ -215,6 +218,7 @@ int omap3_idle_init(void)
struct cpuidle_device *dev;
mpu_pd = pwrdm_lookup("mpu_pwrdm");
+ core_pd = pwrdm_lookup("core_pwrdm");
omap_init_power_states();
cpuidle_register_driver(&omap3_idle_driver);