diff options
author | Jean Pihet <j-pihet@ti.com> | 2011-05-09 06:02:16 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@ti.com> | 2011-05-20 11:15:54 -0400 |
commit | 04908918191f7926ec7af99890fb4ddb3b769c13 (patch) | |
tree | 96a531896df79761459d6f10735a5aa85b484a31 /arch/arm/mach-omap2/cpuidle34xx.c | |
parent | c6cd91de1cb4694f2dfcc7df831e276fffdffffc (diff) |
OMAP3: cpuidle: change the power domains modes determination logic
The achievable power modes of the power domains in cpuidle
depends on the system wide 'enable_off_mode' knob in debugfs.
Upon changing enable_off_mode, do not change the C-states
'valid' field but instead dynamically restrict the power modes
when entering idle.
The C-states 'valid' field is just used to enable/disable some
C-states at init and shall not be changed later on.
Signed-off-by: Jean Pihet <j-pihet@ti.com>
Signed-off-by: Kevin Hilman <khilman@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2/cpuidle34xx.c')
-rw-r--r-- | arch/arm/mach-omap2/cpuidle34xx.c | 58 |
1 files changed, 24 insertions, 34 deletions
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index dd31e539274c..4bf6e6e8b100 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c | |||
@@ -138,22 +138,40 @@ return_sleep_time: | |||
138 | } | 138 | } |
139 | 139 | ||
140 | /** | 140 | /** |
141 | * next_valid_state - Find next valid c-state | 141 | * next_valid_state - Find next valid C-state |
142 | * @dev: cpuidle device | 142 | * @dev: cpuidle device |
143 | * @state: Currently selected c-state | 143 | * @state: Currently selected C-state |
144 | * | 144 | * |
145 | * If the current state is valid, it is returned back to the caller. | 145 | * If the current state is valid, it is returned back to the caller. |
146 | * Else, this function searches for a lower c-state which is still | 146 | * Else, this function searches for a lower c-state which is still |
147 | * valid. | 147 | * valid. |
148 | * | ||
149 | * A state is valid if the 'valid' field is enabled and | ||
150 | * if it satisfies the enable_off_mode condition. | ||
148 | */ | 151 | */ |
149 | static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev, | 152 | static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev, |
150 | struct cpuidle_state *curr) | 153 | struct cpuidle_state *curr) |
151 | { | 154 | { |
152 | struct cpuidle_state *next = NULL; | 155 | struct cpuidle_state *next = NULL; |
153 | struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr); | 156 | struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr); |
157 | u32 mpu_deepest_state = PWRDM_POWER_RET; | ||
158 | u32 core_deepest_state = PWRDM_POWER_RET; | ||
159 | |||
160 | if (enable_off_mode) { | ||
161 | mpu_deepest_state = PWRDM_POWER_OFF; | ||
162 | /* | ||
163 | * Erratum i583: valable for ES rev < Es1.2 on 3630. | ||
164 | * CORE OFF mode is not supported in a stable form, restrict | ||
165 | * instead the CORE state to RET. | ||
166 | */ | ||
167 | if (!IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583)) | ||
168 | core_deepest_state = PWRDM_POWER_OFF; | ||
169 | } | ||
154 | 170 | ||
155 | /* Check if current state is valid */ | 171 | /* Check if current state is valid */ |
156 | if (cx->valid) { | 172 | if ((cx->valid) && |
173 | (cx->mpu_state >= mpu_deepest_state) && | ||
174 | (cx->core_state >= core_deepest_state)) { | ||
157 | return curr; | 175 | return curr; |
158 | } else { | 176 | } else { |
159 | int idx = OMAP3_NUM_STATES - 1; | 177 | int idx = OMAP3_NUM_STATES - 1; |
@@ -176,7 +194,9 @@ static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev, | |||
176 | idx--; | 194 | idx--; |
177 | for (; idx >= 0; idx--) { | 195 | for (; idx >= 0; idx--) { |
178 | cx = cpuidle_get_statedata(&dev->states[idx]); | 196 | cx = cpuidle_get_statedata(&dev->states[idx]); |
179 | if (cx->valid) { | 197 | if ((cx->valid) && |
198 | (cx->mpu_state >= mpu_deepest_state) && | ||
199 | (cx->core_state >= core_deepest_state)) { | ||
180 | next = &dev->states[idx]; | 200 | next = &dev->states[idx]; |
181 | break; | 201 | break; |
182 | } | 202 | } |
@@ -259,31 +279,6 @@ select_state: | |||
259 | 279 | ||
260 | DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); | 280 | DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); |
261 | 281 | ||
262 | /** | ||
263 | * omap3_cpuidle_update_states() - Update the cpuidle states | ||
264 | * @mpu_deepest_state: Enable states up to and including this for mpu domain | ||
265 | * @core_deepest_state: Enable states up to and including this for core domain | ||
266 | * | ||
267 | * This goes through the list of states available and enables and disables the | ||
268 | * validity of C states based on deepest state that can be achieved for the | ||
269 | * variable domain | ||
270 | */ | ||
271 | void omap3_cpuidle_update_states(u32 mpu_deepest_state, u32 core_deepest_state) | ||
272 | { | ||
273 | int i; | ||
274 | |||
275 | for (i = 0; i < OMAP3_NUM_STATES; i++) { | ||
276 | struct omap3_idle_statedata *cx = &omap3_idle_data[i]; | ||
277 | |||
278 | if ((cx->mpu_state >= mpu_deepest_state) && | ||
279 | (cx->core_state >= core_deepest_state)) { | ||
280 | cx->valid = 1; | ||
281 | } else { | ||
282 | cx->valid = 0; | ||
283 | } | ||
284 | } | ||
285 | } | ||
286 | |||
287 | void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params) | 282 | void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params) |
288 | { | 283 | { |
289 | int i; | 284 | int i; |
@@ -393,11 +388,6 @@ int __init omap3_idle_init(void) | |||
393 | cx->mpu_state = PWRDM_POWER_OFF; | 388 | cx->mpu_state = PWRDM_POWER_OFF; |
394 | cx->core_state = PWRDM_POWER_OFF; | 389 | cx->core_state = PWRDM_POWER_OFF; |
395 | 390 | ||
396 | if (enable_off_mode) | ||
397 | omap3_cpuidle_update_states(PWRDM_POWER_OFF, PWRDM_POWER_OFF); | ||
398 | else | ||
399 | omap3_cpuidle_update_states(PWRDM_POWER_RET, PWRDM_POWER_RET); | ||
400 | |||
401 | dev->state_count = OMAP3_NUM_STATES; | 391 | dev->state_count = OMAP3_NUM_STATES; |
402 | if (cpuidle_register_device(dev)) { | 392 | if (cpuidle_register_device(dev)) { |
403 | printk(KERN_ERR "%s: CPUidle register device failed\n", | 393 | printk(KERN_ERR "%s: CPUidle register device failed\n", |