diff options
| author | Tero Kristo <t-kristo@ti.com> | 2012-09-25 12:33:38 -0400 |
|---|---|---|
| committer | Kevin Hilman <khilman@ti.com> | 2012-11-05 18:11:32 -0500 |
| commit | 9a1729cbaaf1a9d1fd27f80cd488ef182fe033a0 (patch) | |
| tree | d5d91e6c8f3830da955ac9bf7e690f4ba4dce295 | |
| parent | 27c16b7026a9ca6455dd319fb00a28c5bb2023b6 (diff) | |
ARM: OMAP4: VC: calculate ramp times
OMAP4 VC code now uses voltage deltas + slew rates for calculating
actual ramp times for voltage changes. Both retention / sleep +
off mode voltage ramp times are setup at the same time during
initialization.
Signed-off-by: Tero Kristo <t-kristo@ti.com>
Signed-off-by: Kevin Hilman <khilman@ti.com>
| -rw-r--r-- | arch/arm/mach-omap2/vc.c | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c index 73b4bcd67023..07e2090d7119 100644 --- a/arch/arm/mach-omap2/vc.c +++ b/arch/arm/mach-omap2/vc.c | |||
| @@ -308,12 +308,106 @@ static void __init omap3_vc_init_channel(struct voltagedomain *voltdm) | |||
| 308 | omap3_set_off_timings(voltdm); | 308 | omap3_set_off_timings(voltdm); |
| 309 | } | 309 | } |
| 310 | 310 | ||
| 311 | /** | ||
| 312 | * omap4_calc_volt_ramp - calculates voltage ramping delays on omap4 | ||
| 313 | * @voltdm: channel to calculate values for | ||
| 314 | * @voltage_diff: voltage difference in microvolts | ||
| 315 | * | ||
| 316 | * Calculates voltage ramp prescaler + counter values for a voltage | ||
| 317 | * difference on omap4. Returns a field value suitable for writing to | ||
| 318 | * VOLTSETUP register for a channel in following format: | ||
| 319 | * bits[8:9] prescaler ... bits[0:5] counter. See OMAP4 TRM for reference. | ||
| 320 | */ | ||
| 321 | static u32 omap4_calc_volt_ramp(struct voltagedomain *voltdm, u32 voltage_diff) | ||
| 322 | { | ||
| 323 | u32 prescaler; | ||
| 324 | u32 cycles; | ||
| 325 | u32 time; | ||
| 326 | |||
| 327 | time = voltage_diff / voltdm->pmic->slew_rate; | ||
| 328 | |||
| 329 | cycles = voltdm->sys_clk.rate / 1000 * time / 1000; | ||
| 330 | |||
| 331 | cycles /= 64; | ||
| 332 | prescaler = 0; | ||
| 333 | |||
| 334 | /* shift to next prescaler until no overflow */ | ||
| 335 | |||
| 336 | /* scale for div 256 = 64 * 4 */ | ||
| 337 | if (cycles > 63) { | ||
| 338 | cycles /= 4; | ||
| 339 | prescaler++; | ||
| 340 | } | ||
| 341 | |||
| 342 | /* scale for div 512 = 256 * 2 */ | ||
| 343 | if (cycles > 63) { | ||
| 344 | cycles /= 2; | ||
| 345 | prescaler++; | ||
| 346 | } | ||
| 347 | |||
| 348 | /* scale for div 2048 = 512 * 4 */ | ||
| 349 | if (cycles > 63) { | ||
| 350 | cycles /= 4; | ||
| 351 | prescaler++; | ||
| 352 | } | ||
| 353 | |||
| 354 | /* check for overflow => invalid ramp time */ | ||
| 355 | if (cycles > 63) { | ||
| 356 | pr_warn("%s: invalid setuptime for vdd_%s\n", __func__, | ||
| 357 | voltdm->name); | ||
| 358 | return 0; | ||
| 359 | } | ||
| 360 | |||
| 361 | cycles++; | ||
| 362 | |||
| 363 | return (prescaler << OMAP4430_RAMP_UP_PRESCAL_SHIFT) | | ||
| 364 | (cycles << OMAP4430_RAMP_UP_COUNT_SHIFT); | ||
| 365 | } | ||
| 366 | |||
| 367 | /** | ||
| 368 | * omap4_set_timings - set voltage ramp timings for a channel | ||
| 369 | * @voltdm: channel to configure | ||
| 370 | * @off_mode: whether off-mode values are used | ||
| 371 | * | ||
| 372 | * Calculates and sets the voltage ramp up / down values for a channel. | ||
| 373 | */ | ||
| 374 | static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode) | ||
| 375 | { | ||
| 376 | u32 val; | ||
| 377 | u32 ramp; | ||
| 378 | int offset; | ||
| 379 | |||
| 380 | if (off_mode) { | ||
| 381 | ramp = omap4_calc_volt_ramp(voltdm, | ||
| 382 | voltdm->vc_param->on - voltdm->vc_param->off); | ||
| 383 | offset = voltdm->vfsm->voltsetup_off_reg; | ||
| 384 | } else { | ||
| 385 | ramp = omap4_calc_volt_ramp(voltdm, | ||
| 386 | voltdm->vc_param->on - voltdm->vc_param->ret); | ||
| 387 | offset = voltdm->vfsm->voltsetup_reg; | ||
| 388 | } | ||
| 389 | |||
| 390 | if (!ramp) | ||
| 391 | return; | ||
| 392 | |||
| 393 | val = voltdm->read(offset); | ||
| 394 | |||
| 395 | val |= ramp << OMAP4430_RAMP_DOWN_COUNT_SHIFT; | ||
| 396 | |||
| 397 | val |= ramp << OMAP4430_RAMP_UP_COUNT_SHIFT; | ||
| 398 | |||
| 399 | voltdm->write(val, offset); | ||
| 400 | } | ||
| 401 | |||
| 311 | /* OMAP4 specific voltage init functions */ | 402 | /* OMAP4 specific voltage init functions */ |
| 312 | static void __init omap4_vc_init_channel(struct voltagedomain *voltdm) | 403 | static void __init omap4_vc_init_channel(struct voltagedomain *voltdm) |
| 313 | { | 404 | { |
| 314 | static bool is_initialized; | 405 | static bool is_initialized; |
| 315 | u32 vc_val; | 406 | u32 vc_val; |
| 316 | 407 | ||
| 408 | omap4_set_timings(voltdm, true); | ||
| 409 | omap4_set_timings(voltdm, false); | ||
| 410 | |||
| 317 | if (is_initialized) | 411 | if (is_initialized) |
| 318 | return; | 412 | return; |
| 319 | 413 | ||
