summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2017-02-27 23:37:24 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-02-27 23:37:23 -0800
commit598d0c01b1708c2cb840930f709f258364429c15 (patch)
tree42c393294e9c09cbacb1e6a5a0f726488a80a9c8
parenta19f132f6eec8cba607cd3ce17df87b39ba1c79a (diff)
parent7d740729a1c7e352a174db9dff6a7d6d8401c213 (diff)
Merge "msm: mdss: add support for Cx iPeak limit management"
-rw-r--r--drivers/video/fbdev/msm/mdss.h2
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.c46
2 files changed, 43 insertions, 5 deletions
diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h
index bf4dc39f57ee..d9a4bd91f3eb 100644
--- a/drivers/video/fbdev/msm/mdss.h
+++ b/drivers/video/fbdev/msm/mdss.h
@@ -27,6 +27,7 @@
#include <linux/msm-bus.h>
#include <linux/file.h>
#include <linux/dma-direction.h>
+#include <soc/qcom/cx_ipeak.h>
#include "mdss_panel.h"
@@ -535,6 +536,7 @@ struct mdss_data_type {
u32 sec_cam_en;
u32 sec_session_cnt;
wait_queue_head_t secure_waitq;
+ struct cx_ipeak_client *mdss_cx_ipeak;
};
extern struct mdss_data_type *mdss_res;
diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c
index 21728c5dee45..3cadfa4ecef7 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp.c
@@ -1173,6 +1173,31 @@ irqreturn_t mdss_mdp_isr(int irq, void *ptr)
return IRQ_HANDLED;
}
+static void mdss_mdp_cxipeak_vote(bool set_vote, unsigned long new_rate,
+ unsigned long prev_rate)
+{
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+ int ret = 0;
+
+ if (!mdata->mdss_cx_ipeak)
+ return;
+
+ /* fmax threshold for mdp in sdm660 is max MDP clk */
+ if (set_vote) {
+ if ((new_rate >= mdata->max_mdp_clk_rate) &&
+ (prev_rate < mdata->max_mdp_clk_rate))
+ ret = cx_ipeak_update(mdata->mdss_cx_ipeak, true);
+ } else {
+ if ((new_rate < mdata->max_mdp_clk_rate) &&
+ (prev_rate >= mdata->max_mdp_clk_rate))
+ ret = cx_ipeak_update(mdata->mdss_cx_ipeak, false);
+ }
+ if (ret) {
+ pr_err("cxipeak api fail ret:%d set_vote :%d new_rate:%lu prev_rate:%lu\n",
+ ret, (int)set_vote, new_rate, prev_rate);
+ }
+}
+
static int mdss_mdp_clk_update(u32 clk_idx, u32 enable)
{
int ret = -ENODEV;
@@ -1234,7 +1259,7 @@ void mdss_mdp_set_clk_rate(unsigned long rate, bool locked)
struct mdss_data_type *mdata = mdss_res;
unsigned long clk_rate;
struct clk *clk = mdss_mdp_get_clk(MDSS_CLK_MDP_CORE);
- unsigned long min_clk_rate;
+ unsigned long min_clk_rate, curr_clk_rate;
min_clk_rate = max(rate, mdata->perf_tune.min_mdp_clk);
@@ -1246,15 +1271,20 @@ void mdss_mdp_set_clk_rate(unsigned long rate, bool locked)
clk_rate = clk_round_rate(clk, min_clk_rate);
else
clk_rate = mdata->max_mdp_clk_rate;
+
+ curr_clk_rate = clk_get_rate(clk);
if (IS_ERR_VALUE(clk_rate)) {
pr_err("unable to round rate err=%ld\n", clk_rate);
- } else if (clk_rate != clk_get_rate(clk)) {
-
+ } else if (clk_rate != curr_clk_rate) {
+ mdss_mdp_cxipeak_vote(true, clk_rate, curr_clk_rate);
mdata->mdp_clk_rate = clk_rate;
- if (IS_ERR_VALUE(clk_set_rate(clk, clk_rate)))
+ if (IS_ERR_VALUE(clk_set_rate(clk, clk_rate))) {
pr_err("clk_set_rate failed\n");
- else
+ } else {
+ mdss_mdp_cxipeak_vote(false, clk_rate,
+ curr_clk_rate);
pr_debug("mdp clk rate=%lu\n", clk_rate);
+ }
}
if (!locked)
mutex_unlock(&mdp_clk_lock);
@@ -4538,6 +4568,10 @@ static int mdss_mdp_parse_dt_misc(struct platform_device *pdev)
pr_debug("max pipe width not specified. Using default value\n");
mdata->max_pipe_width = DEFAULT_MDP_PIPE_WIDTH;
}
+
+ if (of_find_property(pdev->dev.of_node, "qcom,mdss-cx-ipeak", NULL))
+ mdata->mdss_cx_ipeak = cx_ipeak_register(pdev->dev.of_node,
+ "qcom,mdss-cx-ipeak");
return 0;
}
@@ -5523,6 +5557,8 @@ static int mdss_mdp_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
mdss_mdp_pp_term(&pdev->dev);
mdss_mdp_bus_scale_unregister(mdata);
+ if (mdata->mdss_cx_ipeak)
+ cx_ipeak_unregister(mdata->mdss_cx_ipeak);
mdss_debugfs_remove(mdata);
if (mdata->regulator_notif_register)
regulator_unregister_notifier(mdata->fs, &(mdata->gdsc_cb));