summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/tegra_cl_dvfs.c
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2014-02-19 22:42:37 -0800
committerYu-Huan Hsu <yhsu@nvidia.com>2014-02-20 19:28:35 -0800
commitb343b23f413678579d49daf1dcef0d8b8677a5f1 (patch)
tree1d9caf1fe85844146a41a94d9351fa9d5bf7b68a /arch/arm/mach-tegra/tegra_cl_dvfs.c
parentc691da11d8d60f275ddf5538e7c29d5af448371d (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.c30
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);