summaryrefslogtreecommitdiff
path: root/drivers/edp
diff options
context:
space:
mode:
authorSteve Rogers <srogers@nvidia.com>2014-02-04 17:15:33 -0600
committerJuha Tukkinen <jtukkinen@nvidia.com>2014-02-10 04:39:36 -0800
commita7fd41b82287ba85e704f5e7bf06988e22e39151 (patch)
tree49aa5fe63a74e482030f9995aa956c298bd27ec6 /drivers/edp
parent4253883370fd386e453c07c4764dd3eaaa795be3 (diff)
EDP: sysedp: Add capping method selection
Bug 1453350 Change-Id: Ia4064cf59a93f90770a61144fcdb65918cdaa1b7 Signed-off-by: Steve Rogers <srogers@nvidia.com> Reviewed-on: http://git-master/r/363494 (cherry picked from commmit 88b6025796e4b57e750b7c615b9416c433ef7761) Reviewed-on: http://git-master/r/364963 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Sivaram Nair <sivaramn@nvidia.com> Reviewed-by: Juha Tukkinen <jtukkinen@nvidia.com>
Diffstat (limited to 'drivers/edp')
-rw-r--r--drivers/edp/sysedp_dynamic_capping.c49
1 files changed, 44 insertions, 5 deletions
diff --git a/drivers/edp/sysedp_dynamic_capping.c b/drivers/edp/sysedp_dynamic_capping.c
index 0c1cdffec438..441f5f800f36 100644
--- a/drivers/edp/sysedp_dynamic_capping.c
+++ b/drivers/edp/sysedp_dynamic_capping.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -43,6 +43,7 @@ static unsigned int online_cpu_count;
static bool gpu_busy;
static unsigned int avail_power;
static unsigned int avail_oc_relax;
+static unsigned int cap_method;
static struct tegra_sysedp_corecap *cur_corecap;
static struct clk *emc_cap_clk;
@@ -190,6 +191,7 @@ static void update_cur_corecap(void)
{
struct tegra_sysedp_corecap *cap;
unsigned int power;
+ unsigned int relaxed_power;
int i;
if (!capping_device_platdata)
@@ -200,10 +202,29 @@ static void update_cur_corecap(void)
i = capping_device_platdata->corecap_size - 1;
cap = capping_device_platdata->corecap + i;
+ switch (cap_method) {
+ default:
+ pr_warn("%s: Unknown cap_method, %x! Assuming direct.\n",
+ __func__, cap_method);
+ cap_method = TEGRA_SYSEDP_CAP_METHOD_DIRECT;
+ /* intentional fall-through */
+ case TEGRA_SYSEDP_CAP_METHOD_DIRECT:
+ relaxed_power = 0;
+ break;
+
+ case TEGRA_SYSEDP_CAP_METHOD_SIGNAL:
+ relaxed_power = min(avail_oc_relax, cap->pthrot);
+ break;
+
+ case TEGRA_SYSEDP_CAP_METHOD_RELAX:
+ relaxed_power = cap->pthrot;
+ break;
+ }
+
for (; i >= 0; i--, cap--) {
- if (cap->power <= power + min(avail_oc_relax, cap->pthrot)) {
+ if (cap->power <= power + relaxed_power) {
cur_corecap = cap;
- cpu_power_balance = power + min(avail_oc_relax, cap->pthrot)
+ cpu_power_balance = power + relaxed_power
- cap->power;
return;
}
@@ -303,8 +324,9 @@ static int core_set(void *data, u64 val)
*pdata = val;
if (old != *pdata) {
- /* Changes to core_gain require corecap update */
- if (pdata == &capping_device_platdata->core_gain)
+ /* Changes to core_gain and cap_method require corecap update */
+ if ((pdata == &capping_device_platdata->core_gain) ||
+ (pdata == &cap_method))
update_cur_corecap();
do_cap_control();
}
@@ -425,6 +447,7 @@ static int status_show(struct seq_file *file, void *data)
seq_printf(file, "cpu cap : %u kHz\n", cur_caps.cpu);
seq_printf(file, "gpu cap : %u kHz\n", cur_caps.gpu);
seq_printf(file, "emc cap : %u kHz\n", cur_caps.emc);
+ seq_printf(file, "cc method : %u kHz\n", cap_method);
mutex_unlock(&core_lock);
return 0;
@@ -474,6 +497,7 @@ static void init_debug(void)
create_attr("gpu_window", &gpu_window);
create_attr("gain", &capping_device_platdata->core_gain);
create_attr("gpu_high_count", &gpu_high_count);
+ create_attr("cap_method", &cap_method);
create_longattr("corecaps", corecaps_show);
create_longattr("cpucaps", cpucaps_show);
@@ -524,6 +548,21 @@ static int sysedp_dynamic_capping_probe(struct platform_device *pdev)
mutex_lock(&core_lock);
capping_device_platdata = pdev->dev.platform_data;
avail_power = capping_device_platdata->init_req_watts;
+ cap_method = capping_device_platdata->cap_method;
+ switch (cap_method) {
+ case TEGRA_SYSEDP_CAP_METHOD_DEFAULT:
+ cap_method = TEGRA_SYSEDP_CAP_METHOD_SIGNAL;
+ break;
+ case TEGRA_SYSEDP_CAP_METHOD_DIRECT:
+ case TEGRA_SYSEDP_CAP_METHOD_SIGNAL:
+ case TEGRA_SYSEDP_CAP_METHOD_RELAX:
+ break;
+ default:
+ pr_warn("%s: Unknown cap_method, %x! Assuming direct.\n",
+ __func__, cap_method);
+ cap_method = TEGRA_SYSEDP_CAP_METHOD_DIRECT;
+ break;
+ }
/* scale pthrot value in capping table */
i = capping_device_platdata->corecap_size - 1;