aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/vc.c
diff options
context:
space:
mode:
authorTero Kristo <t-kristo@ti.com>2012-09-25 12:33:41 -0400
committerKevin Hilman <khilman@ti.com>2012-11-05 18:20:59 -0500
commitd68ff977b82954fed8e3f4bde8431517455c2003 (patch)
tree8df4bd1b589f79f177f69f08f5740bc6f181c351 /arch/arm/mach-omap2/vc.c
parent085b30250041cd485555f547f625ec03341592dd (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.c62
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 */
214static 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 */
220static 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 */
406static 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 */