diff options
-rw-r--r-- | arch/arm/mach-omap2/board-rx51.c | 38 | ||||
-rw-r--r-- | arch/arm/mach-omap2/cpuidle34xx.c | 298 | ||||
-rw-r--r-- | arch/arm/mach-omap2/cpuidle44xx.c | 126 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm.h | 21 |
4 files changed, 190 insertions, 293 deletions
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c index 27f01f051dff..2da92a6ba40a 100644 --- a/arch/arm/mach-omap2/board-rx51.c +++ b/arch/arm/mach-omap2/board-rx51.c | |||
@@ -59,25 +59,24 @@ static struct platform_device leds_gpio = { | |||
59 | }; | 59 | }; |
60 | 60 | ||
61 | /* | 61 | /* |
62 | * cpuidle C-states definition override from the default values. | 62 | * cpuidle C-states definition for rx51. |
63 | * The 'exit_latency' field is the sum of sleep and wake-up latencies. | 63 | * |
64 | */ | 64 | * The 'exit_latency' field is the sum of sleep |
65 | static struct cpuidle_params rx51_cpuidle_params[] = { | 65 | * and wake-up latencies. |
66 | /* C1 */ | 66 | |
67 | {110 + 162, 5 , 1}, | 67 | --------------------------------------------- |
68 | /* C2 */ | 68 | | state | exit_latency | target_residency | |
69 | {106 + 180, 309, 1}, | 69 | --------------------------------------------- |
70 | /* C3 */ | 70 | | C1 | 110 + 162 | 5 | |
71 | {107 + 410, 46057, 0}, | 71 | | C2 | 106 + 180 | 309 | |
72 | /* C4 */ | 72 | | C3 | 107 + 410 | 46057 | |
73 | {121 + 3374, 46057, 0}, | 73 | | C4 | 121 + 3374 | 46057 | |
74 | /* C5 */ | 74 | | C5 | 855 + 1146 | 46057 | |
75 | {855 + 1146, 46057, 1}, | 75 | | C6 | 7580 + 4134 | 484329 | |
76 | /* C6 */ | 76 | | C7 | 7505 + 15274 | 484329 | |
77 | {7580 + 4134, 484329, 0}, | 77 | --------------------------------------------- |
78 | /* C7 */ | 78 | |
79 | {7505 + 15274, 484329, 1}, | 79 | */ |
80 | }; | ||
81 | 80 | ||
82 | extern void __init rx51_peripherals_init(void); | 81 | extern void __init rx51_peripherals_init(void); |
83 | 82 | ||
@@ -98,7 +97,6 @@ static void __init rx51_init(void) | |||
98 | struct omap_sdrc_params *sdrc_params; | 97 | struct omap_sdrc_params *sdrc_params; |
99 | 98 | ||
100 | omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); | 99 | omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); |
101 | omap3_pm_init_cpuidle(rx51_cpuidle_params); | ||
102 | omap_serial_init(); | 100 | omap_serial_init(); |
103 | 101 | ||
104 | sdrc_params = nokia_get_sdram_timings(); | 102 | sdrc_params = nokia_get_sdram_timings(); |
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index 535866489ce3..207bc1c7759f 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c | |||
@@ -38,40 +38,44 @@ | |||
38 | 38 | ||
39 | #ifdef CONFIG_CPU_IDLE | 39 | #ifdef CONFIG_CPU_IDLE |
40 | 40 | ||
41 | /* | ||
42 | * The latencies/thresholds for various C states have | ||
43 | * to be configured from the respective board files. | ||
44 | * These are some default values (which might not provide | ||
45 | * the best power savings) used on boards which do not | ||
46 | * pass these details from the board file. | ||
47 | */ | ||
48 | static struct cpuidle_params cpuidle_params_table[] = { | ||
49 | /* C1 */ | ||
50 | {2 + 2, 5, 1}, | ||
51 | /* C2 */ | ||
52 | {10 + 10, 30, 1}, | ||
53 | /* C3 */ | ||
54 | {50 + 50, 300, 1}, | ||
55 | /* C4 */ | ||
56 | {1500 + 1800, 4000, 1}, | ||
57 | /* C5 */ | ||
58 | {2500 + 7500, 12000, 1}, | ||
59 | /* C6 */ | ||
60 | {3000 + 8500, 15000, 1}, | ||
61 | /* C7 */ | ||
62 | {10000 + 30000, 300000, 1}, | ||
63 | }; | ||
64 | #define OMAP3_NUM_STATES ARRAY_SIZE(cpuidle_params_table) | ||
65 | |||
66 | /* Mach specific information to be recorded in the C-state driver_data */ | 41 | /* Mach specific information to be recorded in the C-state driver_data */ |
67 | struct omap3_idle_statedata { | 42 | struct omap3_idle_statedata { |
68 | u32 mpu_state; | 43 | u32 mpu_state; |
69 | u32 core_state; | 44 | u32 core_state; |
70 | u8 valid; | ||
71 | }; | 45 | }; |
72 | struct omap3_idle_statedata omap3_idle_data[OMAP3_NUM_STATES]; | ||
73 | 46 | ||
74 | struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd; | 47 | static struct omap3_idle_statedata omap3_idle_data[] = { |
48 | { | ||
49 | .mpu_state = PWRDM_POWER_ON, | ||
50 | .core_state = PWRDM_POWER_ON, | ||
51 | }, | ||
52 | { | ||
53 | .mpu_state = PWRDM_POWER_ON, | ||
54 | .core_state = PWRDM_POWER_ON, | ||
55 | }, | ||
56 | { | ||
57 | .mpu_state = PWRDM_POWER_RET, | ||
58 | .core_state = PWRDM_POWER_ON, | ||
59 | }, | ||
60 | { | ||
61 | .mpu_state = PWRDM_POWER_OFF, | ||
62 | .core_state = PWRDM_POWER_ON, | ||
63 | }, | ||
64 | { | ||
65 | .mpu_state = PWRDM_POWER_RET, | ||
66 | .core_state = PWRDM_POWER_RET, | ||
67 | }, | ||
68 | { | ||
69 | .mpu_state = PWRDM_POWER_OFF, | ||
70 | .core_state = PWRDM_POWER_RET, | ||
71 | }, | ||
72 | { | ||
73 | .mpu_state = PWRDM_POWER_OFF, | ||
74 | .core_state = PWRDM_POWER_OFF, | ||
75 | }, | ||
76 | }; | ||
77 | |||
78 | static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd; | ||
75 | 79 | ||
76 | static int _cpuidle_allow_idle(struct powerdomain *pwrdm, | 80 | static int _cpuidle_allow_idle(struct powerdomain *pwrdm, |
77 | struct clockdomain *clkdm) | 81 | struct clockdomain *clkdm) |
@@ -91,8 +95,7 @@ static int __omap3_enter_idle(struct cpuidle_device *dev, | |||
91 | struct cpuidle_driver *drv, | 95 | struct cpuidle_driver *drv, |
92 | int index) | 96 | int index) |
93 | { | 97 | { |
94 | struct omap3_idle_statedata *cx = | 98 | struct omap3_idle_statedata *cx = &omap3_idle_data[index]; |
95 | cpuidle_get_statedata(&dev->states_usage[index]); | ||
96 | u32 mpu_state = cx->mpu_state, core_state = cx->core_state; | 99 | u32 mpu_state = cx->mpu_state, core_state = cx->core_state; |
97 | 100 | ||
98 | local_fiq_disable(); | 101 | local_fiq_disable(); |
@@ -169,14 +172,12 @@ static inline int omap3_enter_idle(struct cpuidle_device *dev, | |||
169 | * if it satisfies the enable_off_mode condition. | 172 | * if it satisfies the enable_off_mode condition. |
170 | */ | 173 | */ |
171 | static int next_valid_state(struct cpuidle_device *dev, | 174 | static int next_valid_state(struct cpuidle_device *dev, |
172 | struct cpuidle_driver *drv, | 175 | struct cpuidle_driver *drv, int index) |
173 | int index) | ||
174 | { | 176 | { |
175 | struct cpuidle_state_usage *curr_usage = &dev->states_usage[index]; | 177 | struct omap3_idle_statedata *cx = &omap3_idle_data[index]; |
176 | struct cpuidle_state *curr = &drv->states[index]; | ||
177 | struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage); | ||
178 | u32 mpu_deepest_state = PWRDM_POWER_RET; | 178 | u32 mpu_deepest_state = PWRDM_POWER_RET; |
179 | u32 core_deepest_state = PWRDM_POWER_RET; | 179 | u32 core_deepest_state = PWRDM_POWER_RET; |
180 | int idx; | ||
180 | int next_index = -1; | 181 | int next_index = -1; |
181 | 182 | ||
182 | if (enable_off_mode) { | 183 | if (enable_off_mode) { |
@@ -191,45 +192,29 @@ static int next_valid_state(struct cpuidle_device *dev, | |||
191 | } | 192 | } |
192 | 193 | ||
193 | /* Check if current state is valid */ | 194 | /* Check if current state is valid */ |
194 | if ((cx->valid) && | 195 | if ((cx->mpu_state >= mpu_deepest_state) && |
195 | (cx->mpu_state >= mpu_deepest_state) && | 196 | (cx->core_state >= core_deepest_state)) |
196 | (cx->core_state >= core_deepest_state)) { | ||
197 | return index; | 197 | return index; |
198 | } else { | ||
199 | int idx = OMAP3_NUM_STATES - 1; | ||
200 | |||
201 | /* Reach the current state starting at highest C-state */ | ||
202 | for (; idx >= 0; idx--) { | ||
203 | if (&drv->states[idx] == curr) { | ||
204 | next_index = idx; | ||
205 | break; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | /* Should never hit this condition */ | ||
210 | WARN_ON(next_index == -1); | ||
211 | 198 | ||
212 | /* | 199 | /* |
213 | * Drop to next valid state. | 200 | * Drop to next valid state. |
214 | * Start search from the next (lower) state. | 201 | * Start search from the next (lower) state. |
215 | */ | 202 | */ |
216 | idx--; | 203 | for (idx = index - 1; idx >= 0; idx--) { |
217 | for (; idx >= 0; idx--) { | 204 | cx = &omap3_idle_data[idx]; |
218 | cx = cpuidle_get_statedata(&dev->states_usage[idx]); | 205 | if ((cx->mpu_state >= mpu_deepest_state) && |
219 | if ((cx->valid) && | 206 | (cx->core_state >= core_deepest_state)) { |
220 | (cx->mpu_state >= mpu_deepest_state) && | 207 | next_index = idx; |
221 | (cx->core_state >= core_deepest_state)) { | 208 | break; |
222 | next_index = idx; | ||
223 | break; | ||
224 | } | ||
225 | } | 209 | } |
226 | /* | ||
227 | * C1 is always valid. | ||
228 | * So, no need to check for 'next_index == -1' outside | ||
229 | * this loop. | ||
230 | */ | ||
231 | } | 210 | } |
232 | 211 | ||
212 | /* | ||
213 | * C1 is always valid. | ||
214 | * So, no need to check for 'next_index == -1' outside | ||
215 | * this loop. | ||
216 | */ | ||
217 | |||
233 | return next_index; | 218 | return next_index; |
234 | } | 219 | } |
235 | 220 | ||
@@ -273,7 +258,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, | |||
273 | * Prevent PER off if CORE is not in retention or off as this | 258 | * Prevent PER off if CORE is not in retention or off as this |
274 | * would disable PER wakeups completely. | 259 | * would disable PER wakeups completely. |
275 | */ | 260 | */ |
276 | cx = cpuidle_get_statedata(&dev->states_usage[index]); | 261 | cx = &omap3_idle_data[index]; |
277 | core_next_state = cx->core_state; | 262 | core_next_state = cx->core_state; |
278 | per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd); | 263 | per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd); |
279 | if ((per_next_state == PWRDM_POWER_OFF) && | 264 | if ((per_next_state == PWRDM_POWER_OFF) && |
@@ -298,57 +283,71 @@ select_state: | |||
298 | 283 | ||
299 | DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); | 284 | DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); |
300 | 285 | ||
301 | void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params) | ||
302 | { | ||
303 | int i; | ||
304 | |||
305 | if (!cpuidle_board_params) | ||
306 | return; | ||
307 | |||
308 | for (i = 0; i < OMAP3_NUM_STATES; i++) { | ||
309 | cpuidle_params_table[i].valid = cpuidle_board_params[i].valid; | ||
310 | cpuidle_params_table[i].exit_latency = | ||
311 | cpuidle_board_params[i].exit_latency; | ||
312 | cpuidle_params_table[i].target_residency = | ||
313 | cpuidle_board_params[i].target_residency; | ||
314 | } | ||
315 | return; | ||
316 | } | ||
317 | |||
318 | struct cpuidle_driver omap3_idle_driver = { | 286 | struct cpuidle_driver omap3_idle_driver = { |
319 | .name = "omap3_idle", | 287 | .name = "omap3_idle", |
320 | .owner = THIS_MODULE, | 288 | .owner = THIS_MODULE, |
289 | .states = { | ||
290 | { | ||
291 | .enter = omap3_enter_idle, | ||
292 | .exit_latency = 2 + 2, | ||
293 | .target_residency = 5, | ||
294 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
295 | .name = "C1", | ||
296 | .desc = "MPU ON + CORE ON", | ||
297 | }, | ||
298 | { | ||
299 | .enter = omap3_enter_idle_bm, | ||
300 | .exit_latency = 10 + 10, | ||
301 | .target_residency = 30, | ||
302 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
303 | .name = "C2", | ||
304 | .desc = "MPU ON + CORE ON", | ||
305 | }, | ||
306 | { | ||
307 | .enter = omap3_enter_idle_bm, | ||
308 | .exit_latency = 50 + 50, | ||
309 | .target_residency = 300, | ||
310 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
311 | .name = "C3", | ||
312 | .desc = "MPU RET + CORE ON", | ||
313 | }, | ||
314 | { | ||
315 | .enter = omap3_enter_idle_bm, | ||
316 | .exit_latency = 1500 + 1800, | ||
317 | .target_residency = 4000, | ||
318 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
319 | .name = "C4", | ||
320 | .desc = "MPU OFF + CORE ON", | ||
321 | }, | ||
322 | { | ||
323 | .enter = omap3_enter_idle_bm, | ||
324 | .exit_latency = 2500 + 7500, | ||
325 | .target_residency = 12000, | ||
326 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
327 | .name = "C5", | ||
328 | .desc = "MPU RET + CORE RET", | ||
329 | }, | ||
330 | { | ||
331 | .enter = omap3_enter_idle_bm, | ||
332 | .exit_latency = 3000 + 8500, | ||
333 | .target_residency = 15000, | ||
334 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
335 | .name = "C6", | ||
336 | .desc = "MPU OFF + CORE RET", | ||
337 | }, | ||
338 | { | ||
339 | .enter = omap3_enter_idle_bm, | ||
340 | .exit_latency = 10000 + 30000, | ||
341 | .target_residency = 30000, | ||
342 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
343 | .name = "C7", | ||
344 | .desc = "MPU OFF + CORE OFF", | ||
345 | }, | ||
346 | }, | ||
347 | .state_count = ARRAY_SIZE(omap3_idle_data), | ||
348 | .safe_state_index = 0, | ||
321 | }; | 349 | }; |
322 | 350 | ||
323 | /* Helper to fill the C-state common data*/ | ||
324 | static inline void _fill_cstate(struct cpuidle_driver *drv, | ||
325 | int idx, const char *descr) | ||
326 | { | ||
327 | struct cpuidle_state *state = &drv->states[idx]; | ||
328 | |||
329 | state->exit_latency = cpuidle_params_table[idx].exit_latency; | ||
330 | state->target_residency = cpuidle_params_table[idx].target_residency; | ||
331 | state->flags = CPUIDLE_FLAG_TIME_VALID; | ||
332 | state->enter = omap3_enter_idle_bm; | ||
333 | sprintf(state->name, "C%d", idx + 1); | ||
334 | strncpy(state->desc, descr, CPUIDLE_DESC_LEN); | ||
335 | |||
336 | } | ||
337 | |||
338 | /* Helper to register the driver_data */ | ||
339 | static inline struct omap3_idle_statedata *_fill_cstate_usage( | ||
340 | struct cpuidle_device *dev, | ||
341 | int idx) | ||
342 | { | ||
343 | struct omap3_idle_statedata *cx = &omap3_idle_data[idx]; | ||
344 | struct cpuidle_state_usage *state_usage = &dev->states_usage[idx]; | ||
345 | |||
346 | cx->valid = cpuidle_params_table[idx].valid; | ||
347 | cpuidle_set_statedata(state_usage, cx); | ||
348 | |||
349 | return cx; | ||
350 | } | ||
351 | |||
352 | /** | 351 | /** |
353 | * omap3_idle_init - Init routine for OMAP3 idle | 352 | * omap3_idle_init - Init routine for OMAP3 idle |
354 | * | 353 | * |
@@ -358,77 +357,20 @@ static inline struct omap3_idle_statedata *_fill_cstate_usage( | |||
358 | int __init omap3_idle_init(void) | 357 | int __init omap3_idle_init(void) |
359 | { | 358 | { |
360 | struct cpuidle_device *dev; | 359 | struct cpuidle_device *dev; |
361 | struct cpuidle_driver *drv = &omap3_idle_driver; | ||
362 | struct omap3_idle_statedata *cx; | ||
363 | 360 | ||
364 | mpu_pd = pwrdm_lookup("mpu_pwrdm"); | 361 | mpu_pd = pwrdm_lookup("mpu_pwrdm"); |
365 | core_pd = pwrdm_lookup("core_pwrdm"); | 362 | core_pd = pwrdm_lookup("core_pwrdm"); |
366 | per_pd = pwrdm_lookup("per_pwrdm"); | 363 | per_pd = pwrdm_lookup("per_pwrdm"); |
367 | cam_pd = pwrdm_lookup("cam_pwrdm"); | 364 | cam_pd = pwrdm_lookup("cam_pwrdm"); |
368 | 365 | ||
366 | if (!mpu_pd || !core_pd || !per_pd || !cam_pd) | ||
367 | return -ENODEV; | ||
369 | 368 | ||
370 | drv->safe_state_index = -1; | ||
371 | dev = &per_cpu(omap3_idle_dev, smp_processor_id()); | ||
372 | |||
373 | /* C1 . MPU WFI + Core active */ | ||
374 | _fill_cstate(drv, 0, "MPU ON + CORE ON"); | ||
375 | (&drv->states[0])->enter = omap3_enter_idle; | ||
376 | drv->safe_state_index = 0; | ||
377 | cx = _fill_cstate_usage(dev, 0); | ||
378 | cx->valid = 1; /* C1 is always valid */ | ||
379 | cx->mpu_state = PWRDM_POWER_ON; | ||
380 | cx->core_state = PWRDM_POWER_ON; | ||
381 | |||
382 | /* C2 . MPU WFI + Core inactive */ | ||
383 | _fill_cstate(drv, 1, "MPU ON + CORE ON"); | ||
384 | cx = _fill_cstate_usage(dev, 1); | ||
385 | cx->mpu_state = PWRDM_POWER_ON; | ||
386 | cx->core_state = PWRDM_POWER_ON; | ||
387 | |||
388 | /* C3 . MPU CSWR + Core inactive */ | ||
389 | _fill_cstate(drv, 2, "MPU RET + CORE ON"); | ||
390 | cx = _fill_cstate_usage(dev, 2); | ||
391 | cx->mpu_state = PWRDM_POWER_RET; | ||
392 | cx->core_state = PWRDM_POWER_ON; | ||
393 | |||
394 | /* C4 . MPU OFF + Core inactive */ | ||
395 | _fill_cstate(drv, 3, "MPU OFF + CORE ON"); | ||
396 | cx = _fill_cstate_usage(dev, 3); | ||
397 | cx->mpu_state = PWRDM_POWER_OFF; | ||
398 | cx->core_state = PWRDM_POWER_ON; | ||
399 | |||
400 | /* C5 . MPU RET + Core RET */ | ||
401 | _fill_cstate(drv, 4, "MPU RET + CORE RET"); | ||
402 | cx = _fill_cstate_usage(dev, 4); | ||
403 | cx->mpu_state = PWRDM_POWER_RET; | ||
404 | cx->core_state = PWRDM_POWER_RET; | ||
405 | |||
406 | /* C6 . MPU OFF + Core RET */ | ||
407 | _fill_cstate(drv, 5, "MPU OFF + CORE RET"); | ||
408 | cx = _fill_cstate_usage(dev, 5); | ||
409 | cx->mpu_state = PWRDM_POWER_OFF; | ||
410 | cx->core_state = PWRDM_POWER_RET; | ||
411 | |||
412 | /* C7 . MPU OFF + Core OFF */ | ||
413 | _fill_cstate(drv, 6, "MPU OFF + CORE OFF"); | ||
414 | cx = _fill_cstate_usage(dev, 6); | ||
415 | /* | ||
416 | * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot | ||
417 | * enable OFF mode in a stable form for previous revisions. | ||
418 | * We disable C7 state as a result. | ||
419 | */ | ||
420 | if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583)) { | ||
421 | cx->valid = 0; | ||
422 | pr_warn("%s: core off state C7 disabled due to i583\n", | ||
423 | __func__); | ||
424 | } | ||
425 | cx->mpu_state = PWRDM_POWER_OFF; | ||
426 | cx->core_state = PWRDM_POWER_OFF; | ||
427 | |||
428 | drv->state_count = OMAP3_NUM_STATES; | ||
429 | cpuidle_register_driver(&omap3_idle_driver); | 369 | cpuidle_register_driver(&omap3_idle_driver); |
430 | 370 | ||
431 | dev->state_count = OMAP3_NUM_STATES; | 371 | dev = &per_cpu(omap3_idle_dev, smp_processor_id()); |
372 | dev->cpu = 0; | ||
373 | |||
432 | if (cpuidle_register_device(dev)) { | 374 | if (cpuidle_register_device(dev)) { |
433 | printk(KERN_ERR "%s: CPUidle register device failed\n", | 375 | printk(KERN_ERR "%s: CPUidle register device failed\n", |
434 | __func__); | 376 | __func__); |
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index f386cbe9c889..be1617ca84bd 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c | |||
@@ -24,26 +24,31 @@ | |||
24 | 24 | ||
25 | #ifdef CONFIG_CPU_IDLE | 25 | #ifdef CONFIG_CPU_IDLE |
26 | 26 | ||
27 | /* Machine specific information to be recorded in the C-state driver_data */ | 27 | /* Machine specific information */ |
28 | struct omap4_idle_statedata { | 28 | struct omap4_idle_statedata { |
29 | u32 cpu_state; | 29 | u32 cpu_state; |
30 | u32 mpu_logic_state; | 30 | u32 mpu_logic_state; |
31 | u32 mpu_state; | 31 | u32 mpu_state; |
32 | u8 valid; | ||
33 | }; | 32 | }; |
34 | 33 | ||
35 | static struct cpuidle_params cpuidle_params_table[] = { | 34 | static struct omap4_idle_statedata omap4_idle_data[] = { |
36 | /* C1 - CPU0 ON + CPU1 ON + MPU ON */ | 35 | { |
37 | {.exit_latency = 2 + 2 , .target_residency = 5, .valid = 1}, | 36 | .cpu_state = PWRDM_POWER_ON, |
38 | /* C2- CPU0 OFF + CPU1 OFF + MPU CSWR */ | 37 | .mpu_state = PWRDM_POWER_ON, |
39 | {.exit_latency = 328 + 440 , .target_residency = 960, .valid = 1}, | 38 | .mpu_logic_state = PWRDM_POWER_RET, |
40 | /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ | 39 | }, |
41 | {.exit_latency = 460 + 518 , .target_residency = 1100, .valid = 1}, | 40 | { |
41 | .cpu_state = PWRDM_POWER_OFF, | ||
42 | .mpu_state = PWRDM_POWER_RET, | ||
43 | .mpu_logic_state = PWRDM_POWER_RET, | ||
44 | }, | ||
45 | { | ||
46 | .cpu_state = PWRDM_POWER_OFF, | ||
47 | .mpu_state = PWRDM_POWER_RET, | ||
48 | .mpu_logic_state = PWRDM_POWER_OFF, | ||
49 | }, | ||
42 | }; | 50 | }; |
43 | 51 | ||
44 | #define OMAP4_NUM_STATES ARRAY_SIZE(cpuidle_params_table) | ||
45 | |||
46 | struct omap4_idle_statedata omap4_idle_data[OMAP4_NUM_STATES]; | ||
47 | static struct powerdomain *mpu_pd, *cpu0_pd, *cpu1_pd; | 52 | static struct powerdomain *mpu_pd, *cpu0_pd, *cpu1_pd; |
48 | 53 | ||
49 | /** | 54 | /** |
@@ -60,8 +65,7 @@ static int omap4_enter_idle(struct cpuidle_device *dev, | |||
60 | struct cpuidle_driver *drv, | 65 | struct cpuidle_driver *drv, |
61 | int index) | 66 | int index) |
62 | { | 67 | { |
63 | struct omap4_idle_statedata *cx = | 68 | struct omap4_idle_statedata *cx = &omap4_idle_data[index]; |
64 | cpuidle_get_statedata(&dev->states_usage[index]); | ||
65 | u32 cpu1_state; | 69 | u32 cpu1_state; |
66 | int cpu_id = smp_processor_id(); | 70 | int cpu_id = smp_processor_id(); |
67 | 71 | ||
@@ -78,7 +82,7 @@ static int omap4_enter_idle(struct cpuidle_device *dev, | |||
78 | cpu1_state = pwrdm_read_pwrst(cpu1_pd); | 82 | cpu1_state = pwrdm_read_pwrst(cpu1_pd); |
79 | if (cpu1_state != PWRDM_POWER_OFF) { | 83 | if (cpu1_state != PWRDM_POWER_OFF) { |
80 | index = drv->safe_state_index; | 84 | index = drv->safe_state_index; |
81 | cx = cpuidle_get_statedata(&dev->states_usage[index]); | 85 | cx = &omap4_idle_data[index]; |
82 | } | 86 | } |
83 | 87 | ||
84 | if (index > 0) | 88 | if (index > 0) |
@@ -133,36 +137,39 @@ struct cpuidle_driver omap4_idle_driver = { | |||
133 | .name = "omap4_idle", | 137 | .name = "omap4_idle", |
134 | .owner = THIS_MODULE, | 138 | .owner = THIS_MODULE, |
135 | .en_core_tk_irqen = 1, | 139 | .en_core_tk_irqen = 1, |
140 | .states = { | ||
141 | { | ||
142 | /* C1 - CPU0 ON + CPU1 ON + MPU ON */ | ||
143 | .exit_latency = 2 + 2, | ||
144 | .target_residency = 5, | ||
145 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
146 | .enter = omap4_enter_idle, | ||
147 | .name = "C1", | ||
148 | .desc = "MPUSS ON" | ||
149 | }, | ||
150 | { | ||
151 | /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ | ||
152 | .exit_latency = 328 + 440, | ||
153 | .target_residency = 960, | ||
154 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
155 | .enter = omap4_enter_idle, | ||
156 | .name = "C2", | ||
157 | .desc = "MPUSS CSWR", | ||
158 | }, | ||
159 | { | ||
160 | /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ | ||
161 | .exit_latency = 460 + 518, | ||
162 | .target_residency = 1100, | ||
163 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
164 | .enter = omap4_enter_idle, | ||
165 | .name = "C3", | ||
166 | .desc = "MPUSS OSWR", | ||
167 | }, | ||
168 | }, | ||
169 | .state_count = ARRAY_SIZE(omap4_idle_data), | ||
170 | .safe_state_index = 0, | ||
136 | }; | 171 | }; |
137 | 172 | ||
138 | static inline void _fill_cstate(struct cpuidle_driver *drv, | ||
139 | int idx, const char *descr) | ||
140 | { | ||
141 | struct cpuidle_state *state = &drv->states[idx]; | ||
142 | |||
143 | state->exit_latency = cpuidle_params_table[idx].exit_latency; | ||
144 | state->target_residency = cpuidle_params_table[idx].target_residency; | ||
145 | state->flags = CPUIDLE_FLAG_TIME_VALID; | ||
146 | state->enter = omap4_enter_idle; | ||
147 | sprintf(state->name, "C%d", idx + 1); | ||
148 | strncpy(state->desc, descr, CPUIDLE_DESC_LEN); | ||
149 | } | ||
150 | |||
151 | static inline struct omap4_idle_statedata *_fill_cstate_usage( | ||
152 | struct cpuidle_device *dev, | ||
153 | int idx) | ||
154 | { | ||
155 | struct omap4_idle_statedata *cx = &omap4_idle_data[idx]; | ||
156 | struct cpuidle_state_usage *state_usage = &dev->states_usage[idx]; | ||
157 | |||
158 | cx->valid = cpuidle_params_table[idx].valid; | ||
159 | cpuidle_set_statedata(state_usage, cx); | ||
160 | |||
161 | return cx; | ||
162 | } | ||
163 | |||
164 | |||
165 | |||
166 | /** | 173 | /** |
167 | * omap4_idle_init - Init routine for OMAP4 idle | 174 | * omap4_idle_init - Init routine for OMAP4 idle |
168 | * | 175 | * |
@@ -171,9 +178,7 @@ static inline struct omap4_idle_statedata *_fill_cstate_usage( | |||
171 | */ | 178 | */ |
172 | int __init omap4_idle_init(void) | 179 | int __init omap4_idle_init(void) |
173 | { | 180 | { |
174 | struct omap4_idle_statedata *cx; | ||
175 | struct cpuidle_device *dev; | 181 | struct cpuidle_device *dev; |
176 | struct cpuidle_driver *drv = &omap4_idle_driver; | ||
177 | unsigned int cpu_id = 0; | 182 | unsigned int cpu_id = 0; |
178 | 183 | ||
179 | mpu_pd = pwrdm_lookup("mpu_pwrdm"); | 184 | mpu_pd = pwrdm_lookup("mpu_pwrdm"); |
@@ -182,42 +187,15 @@ int __init omap4_idle_init(void) | |||
182 | if ((!mpu_pd) || (!cpu0_pd) || (!cpu1_pd)) | 187 | if ((!mpu_pd) || (!cpu0_pd) || (!cpu1_pd)) |
183 | return -ENODEV; | 188 | return -ENODEV; |
184 | 189 | ||
185 | |||
186 | drv->safe_state_index = -1; | ||
187 | dev = &per_cpu(omap4_idle_dev, cpu_id); | 190 | dev = &per_cpu(omap4_idle_dev, cpu_id); |
188 | dev->cpu = cpu_id; | 191 | dev->cpu = cpu_id; |
189 | 192 | ||
190 | /* C1 - CPU0 ON + CPU1 ON + MPU ON */ | ||
191 | _fill_cstate(drv, 0, "MPUSS ON"); | ||
192 | drv->safe_state_index = 0; | ||
193 | cx = _fill_cstate_usage(dev, 0); | ||
194 | cx->valid = 1; /* C1 is always valid */ | ||
195 | cx->cpu_state = PWRDM_POWER_ON; | ||
196 | cx->mpu_state = PWRDM_POWER_ON; | ||
197 | cx->mpu_logic_state = PWRDM_POWER_RET; | ||
198 | |||
199 | /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ | ||
200 | _fill_cstate(drv, 1, "MPUSS CSWR"); | ||
201 | cx = _fill_cstate_usage(dev, 1); | ||
202 | cx->cpu_state = PWRDM_POWER_OFF; | ||
203 | cx->mpu_state = PWRDM_POWER_RET; | ||
204 | cx->mpu_logic_state = PWRDM_POWER_RET; | ||
205 | |||
206 | /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ | ||
207 | _fill_cstate(drv, 2, "MPUSS OSWR"); | ||
208 | cx = _fill_cstate_usage(dev, 2); | ||
209 | cx->cpu_state = PWRDM_POWER_OFF; | ||
210 | cx->mpu_state = PWRDM_POWER_RET; | ||
211 | cx->mpu_logic_state = PWRDM_POWER_OFF; | ||
212 | |||
213 | drv->state_count = OMAP4_NUM_STATES; | ||
214 | cpuidle_register_driver(&omap4_idle_driver); | 193 | cpuidle_register_driver(&omap4_idle_driver); |
215 | 194 | ||
216 | dev->state_count = OMAP4_NUM_STATES; | ||
217 | if (cpuidle_register_device(dev)) { | 195 | if (cpuidle_register_device(dev)) { |
218 | pr_err("%s: CPUidle register device failed\n", __func__); | 196 | pr_err("%s: CPUidle register device failed\n", __func__); |
219 | return -EIO; | 197 | return -EIO; |
220 | } | 198 | } |
221 | 199 | ||
222 | return 0; | 200 | return 0; |
223 | } | 201 | } |
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 36fa90b6ece8..78564895e914 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h | |||
@@ -38,27 +38,6 @@ static inline int omap4_opp_init(void) | |||
38 | } | 38 | } |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | /* | ||
42 | * cpuidle mach specific parameters | ||
43 | * | ||
44 | * The board code can override the default C-states definition using | ||
45 | * omap3_pm_init_cpuidle | ||
46 | */ | ||
47 | struct cpuidle_params { | ||
48 | u32 exit_latency; /* exit_latency = sleep + wake-up latencies */ | ||
49 | u32 target_residency; | ||
50 | u8 valid; /* validates the C-state */ | ||
51 | }; | ||
52 | |||
53 | #if defined(CONFIG_PM) && defined(CONFIG_CPU_IDLE) | ||
54 | extern void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params); | ||
55 | #else | ||
56 | static | ||
57 | inline void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params) | ||
58 | { | ||
59 | } | ||
60 | #endif | ||
61 | |||
62 | extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); | 41 | extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); |
63 | extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); | 42 | extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); |
64 | 43 | ||