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