diff options
author | Alex Frid <afrid@nvidia.com> | 2014-02-19 22:42:37 -0800 |
---|---|---|
committer | Yu-Huan Hsu <yhsu@nvidia.com> | 2014-02-20 19:28:35 -0800 |
commit | b343b23f413678579d49daf1dcef0d8b8677a5f1 (patch) | |
tree | 1d9caf1fe85844146a41a94d9351fa9d5bf7b68a /arch/arm/mach-tegra/tegra_cl_dvfs.c | |
parent | c691da11d8d60f275ddf5538e7c29d5af448371d (diff) |
ARM: tegra: dvfs: Use safe DFLL caps below minimax
If some other rail depends on DFLL rail, set maximum output cap to
match voltage from safe dvfs table used by s/w DVFS on other rails to
resolve dependencies Otherwise, with no dependencies leave a room for
regulation up to minimax level.
In any case keep maximum cap at/above forced limit if PMIC undershoot
guard-band is specified. The guard-band must be within rail dependency
slack.
Bug 1461646
Change-Id: I6f511b1502c96d5796cfb72fda0b343bcf1b4ff5
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/369765
GVS: Gerrit_Virtual_Submit
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/tegra_cl_dvfs.c')
-rw-r--r-- | arch/arm/mach-tegra/tegra_cl_dvfs.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/tegra_cl_dvfs.c b/arch/arm/mach-tegra/tegra_cl_dvfs.c index f884509a06db..a6f438d38a00 100644 --- a/arch/arm/mach-tegra/tegra_cl_dvfs.c +++ b/arch/arm/mach-tegra/tegra_cl_dvfs.c @@ -704,6 +704,9 @@ static void set_output_limits(struct tegra_cl_dvfs *cld, u8 out_min, u8 out_max) write_seqcount_end(vmin_seqcnt); if (vmax_seqcnt) write_seqcount_end(vmax_seqcnt); + + pr_debug("cl_dvfs limits_mV [%d : %d]\n", + cld->v_limits.vmin, cld->v_limits.vmax); } } @@ -734,6 +737,7 @@ static void set_cl_config(struct tegra_cl_dvfs *cld, struct dfll_rate_req *req) { u32 out_max, out_min; u32 out_cap = get_output_cap(cld, req); + struct dvfs_rail *rail = cld->safe_dvfs->dvfs_rail; switch (cld->tune_state) { case TEGRA_CL_DVFS_TUNE_LOW: @@ -756,6 +760,22 @@ static void set_cl_config(struct tegra_cl_dvfs *cld, struct dfll_rate_req *req) BUG(); } + /* + * Criteria to select new request and output boundaries. Listed in + * the order of priorities to resolve conflicts (if any). + * + * 1) out_min is at/above minimum voltage level for current temperature + * and tuning ranges + * 2) out_max is at/above PMIC guard-band forced minimum + * 3) new request has at least on step room for regulation: request +/-1 + * within [out_min, out_max] interval + * 4) - if no other rail depends on DFLL rail, out_max is at/above + * minimax level to provide better convergence accuracy for rates + * close to tuning range boundaries + * - if some other rail depends on DFLL rail, out_max should match + * voltage from safe dvfs table used by s/w DVFS on other rails to + * resolve dependencies + */ out_min = get_output_min(cld); if (out_cap > (out_min + 1)) req->output = out_cap - 1; @@ -763,7 +783,11 @@ static void set_cl_config(struct tegra_cl_dvfs *cld, struct dfll_rate_req *req) req->output = out_min + 1; if (req->output == cld->safe_output) req->output++; - out_max = max((u8)(req->output + 1), cld->minimax_output); + + if (list_empty(&rail->relationships_to)) + out_max = max((u8)(req->output + 1), cld->minimax_output); + else + out_max = req->output + 1; out_max = max((u8)(out_max), cld->force_out_min); set_output_limits(cld, out_min, out_max); @@ -1033,6 +1057,10 @@ static void cl_dvfs_set_force_out_min(struct tegra_cl_dvfs *cld) return; } + WARN_ONCE(!list_empty(&cld->safe_dvfs->dvfs_rail->relationships_to), + "%s: PMIC undershoot must fit DFLL rail dependency-to slack", + __func__); + force_out_min = get_output_min(cld); force_mv_min += get_mv(cld, force_out_min); force_out_min = find_mv_out_cap(cld, force_mv_min); |