diff options
| author | Vineet Bajaj <vbajaj@codeaurora.org> | 2014-04-06 17:36:26 +0530 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:29:06 -0700 |
| commit | 7dd979a28fc73ec1b0baf2233ed4cbb7450c8111 (patch) | |
| tree | 3b8dd15bfd2899e40e502eca3215544b3be35615 | |
| parent | 68e08b6ebcff37130be02108f2730f0dc491a17e (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.h | 7 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_debug.c | 131 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_debug.h | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.c | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_ctl.c | 6 |
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); |
