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

Commit 254ccadf authored by Yashwanth's avatar Yashwanth
Browse files

disp: msm: sde: add pending ctl recovery mask in sde_kms



This change adds pending ctl recovery mask in sde kms
structure to check if there are any ctl paths pending
for recovery and stages only border fill during such
conditions to avoid device crash. Below is the issue
sequence observed during the crash:

1) On one of the ctl path, flush didn't take effect and
flush bits are still pending.

2) It was a NULL flush and last good flush on that
interface has DMA2 pipe staged along with other pipes.

3) Different ctl path re-uses the DMA2 pipe (attached to
ctl path in #1) causing wr_ptr timeout followed by
ppdone timeout.

Change-Id: I07eb9f2fe41f59963dc27655c551c05abe240392
Signed-off-by: default avatarYashwanth <yvulapu@codeaurora.org>
parent 63e8367a
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -3637,8 +3637,11 @@ int sde_crtc_reset_hw(struct drm_crtc *crtc, struct drm_crtc_state *old_state,
	}

	/* Early out if simple ctl reset succeeded */
	if (i == sde_crtc->num_ctls)
	if (i == sde_crtc->num_ctls) {
		sde_kms_update_recovery_mask(_sde_crtc_get_kms(crtc),
			crtc, false);
		return 0;
	}

	SDE_DEBUG("crtc%d: issuing hard reset\n", DRMID(crtc));

@@ -3696,6 +3699,8 @@ int sde_crtc_reset_hw(struct drm_crtc *crtc, struct drm_crtc_state *old_state,
			sde_encoder_kickoff(encoder, false, true);
	}

	sde_kms_update_recovery_mask(_sde_crtc_get_kms(crtc),
			crtc, false);
	/* panic the device if VBIF is not in good state */
	return !recovery_events ? 0 : -EAGAIN;
}
@@ -3770,6 +3775,8 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc,
						params.recovery_events_enabled))
			is_error = true;
		sde_crtc->needs_hw_reset = false;
	} else {
		sde_kms_update_recovery_mask(sde_kms, crtc, false);
	}

	sde_crtc_calc_fps(sde_crtc);
@@ -3790,9 +3797,10 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc,

	sde_vbif_clear_errors(sde_kms);

	if (is_error) {
	if (is_error || sde_kms->recovery_mask) {
		_sde_crtc_remove_pipe_flush(crtc);
		_sde_crtc_blend_setup(crtc, old_state, false);
		SDE_EVT32(sde_kms->recovery_mask);
	}

	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+28 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
 * Copyright (C) 2013 Red Hat
 * Author: Rob Clark <robdclark@gmail.com>
 *
@@ -1512,6 +1512,31 @@ static void sde_kms_complete_commit(struct msm_kms *kms,
	SDE_ATRACE_END("sde_kms_complete_commit");
}

void sde_kms_update_recovery_mask(struct sde_kms *sde_kms,
		struct drm_crtc *crtc, bool flag)
{
	int i;
	struct sde_hw_ctl *ctl;
	struct sde_crtc *sde_crtc;

	if (!crtc || !sde_kms) {
		SDE_ERROR("invalid params\n");
		return;
	}

	sde_crtc = to_sde_crtc(crtc);

	for (i = 0; i < sde_crtc->num_ctls; ++i) {
		ctl = sde_crtc->mixers[i].hw_ctl;
		if (!ctl || !ctl->ops.reset)
			continue;
		if (flag)
			sde_kms->recovery_mask |= BIT(ctl->idx - CTL_0);
		else
			sde_kms->recovery_mask &= ~BIT(ctl->idx - CTL_0);
	}
}

static void sde_kms_wait_for_commit_done(struct msm_kms *kms,
		struct drm_crtc *crtc)
{
@@ -1561,6 +1586,8 @@ static void sde_kms_wait_for_commit_done(struct msm_kms *kms,
		ret = sde_encoder_wait_for_event(encoder, MSM_ENC_COMMIT_DONE);
		if (ret && ret != -EWOULDBLOCK) {
			SDE_ERROR("wait for commit done returned %d\n", ret);
			sde_kms_update_recovery_mask(to_sde_kms(kms),
				crtc, true);
			sde_crtc_request_frame_reset(crtc);
			break;
		}
+12 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
 * Copyright (C) 2013 Red Hat
 * Author: Rob Clark <robdclark@gmail.com>
 *
@@ -274,6 +274,7 @@ struct sde_kms {
	int irq_num;	/* mdss irq number */
	bool irq_enabled;

	int recovery_mask;
	struct sde_core_perf perf;

	/* saved atomic state during system suspend */
@@ -754,4 +755,14 @@ int sde_kms_vm_trusted_prepare_commit(struct sde_kms *sde_kms,
 */
int sde_kms_vm_primary_prepare_commit(struct sde_kms *sde_kms,
					   struct drm_atomic_state *state);

/**
 * sde_kms_update_recovery_mask - function to update recovery ctl mask
 *				  during error cases
 * @sde_kms: pointer to sde_kms
 * @crtc: pointer to drm_crtc
 * @flag: to determine whether to clear/set recovery mask
 */
void sde_kms_update_recovery_mask(struct sde_kms *sde_kms,
					struct drm_crtc *crtc, bool flag);
#endif /* __sde_kms_H__ */