summaryrefslogtreecommitdiff
path: root/drivers/gpu/msm/kgsl_pwrctrl.c
diff options
context:
space:
mode:
authorOleg Perelet <operelet@codeaurora.org>2016-07-07 09:41:20 -0700
committerOleg Perelet <operelet@codeaurora.org>2016-07-13 10:04:55 -0700
commitfb1c6ee3acd0bb0dc802b1a0f4ec104e1d97de49 (patch)
tree1a62f06761195c80cedb30ab32588f7526ef2081 /drivers/gpu/msm/kgsl_pwrctrl.c
parent400520a6e2f06cc7c45e386e769a85d4aded565b (diff)
msm: kgsl: Disable GPU isense clock below nominal power level
By disabling isense clock below nominal level we'll remove vote for CX rail and save power. CRs-Fixed: 973565 Change-Id: If4a13b3eca117fc2ff9c32ca3a24eb8b8e70b4fe Signed-off-by: Oleg Perelet <operelet@codeaurora.org>
Diffstat (limited to 'drivers/gpu/msm/kgsl_pwrctrl.c')
-rw-r--r--drivers/gpu/msm/kgsl_pwrctrl.c39
1 files changed, 34 insertions, 5 deletions
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 830579d94bcf..51717373b821 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -81,6 +81,8 @@ static void kgsl_pwrctrl_set_state(struct kgsl_device *device,
static void kgsl_pwrctrl_request_state(struct kgsl_device *device,
unsigned int state);
static void kgsl_pwrctrl_retention_clk(struct kgsl_device *device, int state);
+static int _isense_clk_set_rate(struct kgsl_pwrctrl *pwr, int level);
+
/**
* _record_pwrevent() - Record the history of the new event
@@ -387,6 +389,8 @@ void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device,
/* Change register settings if any BEFORE pwrlevel change*/
kgsl_pwrctrl_pwrlevel_change_settings(device, 0);
clk_set_rate(pwr->grp_clks[0], pwrlevel->gpu_freq);
+ _isense_clk_set_rate(pwr, pwr->active_pwrlevel);
+
trace_kgsl_pwrlevel(device,
pwr->active_pwrlevel, pwrlevel->gpu_freq,
pwr->previous_pwrlevel,
@@ -1374,15 +1378,20 @@ static void kgsl_pwrctrl_clk(struct kgsl_device *device, int state,
clk_set_rate(pwr->grp_clks[0],
pwr->pwrlevels[pwr->num_pwrlevels - 1].
gpu_freq);
+ _isense_clk_set_rate(pwr,
+ pwr->num_pwrlevels - 1);
}
} else if (requested_state == KGSL_STATE_SLEEP) {
/* High latency clock maintenance. */
for (i = KGSL_MAX_CLKS - 1; i > 0; i--)
clk_unprepare(pwr->grp_clks[i]);
- if ((pwr->pwrlevels[0].gpu_freq > 0))
+ if ((pwr->pwrlevels[0].gpu_freq > 0)) {
clk_set_rate(pwr->grp_clks[0],
pwr->pwrlevels[pwr->num_pwrlevels - 1].
gpu_freq);
+ _isense_clk_set_rate(pwr,
+ pwr->num_pwrlevels - 1);
+ }
}
} else if (state == KGSL_PWRFLAGS_ON) {
if (!test_and_set_bit(KGSL_PWRFLAGS_CLK_ON,
@@ -1392,11 +1401,15 @@ static void kgsl_pwrctrl_clk(struct kgsl_device *device, int state,
/* High latency clock maintenance. */
if ((device->state != KGSL_STATE_NAP) &&
(device->state != KGSL_STATE_DEEP_NAP)) {
- if (pwr->pwrlevels[0].gpu_freq > 0)
+ if (pwr->pwrlevels[0].gpu_freq > 0) {
clk_set_rate(pwr->grp_clks[0],
pwr->pwrlevels
[pwr->active_pwrlevel].
gpu_freq);
+ _isense_clk_set_rate(pwr,
+ pwr->active_pwrlevel);
+ }
+
for (i = KGSL_MAX_CLKS - 1; i > 0; i--)
clk_prepare(pwr->grp_clks[i]);
}
@@ -1720,9 +1733,27 @@ static int _get_clocks(struct kgsl_device *device)
}
}
+ if (pwr->isense_clk_indx && of_property_read_u32(dev->of_node,
+ "qcom,isense-clk-on-level", &pwr->isense_clk_on_level)) {
+ KGSL_CORE_ERR("Couldn't get isense clock on level\n");
+ return -ENXIO;
+ }
return 0;
}
+static int _isense_clk_set_rate(struct kgsl_pwrctrl *pwr, int level)
+{
+ int rate;
+
+ if (!pwr->isense_clk_indx)
+ return -EINVAL;
+
+ rate = clk_round_rate(pwr->grp_clks[pwr->isense_clk_indx],
+ level > pwr->isense_clk_on_level ?
+ KGSL_XO_CLK_FREQ : KGSL_ISENSE_CLK_FREQ);
+ return clk_set_rate(pwr->grp_clks[pwr->isense_clk_indx], rate);
+}
+
int kgsl_pwrctrl_init(struct kgsl_device *device)
{
int i, k, m, n = 0, result;
@@ -1799,9 +1830,7 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
clk_set_rate(pwr->grp_clks[6],
clk_round_rate(pwr->grp_clks[6], KGSL_RBBMTIMER_CLK_FREQ));
- if (pwr->isense_clk_indx)
- clk_set_rate(pwr->grp_clks[pwr->isense_clk_indx],
- KGSL_ISENSE_CLK_FREQ);
+ _isense_clk_set_rate(pwr, pwr->num_pwrlevels - 1);
result = get_regulators(device);
if (result)