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 /arch/arm/mach-omap2/vc.c | |
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>
Diffstat (limited to 'arch/arm/mach-omap2/vc.c')
-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 | ||