msm: mdss: fix dsi underflow during partial updates on DSC based panels
When 2 soft slices per DSC encoder without merge is used, HW expects certain DSI pixel clock to MDP clock ratio. If not maintained, DSI can underflow. This happens if full-frame is split into 4 slices, thus requiring 2 DSC encoders, 2 soft slices per encoder. Now if partial update frame is left-only or right-only with 2 slices then normal topology would dictate using 1 DSC encoder with 2 soft slices. However during partial update, we don't change the pixel clock, but mdp clock is reduced because less number of pixels needs to be processed. This changes the ratio mentioned earlier and DSI underflows. To fix this, either we increase the MDP clock rate or change the topology such a way that we use 2 DSC encoders with 1 slice each. Implement later option to avoid increasing MDP clock. Change-Id: Ia37d8045baefcd1e680902446b4725d279db6a89 Signed-off-by: Ujwal Patel <ujwalp@codeaurora.org>
This commit is contained in:
parent
d287993820
commit
6489c0aef1
3 changed files with 45 additions and 3 deletions
|
@ -154,6 +154,7 @@ enum mdss_hw_quirk {
|
|||
MDSS_QUIRK_ROTCDP,
|
||||
MDSS_QUIRK_DOWNSCALE_HANG,
|
||||
MDSS_QUIRK_DSC_RIGHT_ONLY_PU,
|
||||
MDSS_QUIRK_DSC_2SLICE_PU_THRPUT,
|
||||
MDSS_QUIRK_MAX,
|
||||
};
|
||||
|
||||
|
|
|
@ -1249,6 +1249,7 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata)
|
|||
mdata->mdss_caps_map);
|
||||
mdss_mdp_init_default_prefill_factors(mdata);
|
||||
mdss_set_quirk(mdata, MDSS_QUIRK_DSC_RIGHT_ONLY_PU);
|
||||
mdss_set_quirk(mdata, MDSS_QUIRK_DSC_2SLICE_PU_THRPUT);
|
||||
break;
|
||||
case MDSS_MDP_HW_REV_105:
|
||||
case MDSS_MDP_HW_REV_109:
|
||||
|
|
|
@ -2430,9 +2430,6 @@ static void mdss_mdp_ctl_dsc_config(struct mdss_mdp_mixer *mixer,
|
|||
mdss_mdp_pingpong_write(mixer->pingpong_base,
|
||||
MDSS_MDP_REG_PP_DCE_DATA_OUT_SWAP, data);
|
||||
|
||||
/* dce0_sel->pp0, dce1_sel->pp1 */
|
||||
writel_relaxed(0x0, offset + MDSS_MDP_REG_DCE_SEL);
|
||||
|
||||
if (mixer->num == MDSS_MDP_INTF_LAYERMIXER0) {
|
||||
offset += MDSS_MDP_DSC_0_OFFSET;
|
||||
} else if (mixer->num == MDSS_MDP_INTF_LAYERMIXER1) {
|
||||
|
@ -2684,6 +2681,49 @@ void mdss_mdp_ctl_dsc_setup(struct mdss_mdp_ctl *ctl,
|
|||
left_valid = true;
|
||||
}
|
||||
|
||||
if ((is_dual_lm_single_display(ctl->mfd)) &&
|
||||
(pinfo->partial_update_enabled) &&
|
||||
(pinfo->dsc_enc_total == 2) && (dsc->full_frame_slices == 4) &&
|
||||
(mdss_has_quirk(mdata, MDSS_QUIRK_DSC_2SLICE_PU_THRPUT))) {
|
||||
|
||||
if (mdss_mdp_is_both_lm_valid(ctl)) {
|
||||
/* left + right */
|
||||
|
||||
pr_debug("full line (4 slices) or middle 2 slice partial update\n");
|
||||
writel_relaxed(0x0,
|
||||
mdata->mdp_base + mdata->ppb[0].ctl_off);
|
||||
writel_relaxed(0x0,
|
||||
mdata->mdp_base + MDSS_MDP_REG_DCE_SEL);
|
||||
} else if (mixer_left->valid_roi || mixer_right->valid_roi) {
|
||||
/* left-only or right-only */
|
||||
|
||||
u32 this_frame_slices =
|
||||
dsc->pic_width / dsc->slice_width;
|
||||
|
||||
if (this_frame_slices == 2) {
|
||||
pr_debug("2 slice parital update, use merge\n");
|
||||
|
||||
/* tandem + merge */
|
||||
mode = BIT(1) | BIT(0);
|
||||
|
||||
right_valid = true;
|
||||
left_valid = true;
|
||||
|
||||
writel_relaxed(0x2 << 4, mdata->mdp_base +
|
||||
mdata->ppb[0].ctl_off);
|
||||
writel_relaxed(BIT(0),
|
||||
mdata->mdp_base + MDSS_MDP_REG_DCE_SEL);
|
||||
} else {
|
||||
pr_debug("only one slice partial update\n");
|
||||
writel_relaxed(0x0,
|
||||
mdata->mdp_base +
|
||||
mdata->ppb[0].ctl_off);
|
||||
writel_relaxed(0x0,
|
||||
mdata->mdp_base + MDSS_MDP_REG_DCE_SEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (left_valid) {
|
||||
mdss_mdp_ctl_dsc_config(mixer_left, dsc, mode,
|
||||
ich_reset_override);
|
||||
|
|
Loading…
Add table
Reference in a new issue