summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/tegra_core_volt_cap.c
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2013-11-06 20:21:27 -0800
committerYu-Huan Hsu <yhsu@nvidia.com>2013-11-26 15:44:06 -0800
commit54461f1cfde8dba9a73ee78ef9830ed887590971 (patch)
treebcc67951c806635d95f00708b98611a7e493be81 /arch/arm/mach-tegra/tegra_core_volt_cap.c
parent4368bddd02cc986e5c00ddb1a5fa7b18f7fe377d (diff)
ARM: tegra: dvfs: Add core rail Vmax cooling device
Added cooling device to cap frequencies of core shared buses based on core rail Vmax thermal profile. Thermal limits implementation is an extension of the existing core voltage capping mechanism, combined with core voltage override limits, and limits set from user space. Bug 1413311 Change-Id: I65e8b885f49318020e20d25425e257b7f0b0f66e Signed-off-by: Alex Frid <afrid@nvidia.com> Reviewed-on: http://git-master/r/335357 Reviewed-by: Sai Gurrappadi <sgurrappadi@nvidia.com> Reviewed-by: Prashant Malani <pmalani@nvidia.com> Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/tegra_core_volt_cap.c')
-rw-r--r--arch/arm/mach-tegra/tegra_core_volt_cap.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/tegra_core_volt_cap.c b/arch/arm/mach-tegra/tegra_core_volt_cap.c
index 9e19b9c32efd..dd009fd801f5 100644
--- a/arch/arm/mach-tegra/tegra_core_volt_cap.c
+++ b/arch/arm/mach-tegra/tegra_core_volt_cap.c
@@ -47,6 +47,7 @@ struct core_cap {
static struct core_cap core_buses_cap;
static struct core_cap override_core_cap;
+static struct core_cap vmax_core_cap;
static struct core_cap user_core_cap;
static struct core_dvfs_cap_table *core_cap_table;
@@ -105,6 +106,8 @@ static int core_cap_update(void)
new_level = core_nominal_mv;
if (override_core_cap.refcnt)
new_level = min(new_level, override_core_cap.level);
+ if (vmax_core_cap.refcnt)
+ new_level = min(new_level, vmax_core_cap.level);
if (user_core_cap.refcnt)
new_level = min(new_level, user_core_cap.level);
@@ -217,6 +220,36 @@ int tegra_dvfs_override_core_cap_apply(int level)
return ret;
}
+int tegra_dvfs_therm_vmax_core_cap_apply(int *cap_idx, int new_idx, int level)
+{
+ int ret = 0;
+
+ mutex_lock(&core_cap_lock);
+ if (*cap_idx == new_idx)
+ goto _out;
+
+ *cap_idx = new_idx;
+
+ if (level) {
+ if (!vmax_core_cap.refcnt) {
+ vmax_core_cap.level = level;
+ vmax_core_cap.refcnt = 1;
+ /* just report error (cannot revert temperature) */
+ ret = core_cap_enable(true);
+ } else if (vmax_core_cap.level != level) {
+ vmax_core_cap.level = level;
+ /* just report error (cannot revert temperature) */
+ ret = core_cap_update();
+ }
+ } else if (vmax_core_cap.refcnt) {
+ vmax_core_cap.refcnt = 0;
+ core_cap_enable(false);
+ }
+_out:
+ mutex_unlock(&core_cap_lock);
+ return ret;
+}
+
static int __init init_core_cap_one(struct clk *c, unsigned long *freqs)
{
int i, v, next_v = 0;