diff options
| author | Tero Kristo <t-kristo@ti.com> | 2012-09-25 12:33:41 -0400 |
|---|---|---|
| committer | Kevin Hilman <khilman@ti.com> | 2012-11-05 18:20:59 -0500 |
| commit | d68ff977b82954fed8e3f4bde8431517455c2003 (patch) | |
| tree | 8df4bd1b589f79f177f69f08f5740bc6f181c351 | |
| parent | 085b30250041cd485555f547f625ec03341592dd (diff) | |
ARM: OMAP3+: voltage: use oscillator data to calculate setup times
We now use the previously defined oscillator setup / shutdown times
to calculate the register values for CLKSETUP.
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 | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c index 07e2090d7119..5d5f9e52f89f 100644 --- a/arch/arm/mach-omap2/vc.c +++ b/arch/arm/mach-omap2/vc.c | |||
| @@ -11,13 +11,19 @@ | |||
| 11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
| 12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
| 13 | #include <linux/bug.h> | 13 | #include <linux/bug.h> |
| 14 | #include <linux/io.h> | ||
| 14 | 15 | ||
| 16 | #include <asm/div64.h> | ||
| 17 | |||
| 18 | #include "iomap.h" | ||
| 15 | #include "soc.h" | 19 | #include "soc.h" |
| 16 | #include "voltage.h" | 20 | #include "voltage.h" |
| 17 | #include "vc.h" | 21 | #include "vc.h" |
| 18 | #include "prm-regbits-34xx.h" | 22 | #include "prm-regbits-34xx.h" |
| 19 | #include "prm-regbits-44xx.h" | 23 | #include "prm-regbits-44xx.h" |
| 20 | #include "prm44xx.h" | 24 | #include "prm44xx.h" |
| 25 | #include "pm.h" | ||
| 26 | #include "scrm44xx.h" | ||
| 21 | 27 | ||
| 22 | /** | 28 | /** |
| 23 | * struct omap_vc_channel_cfg - describe the cfg_channel bitfield | 29 | * struct omap_vc_channel_cfg - describe the cfg_channel bitfield |
| @@ -204,6 +210,18 @@ int omap_vc_bypass_scale(struct voltagedomain *voltdm, | |||
| 204 | return 0; | 210 | return 0; |
| 205 | } | 211 | } |
| 206 | 212 | ||
| 213 | /* Convert microsecond value to number of 32kHz clock cycles */ | ||
| 214 | static inline u32 omap_usec_to_32k(u32 usec) | ||
| 215 | { | ||
| 216 | return DIV_ROUND_UP_ULL(32768ULL * (u64)usec, 1000000ULL); | ||
| 217 | } | ||
| 218 | |||
| 219 | /* Set oscillator setup time for omap3 */ | ||
| 220 | static void omap3_set_clksetup(u32 usec, struct voltagedomain *voltdm) | ||
| 221 | { | ||
| 222 | voltdm->write(omap_usec_to_32k(usec), OMAP3_PRM_CLKSETUP_OFFSET); | ||
| 223 | } | ||
| 224 | |||
| 207 | /** | 225 | /** |
| 208 | * omap3_set_i2c_timings - sets i2c sleep timings for a channel | 226 | * omap3_set_i2c_timings - sets i2c sleep timings for a channel |
| 209 | * @voltdm: channel to configure | 227 | * @voltdm: channel to configure |
| @@ -220,6 +238,12 @@ static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode) | |||
| 220 | unsigned long voltsetup1; | 238 | unsigned long voltsetup1; |
| 221 | u32 tgt_volt; | 239 | u32 tgt_volt; |
| 222 | 240 | ||
| 241 | /* | ||
| 242 | * Oscillator is shut down only if we are using sys_off_mode pad, | ||
| 243 | * thus we set a minimal setup time here | ||
| 244 | */ | ||
| 245 | omap3_set_clksetup(1, voltdm); | ||
| 246 | |||
| 223 | if (off_mode) | 247 | if (off_mode) |
| 224 | tgt_volt = voltdm->vc_param->off; | 248 | tgt_volt = voltdm->vc_param->off; |
| 225 | else | 249 | else |
| @@ -260,6 +284,7 @@ static void omap3_set_off_timings(struct voltagedomain *voltdm) | |||
| 260 | unsigned long voltsetup2; | 284 | unsigned long voltsetup2; |
| 261 | unsigned long voltsetup2_old; | 285 | unsigned long voltsetup2_old; |
| 262 | u32 val; | 286 | u32 val; |
| 287 | u32 tstart, tshut; | ||
| 263 | 288 | ||
| 264 | /* check if sys_off_mode is used to control off-mode voltages */ | 289 | /* check if sys_off_mode is used to control off-mode voltages */ |
| 265 | val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET); | 290 | val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET); |
| @@ -269,6 +294,9 @@ static void omap3_set_off_timings(struct voltagedomain *voltdm) | |||
| 269 | return; | 294 | return; |
| 270 | } | 295 | } |
| 271 | 296 | ||
| 297 | omap_pm_get_oscillator(&tstart, &tshut); | ||
| 298 | omap3_set_clksetup(tstart, voltdm); | ||
| 299 | |||
| 272 | clksetup = voltdm->read(OMAP3_PRM_CLKSETUP_OFFSET); | 300 | clksetup = voltdm->read(OMAP3_PRM_CLKSETUP_OFFSET); |
| 273 | 301 | ||
| 274 | /* voltsetup 2 in us */ | 302 | /* voltsetup 2 in us */ |
| @@ -365,6 +393,30 @@ static u32 omap4_calc_volt_ramp(struct voltagedomain *voltdm, u32 voltage_diff) | |||
| 365 | } | 393 | } |
| 366 | 394 | ||
| 367 | /** | 395 | /** |
| 396 | * omap4_usec_to_val_scrm - convert microsecond value to SCRM module bitfield | ||
| 397 | * @usec: microseconds | ||
| 398 | * @shift: number of bits to shift left | ||
| 399 | * @mask: bitfield mask | ||
| 400 | * | ||
| 401 | * Converts microsecond value to OMAP4 SCRM bitfield. Bitfield is | ||
| 402 | * shifted to requested position, and checked agains the mask value. | ||
| 403 | * If larger, forced to the max value of the field (i.e. the mask itself.) | ||
| 404 | * Returns the SCRM bitfield value. | ||
| 405 | */ | ||
| 406 | static u32 omap4_usec_to_val_scrm(u32 usec, int shift, u32 mask) | ||
| 407 | { | ||
| 408 | u32 val; | ||
| 409 | |||
| 410 | val = omap_usec_to_32k(usec) << shift; | ||
| 411 | |||
| 412 | /* Check for overflow, if yes, force to max value */ | ||
| 413 | if (val > mask) | ||
| 414 | val = mask; | ||
| 415 | |||
| 416 | return val; | ||
| 417 | } | ||
| 418 | |||
| 419 | /** | ||
| 368 | * omap4_set_timings - set voltage ramp timings for a channel | 420 | * omap4_set_timings - set voltage ramp timings for a channel |
| 369 | * @voltdm: channel to configure | 421 | * @voltdm: channel to configure |
| 370 | * @off_mode: whether off-mode values are used | 422 | * @off_mode: whether off-mode values are used |
| @@ -376,6 +428,7 @@ static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode) | |||
| 376 | u32 val; | 428 | u32 val; |
| 377 | u32 ramp; | 429 | u32 ramp; |
| 378 | int offset; | 430 | int offset; |
| 431 | u32 tstart, tshut; | ||
| 379 | 432 | ||
| 380 | if (off_mode) { | 433 | if (off_mode) { |
| 381 | ramp = omap4_calc_volt_ramp(voltdm, | 434 | ramp = omap4_calc_volt_ramp(voltdm, |
| @@ -397,6 +450,15 @@ static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode) | |||
| 397 | val |= ramp << OMAP4430_RAMP_UP_COUNT_SHIFT; | 450 | val |= ramp << OMAP4430_RAMP_UP_COUNT_SHIFT; |
| 398 | 451 | ||
| 399 | voltdm->write(val, offset); | 452 | voltdm->write(val, offset); |
| 453 | |||
| 454 | omap_pm_get_oscillator(&tstart, &tshut); | ||
| 455 | |||
| 456 | val = omap4_usec_to_val_scrm(tstart, OMAP4_SETUPTIME_SHIFT, | ||
| 457 | OMAP4_SETUPTIME_MASK); | ||
| 458 | val |= omap4_usec_to_val_scrm(tshut, OMAP4_DOWNTIME_SHIFT, | ||
| 459 | OMAP4_DOWNTIME_MASK); | ||
| 460 | |||
| 461 | __raw_writel(val, OMAP4_SCRM_CLKSETUPTIME); | ||
| 400 | } | 462 | } |
| 401 | 463 | ||
| 402 | /* OMAP4 specific voltage init functions */ | 464 | /* OMAP4 specific voltage init functions */ |
