Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb007e67 authored by Ujwal Patel's avatar Ujwal Patel
Browse files

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: default avatarUjwal Patel <ujwalp@codeaurora.org>
parent c04a713c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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,
};

+1 −0
Original line number Diff line number Diff line
@@ -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:
+43 −3
Original line number Diff line number Diff line
@@ -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);