From fdec367b00192f62415835eb2d3003725fb519f6 Mon Sep 17 00:00:00 2001 From: Ujwal Patel Date: Mon, 30 Mar 2015 14:05:19 -0700 Subject: msm: mdss: modify bus bw vote lock and count strategy Currently bus bandwidth can happen from 2 separate contexts where commit context does not hold lock and blindly votes bandwidth. Rather use a single bandwidth lock and count for all contexts. This also requires fixing a bug during ctl stop where ctl power status needs to be changed only after bus vote has finished. Conflicts: drivers/video/msm/mdss/mdss_mdp.c drivers/video/msm/mdss/mdss_mdp_ctl.c Change-Id: I4131b05195298d15a46101aa4ebb88ea2e80b3dc Signed-off-by: Ujwal Patel --- drivers/video/fbdev/msm/mdss.h | 2 ++ drivers/video/fbdev/msm/mdss_mdp.c | 46 +++++++++++++++++++++------------- drivers/video/fbdev/msm/mdss_mdp_ctl.c | 5 ++-- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h index 080d244db4b5..52459920ebf5 100644 --- a/drivers/video/fbdev/msm/mdss.h +++ b/drivers/video/fbdev/msm/mdss.h @@ -297,6 +297,8 @@ struct mdss_data_type { u32 *vbif_rt_qos; u32 *vbif_nrt_qos; u32 npriority_lvl; + u32 bus_bw_cnt; + struct mutex bus_bw_lock; u32 reg_bus_hdl; diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index 571a3d62960e..8fcb39513290 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -91,7 +91,6 @@ struct msm_mdp_interface mdp5 = { static DEFINE_SPINLOCK(mdp_lock); static DEFINE_MUTEX(mdp_clk_lock); -static DEFINE_MUTEX(bus_bw_lock); static DEFINE_MUTEX(mdp_iommu_lock); static DEFINE_MUTEX(mdp_fs_idle_pc_lock); @@ -280,6 +279,11 @@ static int mdss_mdp_bus_scale_register(struct mdss_data_type *mdata) mdata->reg_bus_hdl); } + /* + * Following call will not result in actual vote rather update the + * current index and ab/ib value. When continuous splash is enabled, + * actual vote will happen when splash handoff is done. + */ return mdss_bus_scale_set_quota(MDSS_MDP_RT, AB_QUOTA, IB_QUOTA); } @@ -298,6 +302,9 @@ static void mdss_mdp_bus_scale_unregister(struct mdss_data_type *mdata) } } +/* + * Caller needs to hold mdata->bus_bw_lock lock before calling this function. + */ static int mdss_mdp_bus_scale_set_quota(u64 ab_quota_rt, u64 ab_quota_nrt, u64 ib_quota_rt, u64 ib_quota_nrt) { @@ -391,11 +398,14 @@ static int mdss_mdp_bus_scale_set_quota(u64 ab_quota_rt, u64 ab_quota_nrt, } mdss_res->curr_bw_uc_idx = new_uc_idx; - ATRACE_BEGIN("msm_bus_scale_req"); - rc = msm_bus_scale_client_update_request(mdss_res->bus_hdl, - new_uc_idx); - ATRACE_END("msm_bus_scale_req"); - + if ((mdss_res->bus_bw_cnt == 0) && mdss_res->curr_bw_uc_idx) { + rc = 0; + } else { /* vote BW if bus_bw_cnt > 0 or uc_idx is zero */ + ATRACE_BEGIN("msm_bus_scale_req"); + rc = msm_bus_scale_client_update_request(mdss_res->bus_hdl, + new_uc_idx); + ATRACE_END("msm_bus_scale_req"); + } return rc; } @@ -439,7 +449,7 @@ int mdss_bus_scale_set_quota(int client, u64 ab_quota, u64 ib_quota) u64 total_ab_rt = 0, total_ib_rt = 0; u64 total_ab_nrt = 0, total_ib_nrt = 0; - mutex_lock(&bus_bw_lock); + mutex_lock(&mdss_res->bus_bw_lock); mdss_res->ab[client] = ab_quota; mdss_res->ib[client] = ib_quota; @@ -458,7 +468,7 @@ int mdss_bus_scale_set_quota(int client, u64 ab_quota, u64 ib_quota) rc = mdss_mdp_bus_scale_set_quota(total_ab_rt, total_ab_nrt, total_ib_rt, total_ib_nrt); - mutex_unlock(&bus_bw_lock); + mutex_unlock(&mdss_res->bus_bw_lock); return rc; } @@ -768,18 +778,17 @@ end: void mdss_bus_bandwidth_ctrl(int enable) { struct mdss_data_type *mdata = mdss_mdp_get_mdata(); - static int bus_bw_cnt; int changed = 0; - mutex_lock(&bus_bw_lock); + mutex_lock(&mdata->bus_bw_lock); if (enable) { - if (bus_bw_cnt == 0) + if (mdata->bus_bw_cnt == 0) changed++; - bus_bw_cnt++; + mdata->bus_bw_cnt++; } else { - if (bus_bw_cnt) { - bus_bw_cnt--; - if (bus_bw_cnt == 0) + if (mdata->bus_bw_cnt) { + mdata->bus_bw_cnt--; + if (mdata->bus_bw_cnt == 0) changed++; } else { pr_err("Can not be turned off\n"); @@ -787,7 +796,7 @@ void mdss_bus_bandwidth_ctrl(int enable) } pr_debug("bw_cnt=%d changed=%d enable=%d\n", - bus_bw_cnt, changed, enable); + mdata->bus_bw_cnt, changed, enable); if (changed) { if (!enable) { @@ -803,7 +812,7 @@ void mdss_bus_bandwidth_ctrl(int enable) } } - mutex_unlock(&bus_bw_lock); + mutex_unlock(&mdata->bus_bw_lock); } EXPORT_SYMBOL(mdss_bus_bandwidth_ctrl); @@ -1226,8 +1235,10 @@ void mdss_mdp_footswitch_ctrl_splash(int on) pr_err("Footswitch failed to enable\n"); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); + mdss_bus_bandwidth_ctrl(true); } else { pr_debug("Disable MDP FS for splash.\n"); + mdss_bus_bandwidth_ctrl(false); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); regulator_disable(mdata->fs); if (mdata->venus) @@ -1491,6 +1502,7 @@ static int mdss_mdp_probe(struct platform_device *pdev) mdss_res = mdata; mutex_init(&mdata->reg_lock); mutex_init(&mdata->mdp_bus_lock); + mutex_init(&mdata->bus_bw_lock); atomic_set(&mdata->sd_client_count, 0); atomic_set(&mdata->active_intf_cnt, 0); diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index 2c7896fc9796..a645bd290f38 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -3211,11 +3211,12 @@ int mdss_mdp_ctl_stop(struct mdss_mdp_ctl *ctl, int power_state) } ctl->play_cnt = 0; - mdss_mdp_ctl_perf_update(ctl, 0, true); end: - if (!ret) + if (!ret) { ctl->power_state = power_state; + mdss_mdp_ctl_perf_update(ctl, 0, true); + } mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); mutex_unlock(&ctl->lock); -- cgit v1.2.3