Commit 04908918191f7926ec7af99890fb4ddb3b769c13
Committed by
Kevin Hilman
1 parent
c6cd91de1c
Exists in
master
and in
4 other branches
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>
Showing 3 changed files with 24 additions and 50 deletions Side-by-side Diff
arch/arm/mach-omap2/cpuidle34xx.c
... | ... | @@ -138,22 +138,40 @@ |
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 | 142 | * @dev: cpuidle device |
143 | - * @state: Currently selected c-state | |
143 | + * @state: Currently selected C-state | |
144 | 144 | * |
145 | 145 | * If the current state is valid, it is returned back to the caller. |
146 | 146 | * Else, this function searches for a lower c-state which is still |
147 | 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 | 152 | static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev, |
150 | 153 | struct cpuidle_state *curr) |
151 | 154 | { |
152 | 155 | struct cpuidle_state *next = NULL; |
153 | 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; | |
154 | 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 | + } | |
170 | + | |
155 | 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 | 175 | return curr; |
158 | 176 | } else { |
159 | 177 | int idx = OMAP3_NUM_STATES - 1; |
... | ... | @@ -176,7 +194,9 @@ |
176 | 194 | idx--; |
177 | 195 | for (; idx >= 0; idx--) { |
178 | 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 | 200 | next = &dev->states[idx]; |
181 | 201 | break; |
182 | 202 | } |
... | ... | @@ -259,31 +279,6 @@ |
259 | 279 | |
260 | 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 | 282 | void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params) |
288 | 283 | { |
289 | 284 | int i; |
... | ... | @@ -392,11 +387,6 @@ |
392 | 387 | } |
393 | 388 | cx->mpu_state = PWRDM_POWER_OFF; |
394 | 389 | cx->core_state = PWRDM_POWER_OFF; |
395 | - | |
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 | 390 | |
401 | 391 | dev->state_count = OMAP3_NUM_STATES; |
402 | 392 | if (cpuidle_register_device(dev)) { |
arch/arm/mach-omap2/pm.h
... | ... | @@ -78,10 +78,6 @@ |
78 | 78 | #define sleep_while_idle 0 |
79 | 79 | #endif |
80 | 80 | |
81 | -#if defined(CONFIG_CPU_IDLE) | |
82 | -extern void omap3_cpuidle_update_states(u32, u32); | |
83 | -#endif | |
84 | - | |
85 | 81 | #if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) |
86 | 82 | extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev); |
87 | 83 | extern int pm_dbg_regset_save(int reg_set); |
arch/arm/mach-omap2/pm34xx.c
... | ... | @@ -779,18 +779,6 @@ |
779 | 779 | else |
780 | 780 | state = PWRDM_POWER_RET; |
781 | 781 | |
782 | -#ifdef CONFIG_CPU_IDLE | |
783 | - /* | |
784 | - * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot | |
785 | - * enable OFF mode in a stable form for previous revisions, restrict | |
786 | - * instead to RET | |
787 | - */ | |
788 | - if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583)) | |
789 | - omap3_cpuidle_update_states(state, PWRDM_POWER_RET); | |
790 | - else | |
791 | - omap3_cpuidle_update_states(state, state); | |
792 | -#endif | |
793 | - | |
794 | 782 | list_for_each_entry(pwrst, &pwrst_list, node) { |
795 | 783 | if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583) && |
796 | 784 | pwrst->pwrdm == core_pwrdm && |