From 8343bb90a0e4c1d02ba5ca26ce9508cdf205df6f Mon Sep 17 00:00:00 2001 From: Mahadevan Date: Wed, 10 Mar 2021 16:28:50 +0530 Subject: [PATCH] disp: msm: sde: re-sechedule idle pc event in esd failure case 1. When panel esd check fails, rc_state request to ON will occur in event thread. 2. This ON state is not guaranteed since idle pc event can occur in parallel on commit thread if frame pending count reaches 0. 3. ESD thread is trying to switch vsync at this point to avoid RSC hang, but idle pc event has disabled clocks causing NOC error. To avoid such condition this patch re-schedules idle work which allows completion of display failure notification before the device enters idle state. This re-scheduling is achieved by modifying early return in rc_restart_delayed introduced as part of commit 63107e09b3a8 ("disp: msm: sde: allow delayed_off_work scheduling always"). Change-Id: Ie1a1964b92fe1c681cdf0fc5e10591ef14b2d4c3 Signed-off-by: Mahadevan --- msm/sde/sde_encoder.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index c2135d324e9b..86ca5271903c 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -1626,10 +1626,6 @@ static void _sde_encoder_rc_restart_delayed(struct sde_encoder_virt *sde_enc, unsigned int lp, idle_pc_duration; struct msm_drm_thread *disp_thread; - /* return early if called from esd thread */ - if (sde_enc->delay_kickoff) - return; - /* set idle timeout based on master connector's lp value */ if (sde_enc->cur_master) lp = sde_connector_get_lp( @@ -1717,7 +1713,9 @@ static int _sde_encoder_rc_kickoff(struct drm_encoder *drm_enc, sde_enc->rc_state = SDE_ENC_RC_STATE_ON; end: - _sde_encoder_rc_kickoff_delayed(sde_enc, sw_event); + /* avoid delayed off work if called from esd thread */ + if (!sde_enc->delay_kickoff) + _sde_encoder_rc_kickoff_delayed(sde_enc, sw_event); mutex_unlock(&sde_enc->rc_lock); return ret; @@ -1921,7 +1919,8 @@ static int _sde_encoder_rc_idle(struct drm_encoder *drm_enc, SDE_EVTLOG_ERROR); goto end; } else if (sde_crtc_frame_pending(sde_enc->crtc) || - sde_crtc->kickoff_in_progress) { + sde_crtc->kickoff_in_progress || + sde_enc->delay_kickoff) { SDE_DEBUG_ENC(sde_enc, "skip idle entry"); SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state, sde_crtc_frame_pending(sde_enc->crtc),