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: Yashwanth <yvulapu@codeaurora.org>
This commit is contained in:

committed by
Nilaan Gunabalachandran

parent
1961183b41
commit
e96e5bd074
@@ -3892,8 +3892,11 @@ 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));
|
||||||
|
|
||||||
@@ -3951,6 +3954,8 @@ 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;
|
||||||
}
|
}
|
||||||
@@ -4025,6 +4030,8 @@ 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);
|
||||||
@@ -4045,9 +4052,10 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc,
|
|||||||
|
|
||||||
sde_vbif_clear_errors(sde_kms);
|
sde_vbif_clear_errors(sde_kms);
|
||||||
|
|
||||||
if (is_error) {
|
if (is_error || sde_kms->recovery_mask) {
|
||||||
_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) {
|
||||||
|
@@ -1531,6 +1531,31 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -1580,6 +1605,8 @@ 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),
|
||||||
|
crtc, true);
|
||||||
sde_crtc_request_frame_reset(crtc);
|
sde_crtc_request_frame_reset(crtc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -274,6 +274,7 @@ 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 */
|
||||||
@@ -764,4 +765,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,
|
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__ */
|
||||||
|
Reference in New Issue
Block a user