summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/dvfs.c
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2012-09-10 21:52:26 -0700
committerSimone Willett <swillett@nvidia.com>2012-09-12 10:19:57 -0700
commiteba9bf3979e0e601ea8ca7b9c2dd888643929408 (patch)
tree4bb1c8fce19145d4de3a77baac9e15af514491a2 /arch/arm/mach-tegra/dvfs.c
parent4d52a4e6a520dba45834a9886a37998822d3b1af (diff)
ARM: tegra: dvfs: Update dfll mode rate/voltage control
Updated dvfs rate and voltage control in dfll mode: - use dfll voltages in set dvfs rate operation when dfll mode is enabled - use dfll voltages in predict voltage level operation when dfll mode is enabled - do not trigger any transaction to regulator when dfll mode is enabled Change-Id: Id66fbc21ac19f9495e743b785a99c7a1e250fce1 Signed-off-by: Alex Frid <afrid@nvidia.com> Reviewed-on: http://git-master/r/131306 Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/dvfs.c')
-rw-r--r--arch/arm/mach-tegra/dvfs.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/arch/arm/mach-tegra/dvfs.c b/arch/arm/mach-tegra/dvfs.c
index 7921ffbc403d..4565ca0cd7db 100644
--- a/arch/arm/mach-tegra/dvfs.c
+++ b/arch/arm/mach-tegra/dvfs.c
@@ -189,6 +189,13 @@ static int dvfs_rail_set_voltage(struct dvfs_rail *rail, int millivolts)
return -EINVAL;
}
+ /* DFLL adjusts rail voltage automatically - only update stats */
+ if (rail->dfll_mode) {
+ rail->millivolts = rail->new_millivolts;
+ dvfs_rail_stats_update(rail, rail->millivolts, ktime_get());
+ return 0;
+ }
+
if (rail->disabled)
return 0;
@@ -350,14 +357,22 @@ static inline unsigned long *dvfs_get_freqs(struct dvfs *d)
return d->alt_freqs ? : &d->freqs[0];
}
+static inline const int *dvfs_get_millivolts(struct dvfs *d)
+{
+ if (d->dvfs_rail && d->dvfs_rail->dfll_mode)
+ return d->dfll_millivolts;
+ return d->millivolts;
+}
+
static int
__tegra_dvfs_set_rate(struct dvfs *d, unsigned long rate)
{
int i = 0;
int ret;
unsigned long *freqs = dvfs_get_freqs(d);
+ const int *millivolts = dvfs_get_millivolts(d);
- if (freqs == NULL || d->millivolts == NULL)
+ if (freqs == NULL || millivolts == NULL)
return -ENODEV;
if (rate > freqs[d->num_freqs - 1]) {
@@ -373,12 +388,12 @@ __tegra_dvfs_set_rate(struct dvfs *d, unsigned long rate)
i++;
if ((d->max_millivolts) &&
- (d->millivolts[i] > d->max_millivolts)) {
+ (millivolts[i] > d->max_millivolts)) {
pr_warn("tegra_dvfs: voltage %d too high for dvfs on"
- " %s\n", d->millivolts[i], d->clk_name);
+ " %s\n", millivolts[i], d->clk_name);
return -EINVAL;
}
- d->cur_millivolts = d->millivolts[i];
+ d->cur_millivolts = millivolts[i];
}
d->cur_rate = rate;
@@ -409,11 +424,13 @@ int tegra_dvfs_alt_freqs_set(struct dvfs *d, unsigned long *alt_freqs)
int tegra_dvfs_predict_millivolts(struct clk *c, unsigned long rate)
{
int i;
+ const int *millivolts;
if (!rate || !c->dvfs)
return 0;
- if (!c->dvfs->millivolts)
+ millivolts = dvfs_get_millivolts(c->dvfs);
+ if (!millivolts)
return -ENODEV;
/*
@@ -432,7 +449,7 @@ int tegra_dvfs_predict_millivolts(struct clk *c, unsigned long rate)
if (i == c->dvfs->num_freqs)
return -EINVAL;
- return c->dvfs->millivolts[i];
+ return millivolts[i];
}
int tegra_dvfs_set_rate(struct clk *c, unsigned long rate)
@@ -611,6 +628,10 @@ static void __tegra_dvfs_rail_disable(struct dvfs_rail *rail)
{
int ret;
+ /* don't set voltage in DFLL mode - won't work, but break stats */
+ if (rail->dfll_mode)
+ return;
+
ret = dvfs_rail_set_voltage(rail, rail->nominal_millivolts);
if (ret)
pr_info("dvfs: failed to set regulator %s to disable "