From a823531c33f0b3f34afdc326e56c1f38209f2643 Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Wed, 30 Oct 2019 17:36:17 -0700 Subject: [PATCH] disp: msm: sde: handle another case for lost pp-done interrupt Due to interrupt delays, sometimes the pp-done interrupt for an in-between frame is lost, as with posted-start frames are queued to the hardware before the completion of the previous frame. Handle the lost pp-done interrupt in the case where frame-n pp-done interrupt is missed and frame-n+1 pp-done interrupt is processed before frame-n+1 wr-ptr interrupt. Change-Id: I36ec7ac494b2720fc005dab75047d2f4a5a2a699 Signed-off-by: Veera Sundaram Sankaran --- msm/sde/sde_encoder_phys_cmd.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/msm/sde/sde_encoder_phys_cmd.c b/msm/sde/sde_encoder_phys_cmd.c index 7e9b3fb01d25..92410685f1a2 100644 --- a/msm/sde/sde_encoder_phys_cmd.c +++ b/msm/sde/sde_encoder_phys_cmd.c @@ -1345,10 +1345,11 @@ static int sde_encoder_phys_cmd_prepare_for_kickoff( } SDE_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0); + phys_enc->frame_trigger_mode = params->frame_trigger_mode; SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0, atomic_read(&phys_enc->pending_kickoff_cnt), - atomic_read(&cmd_enc->autorefresh.kickoff_cnt)); - phys_enc->frame_trigger_mode = params->frame_trigger_mode; + atomic_read(&cmd_enc->autorefresh.kickoff_cnt), + phys_enc->frame_trigger_mode); if (phys_enc->frame_trigger_mode == FRAME_DONE_WAIT_DEFAULT) { /* @@ -1557,6 +1558,8 @@ static int sde_encoder_phys_cmd_wait_for_commit_done( int rc = 0, i, pending_cnt; struct sde_encoder_phys_cmd *cmd_enc; ktime_t profile_timestamp = ktime_get(); + u32 scheduler_status = INVALID_CTL_STATUS; + struct sde_hw_ctl *ctl; if (!phys_enc) return -EINVAL; @@ -1582,11 +1585,17 @@ static int sde_encoder_phys_cmd_wait_for_commit_done( if (cmd_enc->autorefresh.cfg.enable) rc = _sde_encoder_phys_cmd_wait_for_autorefresh_done( phys_enc); + + ctl = phys_enc->hw_ctl; + if (ctl && ctl->ops.get_scheduler_status) + scheduler_status = ctl->ops.get_scheduler_status(ctl); } /* 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)) + pending_cnt = atomic_read(&phys_enc->pending_kickoff_cnt); + if ((pending_cnt > 1) || + (pending_cnt && (scheduler_status & BIT(0))) || + (!rc && phys_enc->frame_trigger_mode == FRAME_DONE_WAIT_SERIALIZE)) goto wait_for_idle; return rc; @@ -1601,7 +1610,8 @@ wait_for_idle: phys_enc->hw_pp->idx - PINGPONG_0, phys_enc->frame_trigger_mode, atomic_read(&phys_enc->pending_kickoff_cnt), - phys_enc->enable_state, rc); + phys_enc->enable_state, + cmd_enc->wr_ptr_wait_success, scheduler_status, rc); 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)