1 /* 2 * linux/arch/arm/mach-omap2/cpuidle34xx.c 3 * 4 * OMAP3 CPU IDLE Routines 5 * 6 * Copyright (C) 2008 Texas Instruments, Inc. 7 * Rajendra Nayak <rnayak@ti.com> 8 * 9 * Copyright (C) 2007 Texas Instruments, Inc. 10 * Karthik Dasu <karthik-dp@ti.com> 11 * 12 * Copyright (C) 2006 Nokia Corporation 13 * Tony Lindgren <tony@atomide.com> 14 * 15 * Copyright (C) 2005 Texas Instruments, Inc. 16 * Richard Woodruff <r-woodruff2@ti.com> 17 * 18 * Based on pm.c for omap2 19 * 20 * This program is free software; you can redistribute it and/or modify 21 * it under the terms of the GNU General Public License version 2 as 22 * published by the Free Software Foundation. 23 */ 24 25 #include <linux/sched.h> 26 #include <linux/cpuidle.h> 27 28 #include <plat/prcm.h> 29 #include <plat/irqs.h> 30 #include <plat/powerdomain.h> 31 #include <plat/clockdomain.h> 32 #include <plat/serial.h> 33 34 #include "pm.h" 35 #include "control.h" 36 37 #ifdef CONFIG_CPU_IDLE 38 39 #define OMAP3_MAX_STATES 7 40 #define OMAP3_STATE_C1 0 /* C1 - MPU WFI + Core active */ 41 #define OMAP3_STATE_C2 1 /* C2 - MPU WFI + Core inactive */ 42 #define OMAP3_STATE_C3 2 /* C3 - MPU CSWR + Core inactive */ 43 #define OMAP3_STATE_C4 3 /* C4 - MPU OFF + Core iactive */ 44 #define OMAP3_STATE_C5 4 /* C5 - MPU RET + Core RET */ 45 #define OMAP3_STATE_C6 5 /* C6 - MPU OFF + Core RET */ 46 #define OMAP3_STATE_C7 6 /* C7 - MPU OFF + Core OFF */ 47 48 #define OMAP3_STATE_MAX OMAP3_STATE_C7 49 50 struct omap3_processor_cx { 51 u8 valid; 52 u8 type; 53 u32 sleep_latency; 54 u32 wakeup_latency; 55 u32 mpu_state; 56 u32 core_state; 57 u32 threshold; 58 u32 flags; 59 }; 60 61 struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES]; 62 struct omap3_processor_cx current_cx_state; 63 struct powerdomain *mpu_pd, *core_pd, *per_pd; 64 struct powerdomain *cam_pd; 65 66 /* 67 * The latencies/thresholds for various C states have 68 * to be configured from the respective board files. 69 * These are some default values (which might not provide 70 * the best power savings) used on boards which do not 71 * pass these details from the board file. 72 */ 73 static struct cpuidle_params cpuidle_params_table[] = { 74 /* C1 */ 75 {1, 2, 2, 5}, 76 /* C2 */ 77 {1, 10, 10, 30}, 78 /* C3 */ 79 {1, 50, 50, 300}, 80 /* C4 */ 81 {1, 1500, 1800, 4000}, 82 /* C5 */ 83 {1, 2500, 7500, 12000}, 84 /* C6 */ 85 {1, 3000, 8500, 15000}, 86 /* C7 */ 87 {1, 10000, 30000, 300000}, 88 }; 89 90 static int omap3_idle_bm_check(void) 91 { 92 if (!omap3_can_sleep()) 93 return 1; 94 return 0; 95 } 96 97 static int _cpuidle_allow_idle(struct powerdomain *pwrdm, 98 struct clockdomain *clkdm) 99 { 100 omap2_clkdm_allow_idle(clkdm); 101 return 0; 102 } 103 104 static int _cpuidle_deny_idle(struct powerdomain *pwrdm, 105 struct clockdomain *clkdm) 106 { 107 omap2_clkdm_deny_idle(clkdm); 108 return 0; 109 } 110 111 /** 112 * omap3_enter_idle - Programs OMAP3 to enter the specified state 113 * @dev: cpuidle device 114 * @state: The target state to be programmed 115 * 116 * Called from the CPUidle framework to program the device to the 117 * specified target state selected by the governor. 118 */ 119 static int omap3_enter_idle(struct cpuidle_device *dev, 120 struct cpuidle_state *state) 121 { 122 struct omap3_processor_cx *cx = cpuidle_get_statedata(state); 123 struct timespec ts_preidle, ts_postidle, ts_idle; 124 u32 mpu_state = cx->mpu_state, core_state = cx->core_state; 125 126 current_cx_state = *cx; 127 128 /* Used to keep track of the total time in idle */ 129 getnstimeofday(&ts_preidle); 130 131 local_irq_disable(); 132 local_fiq_disable(); 133 134 pwrdm_set_next_pwrst(mpu_pd, mpu_state); 135 pwrdm_set_next_pwrst(core_pd, core_state); 136 137 if (omap_irq_pending() || need_resched()) 138 goto return_sleep_time; 139 140 if (cx->type == OMAP3_STATE_C1) { 141 pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle); 142 pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle); 143 } 144 145 /* Execute ARM wfi */ 146 omap_sram_idle(); 147 148 if (cx->type == OMAP3_STATE_C1) { 149 pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle); 150 pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle); 151 } 152 153 return_sleep_time: 154 getnstimeofday(&ts_postidle); 155 ts_idle = timespec_sub(ts_postidle, ts_preidle); 156 157 local_irq_enable(); 158 local_fiq_enable(); 159 160 return ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * USEC_PER_SEC; 161 } 162 163 /** 164 * next_valid_state - Find next valid c-state 165 * @dev: cpuidle device 166 * @state: Currently selected c-state 167 * 168 * If the current state is valid, it is returned back to the caller. 169 * Else, this function searches for a lower c-state which is still 170 * valid (as defined in omap3_power_states[]). 171 */ 172 static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev, 173 struct cpuidle_state *curr) 174 { 175 struct cpuidle_state *next = NULL; 176 struct omap3_processor_cx *cx; 177 178 cx = (struct omap3_processor_cx *)cpuidle_get_statedata(curr); 179 180 /* Check if current state is valid */ 181 if (cx->valid) { 182 return curr; 183 } else { 184 u8 idx = OMAP3_STATE_MAX; 185 186 /* 187 * Reach the current state starting at highest C-state 188 */ 189 for (; idx >= OMAP3_STATE_C1; idx--) { 190 if (&dev->states[idx] == curr) { 191 next = &dev->states[idx]; 192 break; 193 } 194 } 195 196 /* 197 * Should never hit this condition. 198 */ 199 WARN_ON(next == NULL); 200 201 /* 202 * Drop to next valid state. 203 * Start search from the next (lower) state. 204 */ 205 idx--; 206 for (; idx >= OMAP3_STATE_C1; idx--) { 207 struct omap3_processor_cx *cx; 208 209 cx = cpuidle_get_statedata(&dev->states[idx]); 210 if (cx->valid) { 211 next = &dev->states[idx]; 212 break; 213 } 214 } 215 /* 216 * C1 and C2 are always valid. 217 * So, no need to check for 'next==NULL' outside this loop. 218 */ 219 } 220 221 return next; 222 } 223 224 /** 225 * omap3_enter_idle_bm - Checks for any bus activity 226 * @dev: cpuidle device 227 * @state: The target state to be programmed 228 * 229 * Used for C states with CPUIDLE_FLAG_CHECK_BM flag set. This 230 * function checks for any pending activity and then programs the 231 * device to the specified or a safer state. 232 */ 233 static int omap3_enter_idle_bm(struct cpuidle_device *dev, 234 struct cpuidle_state *state) 235 { 236 struct cpuidle_state *new_state = next_valid_state(dev, state); 237 u32 core_next_state, per_next_state = 0, per_saved_state = 0; 238 u32 cam_state; 239 struct omap3_processor_cx *cx; 240 int ret; 241 242 if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) { 243 BUG_ON(!dev->safe_state); 244 new_state = dev->safe_state; 245 goto select_state; 246 } 247 248 cx = cpuidle_get_statedata(state); 249 core_next_state = cx->core_state; 250 251 /* 252 * FIXME: we currently manage device-specific idle states 253 * for PER and CORE in combination with CPU-specific 254 * idle states. This is wrong, and device-specific 255 * idle managment needs to be separated out into 256 * its own code. 257 */ 258 259 /* 260 * Prevent idle completely if CAM is active. 261 * CAM does not have wakeup capability in OMAP3. 262 */ 263 cam_state = pwrdm_read_pwrst(cam_pd); 264 if (cam_state == PWRDM_POWER_ON) { 265 new_state = dev->safe_state; 266 goto select_state; 267 } 268 269 /* 270 * Prevent PER off if CORE is not in retention or off as this 271 * would disable PER wakeups completely. 272 */ 273 per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd); 274 if ((per_next_state == PWRDM_POWER_OFF) && 275 (core_next_state > PWRDM_POWER_RET)) 276 per_next_state = PWRDM_POWER_RET; 277 278 /* Are we changing PER target state? */ 279 if (per_next_state != per_saved_state) 280 pwrdm_set_next_pwrst(per_pd, per_next_state); 281 282 select_state: 283 dev->last_state = new_state; 284 ret = omap3_enter_idle(dev, new_state); 285 286 /* Restore original PER state if it was modified */ 287 if (per_next_state != per_saved_state) 288 pwrdm_set_next_pwrst(per_pd, per_saved_state); 289 290 return ret; 291 } 292 293 DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); 294 295 /** 296 * omap3_cpuidle_update_states - Update the cpuidle states. 297 * 298 * Currently, this function toggles the validity of idle states based upon 299 * the flag 'enable_off_mode'. When the flag is set all states are valid. 300 * Else, states leading to OFF state set to be invalid. 301 */ 302 void omap3_cpuidle_update_states(void) 303 { 304 int i; 305 306 for (i = OMAP3_STATE_C1; i < OMAP3_MAX_STATES; i++) { 307 struct omap3_processor_cx *cx = &omap3_power_states[i]; 308 309 if (enable_off_mode) { 310 cx->valid = 1; 311 } else { 312 if ((cx->mpu_state == PWRDM_POWER_OFF) || 313 (cx->core_state == PWRDM_POWER_OFF)) 314 cx->valid = 0; 315 } 316 } 317 } 318 319 void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params) 320 { 321 int i; 322 323 if (!cpuidle_board_params) 324 return; 325 326 for (i = OMAP3_STATE_C1; i < OMAP3_MAX_STATES; i++) { 327 cpuidle_params_table[i].valid = 328 cpuidle_board_params[i].valid; 329 cpuidle_params_table[i].sleep_latency = 330 cpuidle_board_params[i].sleep_latency; 331 cpuidle_params_table[i].wake_latency = 332 cpuidle_board_params[i].wake_latency; 333 cpuidle_params_table[i].threshold = 334 cpuidle_board_params[i].threshold; 335 } 336 return; 337 } 338 339 /* omap3_init_power_states - Initialises the OMAP3 specific C states. 340 * 341 * Below is the desciption of each C state. 342 * C1 . MPU WFI + Core active 343 * C2 . MPU WFI + Core inactive 344 * C3 . MPU CSWR + Core inactive 345 * C4 . MPU OFF + Core inactive 346 * C5 . MPU CSWR + Core CSWR 347 * C6 . MPU OFF + Core CSWR 348 * C7 . MPU OFF + Core OFF 349 */ 350 void omap_init_power_states(void) 351 { 352 /* C1 . MPU WFI + Core active */ 353 omap3_power_states[OMAP3_STATE_C1].valid = 354 cpuidle_params_table[OMAP3_STATE_C1].valid; 355 omap3_power_states[OMAP3_STATE_C1].type = OMAP3_STATE_C1; 356 omap3_power_states[OMAP3_STATE_C1].sleep_latency = 357 cpuidle_params_table[OMAP3_STATE_C1].sleep_latency; 358 omap3_power_states[OMAP3_STATE_C1].wakeup_latency = 359 cpuidle_params_table[OMAP3_STATE_C1].wake_latency; 360 omap3_power_states[OMAP3_STATE_C1].threshold = 361 cpuidle_params_table[OMAP3_STATE_C1].threshold; 362 omap3_power_states[OMAP3_STATE_C1].mpu_state = PWRDM_POWER_ON; 363 omap3_power_states[OMAP3_STATE_C1].core_state = PWRDM_POWER_ON; 364 omap3_power_states[OMAP3_STATE_C1].flags = CPUIDLE_FLAG_TIME_VALID; 365 366 /* C2 . MPU WFI + Core inactive */ 367 omap3_power_states[OMAP3_STATE_C2].valid = 368 cpuidle_params_table[OMAP3_STATE_C2].valid; 369 omap3_power_states[OMAP3_STATE_C2].type = OMAP3_STATE_C2; 370 omap3_power_states[OMAP3_STATE_C2].sleep_latency = 371 cpuidle_params_table[OMAP3_STATE_C2].sleep_latency; 372 omap3_power_states[OMAP3_STATE_C2].wakeup_latency = 373 cpuidle_params_table[OMAP3_STATE_C2].wake_latency; 374 omap3_power_states[OMAP3_STATE_C2].threshold = 375 cpuidle_params_table[OMAP3_STATE_C2].threshold; 376 omap3_power_states[OMAP3_STATE_C2].mpu_state = PWRDM_POWER_ON; 377 omap3_power_states[OMAP3_STATE_C2].core_state = PWRDM_POWER_ON; 378 omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID | 379 CPUIDLE_FLAG_CHECK_BM; 380 381 /* C3 . MPU CSWR + Core inactive */ 382 omap3_power_states[OMAP3_STATE_C3].valid = 383 cpuidle_params_table[OMAP3_STATE_C3].valid; 384 omap3_power_states[OMAP3_STATE_C3].type = OMAP3_STATE_C3; 385 omap3_power_states[OMAP3_STATE_C3].sleep_latency = 386 cpuidle_params_table[OMAP3_STATE_C3].sleep_latency; 387 omap3_power_states[OMAP3_STATE_C3].wakeup_latency = 388 cpuidle_params_table[OMAP3_STATE_C3].wake_latency; 389 omap3_power_states[OMAP3_STATE_C3].threshold = 390 cpuidle_params_table[OMAP3_STATE_C3].threshold; 391 omap3_power_states[OMAP3_STATE_C3].mpu_state = PWRDM_POWER_RET; 392 omap3_power_states[OMAP3_STATE_C3].core_state = PWRDM_POWER_ON; 393 omap3_power_states[OMAP3_STATE_C3].flags = CPUIDLE_FLAG_TIME_VALID | 394 CPUIDLE_FLAG_CHECK_BM; 395 396 /* C4 . MPU OFF + Core inactive */ 397 omap3_power_states[OMAP3_STATE_C4].valid = 398 cpuidle_params_table[OMAP3_STATE_C4].valid; 399 omap3_power_states[OMAP3_STATE_C4].type = OMAP3_STATE_C4; 400 omap3_power_states[OMAP3_STATE_C4].sleep_latency = 401 cpuidle_params_table[OMAP3_STATE_C4].sleep_latency; 402 omap3_power_states[OMAP3_STATE_C4].wakeup_latency = 403 cpuidle_params_table[OMAP3_STATE_C4].wake_latency; 404 omap3_power_states[OMAP3_STATE_C4].threshold = 405 cpuidle_params_table[OMAP3_STATE_C4].threshold; 406 omap3_power_states[OMAP3_STATE_C4].mpu_state = PWRDM_POWER_OFF; 407 omap3_power_states[OMAP3_STATE_C4].core_state = PWRDM_POWER_ON; 408 omap3_power_states[OMAP3_STATE_C4].flags = CPUIDLE_FLAG_TIME_VALID | 409 CPUIDLE_FLAG_CHECK_BM; 410 411 /* C5 . MPU CSWR + Core CSWR*/ 412 omap3_power_states[OMAP3_STATE_C5].valid = 413 cpuidle_params_table[OMAP3_STATE_C5].valid; 414 omap3_power_states[OMAP3_STATE_C5].type = OMAP3_STATE_C5; 415 omap3_power_states[OMAP3_STATE_C5].sleep_latency = 416 cpuidle_params_table[OMAP3_STATE_C5].sleep_latency; 417 omap3_power_states[OMAP3_STATE_C5].wakeup_latency = 418 cpuidle_params_table[OMAP3_STATE_C5].wake_latency; 419 omap3_power_states[OMAP3_STATE_C5].threshold = 420 cpuidle_params_table[OMAP3_STATE_C5].threshold; 421 omap3_power_states[OMAP3_STATE_C5].mpu_state = PWRDM_POWER_RET; 422 omap3_power_states[OMAP3_STATE_C5].core_state = PWRDM_POWER_RET; 423 omap3_power_states[OMAP3_STATE_C5].flags = CPUIDLE_FLAG_TIME_VALID | 424 CPUIDLE_FLAG_CHECK_BM; 425 426 /* C6 . MPU OFF + Core CSWR */ 427 omap3_power_states[OMAP3_STATE_C6].valid = 428 cpuidle_params_table[OMAP3_STATE_C6].valid; 429 omap3_power_states[OMAP3_STATE_C6].type = OMAP3_STATE_C6; 430 omap3_power_states[OMAP3_STATE_C6].sleep_latency = 431 cpuidle_params_table[OMAP3_STATE_C6].sleep_latency; 432 omap3_power_states[OMAP3_STATE_C6].wakeup_latency = 433 cpuidle_params_table[OMAP3_STATE_C6].wake_latency; 434 omap3_power_states[OMAP3_STATE_C6].threshold = 435 cpuidle_params_table[OMAP3_STATE_C6].threshold; 436 omap3_power_states[OMAP3_STATE_C6].mpu_state = PWRDM_POWER_OFF; 437 omap3_power_states[OMAP3_STATE_C6].core_state = PWRDM_POWER_RET; 438 omap3_power_states[OMAP3_STATE_C6].flags = CPUIDLE_FLAG_TIME_VALID | 439 CPUIDLE_FLAG_CHECK_BM; 440 441 /* C7 . MPU OFF + Core OFF */ 442 omap3_power_states[OMAP3_STATE_C7].valid = 443 cpuidle_params_table[OMAP3_STATE_C7].valid; 444 omap3_power_states[OMAP3_STATE_C7].type = OMAP3_STATE_C7; 445 omap3_power_states[OMAP3_STATE_C7].sleep_latency = 446 cpuidle_params_table[OMAP3_STATE_C7].sleep_latency; 447 omap3_power_states[OMAP3_STATE_C7].wakeup_latency = 448 cpuidle_params_table[OMAP3_STATE_C7].wake_latency; 449 omap3_power_states[OMAP3_STATE_C7].threshold = 450 cpuidle_params_table[OMAP3_STATE_C7].threshold; 451 omap3_power_states[OMAP3_STATE_C7].mpu_state = PWRDM_POWER_OFF; 452 omap3_power_states[OMAP3_STATE_C7].core_state = PWRDM_POWER_OFF; 453 omap3_power_states[OMAP3_STATE_C7].flags = CPUIDLE_FLAG_TIME_VALID | 454 CPUIDLE_FLAG_CHECK_BM; 455 } 456 457 struct cpuidle_driver omap3_idle_driver = { 458 .name = "omap3_idle", 459 .owner = THIS_MODULE, 460 }; 461 462 /** 463 * omap3_idle_init - Init routine for OMAP3 idle 464 * 465 * Registers the OMAP3 specific cpuidle driver with the cpuidle 466 * framework with the valid set of states. 467 */ 468 int __init omap3_idle_init(void) 469 { 470 int i, count = 0; 471 struct omap3_processor_cx *cx; 472 struct cpuidle_state *state; 473 struct cpuidle_device *dev; 474 475 mpu_pd = pwrdm_lookup("mpu_pwrdm"); 476 core_pd = pwrdm_lookup("core_pwrdm"); 477 per_pd = pwrdm_lookup("per_pwrdm"); 478 cam_pd = pwrdm_lookup("cam_pwrdm"); 479 480 omap_init_power_states(); 481 cpuidle_register_driver(&omap3_idle_driver); 482 483 dev = &per_cpu(omap3_idle_dev, smp_processor_id()); 484 485 for (i = OMAP3_STATE_C1; i < OMAP3_MAX_STATES; i++) { 486 cx = &omap3_power_states[i]; 487 state = &dev->states[count]; 488 489 if (!cx->valid) 490 continue; 491 cpuidle_set_statedata(state, cx); 492 state->exit_latency = cx->sleep_latency + cx->wakeup_latency; 493 state->target_residency = cx->threshold; 494 state->flags = cx->flags; 495 state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ? 496 omap3_enter_idle_bm : omap3_enter_idle; 497 if (cx->type == OMAP3_STATE_C1) 498 dev->safe_state = state; 499 sprintf(state->name, "C%d", count+1); 500 count++; 501 } 502 503 if (!count) 504 return -EINVAL; 505 dev->state_count = count; 506 507 omap3_cpuidle_update_states(); 508 509 if (cpuidle_register_device(dev)) { 510 printk(KERN_ERR "%s: CPUidle register device failed\n", 511 __func__); 512 return -EIO; 513 } 514 515 return 0; 516 } 517 #else 518 int __init omap3_idle_init(void) 519 { 520 return 0; 521 } 522 #endif /* CONFIG_CPU_IDLE */ 523