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

Commit 3b888b44 authored by Veera Sundaram Sankaran's avatar Veera Sundaram Sankaran Committed by Ray Zhang
Browse files

disp: msm: sde: reset ctl during wr_ptr_irq timeout



wr_ptr_irq timeout signifies that the MDP is stuck
on either the current or previous frame. Handle
ctl reset and fence signalling as part of this
timeout handling. This logic would help to recover
the HW faster in case of posted-start.

Change-Id: I09b3d21772df431f9fc4a58b2fd9b4fcac4a7de7
Signed-off-by: default avatarVeera Sundaram Sankaran <veeras@codeaurora.org>
Signed-off-by: default avatarRay Zhang <rayz@codeaurora.org>
Signed-off-by: default avatarBruce Hoo <bingchua@codeaurora.org>
parent 6e3e2450
Loading
Loading
Loading
Loading
+4 −19
Original line number Diff line number Diff line
@@ -4626,21 +4626,11 @@ static void _helper_flush_dsc(struct sde_encoder_virt *sde_enc)
	}
}

static void _sde_encoder_needs_hw_reset(struct drm_encoder *drm_enc,
	int ln_cnt1)
void sde_encoder_helper_needs_hw_reset(struct drm_encoder *drm_enc)
{
	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
	struct sde_encoder_phys *phys;
	int ln_cnt2, i;

	/* query line count before cur_master is updated */
	if (sde_enc->cur_master && sde_enc->cur_master->ops.get_wr_line_count)
		ln_cnt2 = sde_enc->cur_master->ops.get_wr_line_count(
			sde_enc->cur_master);
	else
		ln_cnt2 = -EINVAL;

	SDE_EVT32(DRMID(drm_enc), ln_cnt1, ln_cnt2);
	int i;

	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		phys = sde_enc->phys_encs[i];
@@ -4658,7 +4648,7 @@ int sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,
	struct sde_crtc *sde_crtc;
	struct msm_drm_private *priv = NULL;
	bool needs_hw_reset = false;
	int ln_cnt1 = -EINVAL, i, rc, ret = 0;
	int i, rc, ret = 0;
	struct msm_display_info *disp_info;

	if (!drm_enc || !params || !drm_enc->dev ||
@@ -4675,11 +4665,6 @@ int sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,
	SDE_DEBUG_ENC(sde_enc, "\n");
	SDE_EVT32(DRMID(drm_enc));

	/* save this for later, in case of errors */
	if (sde_enc->cur_master && sde_enc->cur_master->ops.get_wr_line_count)
		ln_cnt1 = sde_enc->cur_master->ops.get_wr_line_count(
				sde_enc->cur_master);

	if (sde_enc->cur_master && sde_enc->cur_master->connector &&
		disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE)
		sde_enc->frame_trigger_mode = sde_connector_get_property(
@@ -4722,7 +4707,7 @@ int sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,

	/* if any phys needs reset, reset all phys, in-order */
	if (needs_hw_reset)
		_sde_encoder_needs_hw_reset(drm_enc, ln_cnt1);
		sde_encoder_helper_needs_hw_reset(drm_enc);

	_sde_encoder_update_master(drm_enc, params);

+6 −0
Original line number Diff line number Diff line
@@ -516,6 +516,12 @@ void sde_encoder_phys_setup_cdm(struct sde_encoder_phys *phys_enc,
		struct drm_framebuffer *fb, const struct sde_format *format,
		struct sde_rect *wb_roi);

/**
 * sde_encoder_helper_needs_hw_reset - hw reset helper function
 * @drm_enc:    Pointer to drm encoder structure
 */
void sde_encoder_helper_needs_hw_reset(struct drm_encoder *drm_enc);

/**
 * sde_encoder_helper_trigger_flush - control flush helper function
 *	This helper function may be optionally specified by physical
+20 −9
Original line number Diff line number Diff line
@@ -1436,8 +1436,11 @@ static int sde_encoder_phys_cmd_wait_for_commit_done(
	cmd_enc = to_sde_encoder_phys_cmd(phys_enc);

	/* only required for master controller */
	if (sde_encoder_phys_cmd_is_master(phys_enc))
	if (sde_encoder_phys_cmd_is_master(phys_enc)) {
		rc = _sde_encoder_phys_cmd_wait_for_wr_ptr(phys_enc);
		if (rc == -ETIMEDOUT)
			goto wait_for_idle;
	}

	if (!rc && sde_encoder_phys_cmd_is_master(phys_enc) &&
			cmd_enc->autorefresh.cfg.enable)
@@ -1446,14 +1449,22 @@ static int sde_encoder_phys_cmd_wait_for_commit_done(
	/* wait for posted start or serialize trigger */
	if ((atomic_read(&phys_enc->pending_kickoff_cnt) > 1) ||
		(!rc && phys_enc->frame_trigger_mode ==
						FRAME_DONE_WAIT_SERIALIZE)) {
				FRAME_DONE_WAIT_SERIALIZE))
		goto wait_for_idle;

wait_for_idle:
	rc = _sde_encoder_phys_cmd_wait_for_idle(phys_enc);
	if (rc) {
			atomic_set(&phys_enc->pending_kickoff_cnt, 0);
		SDE_EVT32(DRMID(phys_enc->parent),
				phys_enc->hw_pp->idx - PINGPONG_0);
		SDE_ERROR("failed wait_for_idle: %d\n", rc);
		}
			phys_enc->hw_pp->idx - PINGPONG_0,
			phys_enc->frame_trigger_mode,
			atomic_read(&phys_enc->pending_kickoff_cnt),
			phys_enc->enable_state, rc);
		atomic_set(&phys_enc->pending_kickoff_cnt, 0);
		SDE_ERROR("pp:%d failed wait_for_idle: %d\n",
			phys_enc->hw_pp->idx - PINGPONG_0, rc);
		if (phys_enc->enable_state == SDE_ENC_ERR_NEEDS_HW_RESET)
			sde_encoder_helper_needs_hw_reset(phys_enc->parent);
	}

	return rc;