msm: mdss: fix underrun seen with HDMI connected as external

Underruns are observed on 8974 with HDMI connected since the
combined BW of primary and HDMI interface exceeds the
threshold BW. Fail the prepare call under such conditions so
that fallback happens.

Change-Id: I1217c862c344871868e1fabbb7ba51f6814c1e04
Signed-off-by: Vineet Bajaj <vbajaj@codeaurora.org>
This commit is contained in:
Vineet Bajaj 2014-11-20 18:39:47 +05:30 committed by David Keitel
parent 4538cfcaee
commit 88ba84bbe7
3 changed files with 17 additions and 3 deletions

View file

@ -226,6 +226,7 @@ struct mdss_mdp_ctl {
struct mdss_mdp_perf_params new_perf; struct mdss_mdp_perf_params new_perf;
u32 perf_transaction_status; u32 perf_transaction_status;
bool perf_release_ctl_bw; bool perf_release_ctl_bw;
u64 bw_pending;
bool traffic_shaper_enabled; bool traffic_shaper_enabled;
u32 traffic_shaper_mdp_clk; u32 traffic_shaper_mdp_clk;

View file

@ -971,7 +971,8 @@ int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl,
{ {
struct mdss_data_type *mdata = ctl->mdata; struct mdss_data_type *mdata = ctl->mdata;
struct mdss_mdp_perf_params perf; struct mdss_mdp_perf_params perf;
u32 bw, threshold; u32 bw, threshold, i;
u64 bw_sum_of_intfs = 0;
/* we only need bandwidth check on real-time clients (interfaces) */ /* we only need bandwidth check on real-time clients (interfaces) */
if (ctl->intf_type == MDSS_MDP_NO_INTF) if (ctl->intf_type == MDSS_MDP_NO_INTF)
@ -980,13 +981,24 @@ int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl,
__mdss_mdp_perf_calc_ctl_helper(ctl, &perf, __mdss_mdp_perf_calc_ctl_helper(ctl, &perf,
left_plist, left_cnt, right_plist, right_cnt, left_plist, left_cnt, right_plist, right_cnt,
PERF_CALC_PIPE_CALC_SMP_SIZE); PERF_CALC_PIPE_CALC_SMP_SIZE);
ctl->bw_pending = perf.bw_ctl;
for (i = 0; i < mdata->nctl; i++) {
struct mdss_mdp_ctl *temp = mdata->ctl_off + i;
if (temp->power_state == MDSS_PANEL_POWER_ON &&
(temp->intf_type != MDSS_MDP_NO_INTF))
bw_sum_of_intfs += temp->bw_pending;
}
/* convert bandwidth to kb */ /* convert bandwidth to kb */
bw = DIV_ROUND_UP_ULL(perf.bw_ctl, 1000); bw = DIV_ROUND_UP_ULL(bw_sum_of_intfs, 1000);
pr_debug("calculated bandwidth=%uk\n", bw); pr_debug("calculated bandwidth=%uk\n", bw);
threshold = ctl->is_video_mode ? mdata->max_bw_low : mdata->max_bw_high; threshold = (ctl->is_video_mode ||
mdss_mdp_video_mode_intf_connected(ctl)) ?
mdata->max_bw_low : mdata->max_bw_high;
if (bw > threshold) { if (bw > threshold) {
ctl->bw_pending = 0;
pr_debug("exceeds bandwidth: %ukb > %ukb\n", bw, threshold); pr_debug("exceeds bandwidth: %ukb > %ukb\n", bw, threshold);
return -E2BIG; return -E2BIG;
} }

View file

@ -1442,6 +1442,7 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
} }
mutex_lock(&mdp5_data->ov_lock); mutex_lock(&mdp5_data->ov_lock);
ctl->bw_pending = 0;
ret = mdss_mdp_overlay_start(mfd); ret = mdss_mdp_overlay_start(mfd);
if (ret) { if (ret) {
pr_err("unable to start overlay %d (%d)\n", mfd->index, ret); pr_err("unable to start overlay %d (%d)\n", mfd->index, ret);