diff options
author | Alex Frid <afrid@nvidia.com> | 2012-09-10 21:52:26 -0700 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-09-12 10:19:57 -0700 |
commit | eba9bf3979e0e601ea8ca7b9c2dd888643929408 (patch) | |
tree | 4bb1c8fce19145d4de3a77baac9e15af514491a2 /arch/arm/mach-tegra/dvfs.c | |
parent | 4d52a4e6a520dba45834a9886a37998822d3b1af (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.c | 33 |
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 " |