summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVineet Bajaj <vbajaj@codeaurora.org>2014-04-06 17:36:26 +0530
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:29:06 -0700
commit7dd979a28fc73ec1b0baf2233ed4cbb7450c8111 (patch)
tree3b8dd15bfd2899e40e502eca3215544b3be35615
parent68e08b6ebcff37130be02108f2730f0dc491a17e (diff)
msm:mdss: Add performance tuning parameters in debugfs
Adding params in debugfs to tune the performance of the driver at runtime from debugfs. These params are min_bus_vote, clk_factor, ab and ib factor, bw thresholds etc. User can tweak these parameters from debugfs to help in debugging the issues. Change-Id: Ie134eba35bf81ecc1524fba29bae902870673bd0 Signed-off-by: Vineet Bajaj <vbajaj@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss.h7
-rw-r--r--drivers/video/fbdev/msm/mdss_debug.c131
-rw-r--r--drivers/video/fbdev/msm/mdss_debug.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.c2
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_ctl.c6
5 files changed, 132 insertions, 15 deletions
diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h
index 579fb93ede9f..fa7c768306b7 100644
--- a/drivers/video/fbdev/msm/mdss.h
+++ b/drivers/video/fbdev/msm/mdss.h
@@ -71,6 +71,11 @@ struct mdss_fudge_factor {
u32 denom;
};
+struct mdss_perf_tune {
+ unsigned long min_mdp_clk;
+ u64 min_bus_vote;
+};
+
#define MDSS_IRQ_SUSPEND -1
#define MDSS_IRQ_RESUME 1
#define MDSS_IRQ_REQ 0
@@ -131,7 +136,6 @@ struct mdss_data_type {
u8 clk_ena;
u8 fs_ena;
u8 vsync_ena;
- unsigned long min_mdp_clk;
u32 res_init;
@@ -199,6 +203,7 @@ struct mdss_data_type {
int handoff_pending;
bool ulps;
+ struct mdss_perf_tune perf_tune;
};
extern struct mdss_data_type *mdss_res;
diff --git a/drivers/video/fbdev/msm/mdss_debug.c b/drivers/video/fbdev/msm/mdss_debug.c
index f9bd2c001c99..b0738f834c46 100644
--- a/drivers/video/fbdev/msm/mdss_debug.c
+++ b/drivers/video/fbdev/msm/mdss_debug.c
@@ -334,6 +334,78 @@ static const struct file_operations mdss_stat_fops = {
.read = mdss_debug_stat_read,
};
+static ssize_t mdss_debug_factor_write(struct file *file,
+ const char __user *user_buf, size_t count, loff_t *ppos)
+{
+ struct mdss_fudge_factor *factor = file->private_data;
+ u32 numer = factor->numer;
+ u32 denom = factor->denom;
+ char buf[32];
+
+ if (!factor)
+ return -ENODEV;
+
+ if (count >= sizeof(buf))
+ return -EFAULT;
+
+ if (copy_from_user(buf, user_buf, count))
+ return -EFAULT;
+
+ buf[count] = 0; /* end of string */
+
+ if (strnchr(buf, count, '/')) {
+ /* Parsing buf as fraction */
+ if (sscanf(buf, "%d/%d", &numer, &denom) != 2)
+ return -EFAULT;
+ } else {
+ /* Parsing buf as percentage */
+ if (sscanf(buf, "%d", &numer) != 1)
+ return -EFAULT;
+ denom = 100;
+ }
+
+ if (numer && denom) {
+ factor->numer = numer;
+ factor->denom = denom;
+ }
+
+ pr_debug("numer=%d denom=%d\n", numer, denom);
+
+ return count;
+}
+
+static ssize_t mdss_debug_factor_read(struct file *file,
+ char __user *buff, size_t count, loff_t *ppos)
+{
+ struct mdss_fudge_factor *factor = file->private_data;
+ int len = 0;
+ char buf[32];
+
+ if (!factor)
+ return -ENODEV;
+
+ if (*ppos)
+ return 0; /* the end */
+
+ len = snprintf(buf, sizeof(buf), "%d/%d\n",
+ factor->numer, factor->denom);
+ if (len < 0)
+ return 0;
+
+ if (copy_to_user(buff, buf, len))
+ return -EFAULT;
+
+ *ppos += len; /* increase offset */
+
+ return len;
+}
+
+static const struct file_operations mdss_factor_fops = {
+ .open = simple_open,
+ .read = mdss_debug_factor_read,
+ .write = mdss_debug_factor_write,
+};
+
static int mdss_debugfs_cleanup(struct mdss_debug_data *mdd)
{
struct mdss_debug_base *base, *tmp;
@@ -354,6 +426,39 @@ static int mdss_debugfs_cleanup(struct mdss_debug_data *mdd)
return 0;
}
+static int mdss_debugfs_perf_init(struct mdss_debug_data *mdd,
+ struct mdss_data_type *mdata) {
+
+ debugfs_create_u32("min_mdp_clk", 0644, mdd->perf,
+ (u32 *)&mdata->perf_tune.min_mdp_clk);
+
+ debugfs_create_u64("min_bus_vote", 0644, mdd->perf,
+ (u64 *)&mdata->perf_tune.min_bus_vote);
+
+ debugfs_create_file("ab_factor", 0644, mdd->perf,
+ &mdata->ab_factor, &mdss_factor_fops);
+
+ debugfs_create_file("ib_factor", 0644, mdd->perf,
+ &mdata->ib_factor, &mdss_factor_fops);
+
+ debugfs_create_file("ib_factor_overlap", 0644, mdd->perf,
+ &mdata->ib_factor_overlap, &mdss_factor_fops);
+
+ debugfs_create_file("clk_factor", 0644, mdd->perf,
+ &mdata->clk_factor, &mdss_factor_fops);
+
+ debugfs_create_u32("threshold_low", 0644, mdd->perf,
+ (u32 *)&mdata->max_bw_low);
+
+ debugfs_create_u32("threshold_high", 0644, mdd->perf,
+ (u32 *)&mdata->max_bw_high);
+
+ debugfs_create_u32("threshold_pipe", 0644, mdd->perf,
+ (u32 *)&mdata->max_bw_per_pipe);
+
+ return 0;
+}
+
int mdss_debugfs_init(struct mdss_data_type *mdata)
{
struct mdss_debug_data *mdd;
@@ -372,25 +477,31 @@ int mdss_debugfs_init(struct mdss_data_type *mdata)
mdd->root = debugfs_create_dir("mdp", NULL);
if (IS_ERR_OR_NULL(mdd->root)) {
- pr_err("debugfs_create_dir fail, error %ld\n",
+ pr_err("debugfs_create_dir for mdp failed, error %ld\n",
PTR_ERR(mdd->root));
- mdd->root = NULL;
- mdss_debugfs_cleanup(mdd);
- return -ENODEV;
+ goto err;
}
debugfs_create_file("stat", 0644, mdd->root, mdata, &mdss_stat_fops);
- debugfs_create_u32("min_mdp_clk", 0644, mdd->root,
- (u32 *)&mdata->min_mdp_clk);
-
- if (mdss_create_xlog_debug(mdd)) {
- mdss_debugfs_cleanup(mdd);
- return -ENODEV;
+ mdd->perf = debugfs_create_dir("perf", mdd->root);
+ if (IS_ERR_OR_NULL(mdd->perf)) {
+ pr_err("debugfs_create_dir perf fail, error %ld\n",
+ PTR_ERR(mdd->perf));
+ goto err;
}
+ mdss_debugfs_perf_init(mdd, mdata);
+
+ if (mdss_create_xlog_debug(mdd))
+ goto err;
+
mdata->debug_inf.debug_data = mdd;
return 0;
+
+err:
+ mdss_debugfs_cleanup(mdd);
+ return -ENODEV;
}
int mdss_debugfs_remove(struct mdss_data_type *mdata)
diff --git a/drivers/video/fbdev/msm/mdss_debug.h b/drivers/video/fbdev/msm/mdss_debug.h
index 08bf7f4f6831..93d5d60ee1c9 100644
--- a/drivers/video/fbdev/msm/mdss_debug.h
+++ b/drivers/video/fbdev/msm/mdss_debug.h
@@ -52,6 +52,7 @@ struct debug_log {
struct mdss_debug_data {
struct dentry *root;
+ struct dentry *perf;
struct list_head base_list;
struct debug_log logd;
};
diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c
index 6129f9226ec1..6876eefe47eb 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp.c
@@ -638,7 +638,7 @@ void mdss_mdp_set_clk_rate(unsigned long rate)
struct clk *clk = mdss_mdp_get_clk(MDSS_CLK_MDP_SRC);
unsigned long min_clk_rate;
- min_clk_rate = max(rate, mdata->min_mdp_clk);
+ min_clk_rate = max(rate, mdata->perf_tune.min_mdp_clk);
if (clk) {
mutex_lock(&mdp_clk_lock);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
index 12643eb68c3f..c899e6f15acb 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
@@ -35,7 +35,7 @@ static inline u64 fudge_factor(u64 val, u32 numer, u32 denom)
static inline u64 apply_fudge_factor(u64 val,
struct mdss_fudge_factor *factor)
{
- return fudge_factor(val, factor->numer, factor->denom);
+ return fudge_factor(val, factor->numer, factor->denom);
}
static DEFINE_MUTEX(mdss_mdp_ctl_lock);
@@ -935,8 +935,8 @@ static inline void mdss_mdp_ctl_perf_update_bus(struct mdss_mdp_ctl *ctl)
ctl->cur_perf.bw_ctl);
}
}
- bus_ib_quota = bw_sum_of_intfs;
- bus_ab_quota = apply_fudge_factor(bw_sum_of_intfs,
+ bus_ib_quota = max(bw_sum_of_intfs, mdata->perf_tune.min_bus_vote);
+ bus_ab_quota = apply_fudge_factor(bus_ib_quota,
&mdss_res->ab_factor);
mdss_mdp_bus_scale_set_quota(bus_ab_quota, bus_ib_quota);
pr_debug("ab=%llu ib=%llu\n", bus_ab_quota, bus_ib_quota);