Commit 04908918191f7926ec7af99890fb4ddb3b769c13

Authored by Jean Pihet
Committed by Kevin Hilman
1 parent c6cd91de1c

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 &&