disp: msm: sde: add ctl reset during wait for commit done timeout

During one of the DP timeout usecases, flush doesn't take
effect due to vid vblank wait failure. As a result, smmu
faults are observed because of fetching the previously
staged planes. This change adds ctl reset in the same
DP atomic commit context to recover and avoid
smmu faults.

Change-Id: I2f9aceca56e27f140607317f7596d6fe0d908af8
Signed-off-by: Yashwanth <yvulapu@codeaurora.org>
This commit is contained in:
Yashwanth
2021-03-09 14:31:39 +05:30
committed by Nilaan Gunabalachandran
parent e96e5bd074
commit 8e53d758dd
4 changed files with 9 additions and 51 deletions

View File

@@ -3892,11 +3892,8 @@ int sde_crtc_reset_hw(struct drm_crtc *crtc, struct drm_crtc_state *old_state,
} }
/* Early out if simple ctl reset succeeded */ /* 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; return 0;
}
SDE_DEBUG("crtc%d: issuing hard reset\n", DRMID(crtc)); SDE_DEBUG("crtc%d: issuing hard reset\n", DRMID(crtc));
@@ -3954,8 +3951,6 @@ int sde_crtc_reset_hw(struct drm_crtc *crtc, struct drm_crtc_state *old_state,
sde_encoder_kickoff(encoder, false, true); 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 */ /* panic the device if VBIF is not in good state */
return !recovery_events ? 0 : -EAGAIN; return !recovery_events ? 0 : -EAGAIN;
} }
@@ -4030,8 +4025,6 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc,
params.recovery_events_enabled)) params.recovery_events_enabled))
is_error = true; is_error = true;
sde_crtc->needs_hw_reset = false; sde_crtc->needs_hw_reset = false;
} else {
sde_kms_update_recovery_mask(sde_kms, crtc, false);
} }
sde_crtc_calc_fps(sde_crtc); sde_crtc_calc_fps(sde_crtc);
@@ -4052,10 +4045,9 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc,
sde_vbif_clear_errors(sde_kms); sde_vbif_clear_errors(sde_kms);
if (is_error || sde_kms->recovery_mask) { if (is_error) {
_sde_crtc_remove_pipe_flush(crtc); _sde_crtc_remove_pipe_flush(crtc);
_sde_crtc_blend_setup(crtc, old_state, false); _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) { list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {

View File

@@ -29,6 +29,7 @@
#include "sde_core_perf.h" #include "sde_core_perf.h"
#include "sde_hw_ds.h" #include "sde_hw_ds.h"
#include "sde_color_processing.h" #include "sde_color_processing.h"
#include "sde_encoder.h"
#define SDE_CRTC_NAME_SIZE 12 #define SDE_CRTC_NAME_SIZE 12
@@ -632,12 +633,15 @@ int sde_crtc_reset_hw(struct drm_crtc *crtc, struct drm_crtc_state *old_state,
/** /**
* sde_crtc_request_frame_reset - requests for next frame reset * sde_crtc_request_frame_reset - requests for next frame reset
* @crtc: Pointer to drm crtc object * @crtc: Pointer to drm crtc object
* @encoder: Pointer to drm encoder object
*/ */
static inline int sde_crtc_request_frame_reset(struct drm_crtc *crtc) static inline int sde_crtc_request_frame_reset(struct drm_crtc *crtc,
struct drm_encoder *encoder)
{ {
struct sde_crtc *sde_crtc = to_sde_crtc(crtc); struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
if (sde_crtc->frame_trigger_mode == FRAME_DONE_WAIT_POSTED_START) if (sde_crtc->frame_trigger_mode == FRAME_DONE_WAIT_POSTED_START ||
!sde_encoder_is_dsi_display(encoder))
sde_crtc_reset_hw(crtc, crtc->state, false); sde_crtc_reset_hw(crtc, crtc->state, false);
return 0; return 0;

View File

@@ -1531,31 +1531,6 @@ static void sde_kms_complete_commit(struct msm_kms *kms,
SDE_ATRACE_END("sde_kms_complete_commit"); 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, static void sde_kms_wait_for_commit_done(struct msm_kms *kms,
struct drm_crtc *crtc) struct drm_crtc *crtc)
{ {
@@ -1605,9 +1580,7 @@ static void sde_kms_wait_for_commit_done(struct msm_kms *kms,
ret = sde_encoder_wait_for_event(encoder, MSM_ENC_COMMIT_DONE); ret = sde_encoder_wait_for_event(encoder, MSM_ENC_COMMIT_DONE);
if (ret && ret != -EWOULDBLOCK) { if (ret && ret != -EWOULDBLOCK) {
SDE_ERROR("wait for commit done returned %d\n", ret); SDE_ERROR("wait for commit done returned %d\n", ret);
sde_kms_update_recovery_mask(to_sde_kms(kms), sde_crtc_request_frame_reset(crtc, encoder);
crtc, true);
sde_crtc_request_frame_reset(crtc);
break; break;
} }

View File

@@ -274,7 +274,6 @@ struct sde_kms {
int irq_num; /* mdss irq number */ int irq_num; /* mdss irq number */
bool irq_enabled; bool irq_enabled;
int recovery_mask;
struct sde_core_perf perf; struct sde_core_perf perf;
/* saved atomic state during system suspend */ /* saved atomic state during system suspend */
@@ -765,14 +764,4 @@ int sde_kms_vm_trusted_prepare_commit(struct sde_kms *sde_kms,
*/ */
int sde_kms_vm_primary_prepare_commit(struct sde_kms *sde_kms, int sde_kms_vm_primary_prepare_commit(struct sde_kms *sde_kms,
struct drm_atomic_state *state); 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__ */ #endif /* __sde_kms_H__ */