diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h index 2e07fc87701a..212b752016de 100644 --- a/drivers/video/fbdev/msm/mdss.h +++ b/drivers/video/fbdev/msm/mdss.h @@ -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, }; diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index 28216ab8222a..fee51562bad5 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -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: diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index 3a888597dcc3..9611a4e6e41f 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -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);