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 <veeras@codeaurora.org>
This commit is contained in:
@@ -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);
|
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,
|
SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0,
|
||||||
atomic_read(&phys_enc->pending_kickoff_cnt),
|
atomic_read(&phys_enc->pending_kickoff_cnt),
|
||||||
atomic_read(&cmd_enc->autorefresh.kickoff_cnt));
|
atomic_read(&cmd_enc->autorefresh.kickoff_cnt),
|
||||||
phys_enc->frame_trigger_mode = params->frame_trigger_mode;
|
phys_enc->frame_trigger_mode);
|
||||||
|
|
||||||
if (phys_enc->frame_trigger_mode == FRAME_DONE_WAIT_DEFAULT) {
|
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;
|
int rc = 0, i, pending_cnt;
|
||||||
struct sde_encoder_phys_cmd *cmd_enc;
|
struct sde_encoder_phys_cmd *cmd_enc;
|
||||||
ktime_t profile_timestamp = ktime_get();
|
ktime_t profile_timestamp = ktime_get();
|
||||||
|
u32 scheduler_status = INVALID_CTL_STATUS;
|
||||||
|
struct sde_hw_ctl *ctl;
|
||||||
|
|
||||||
if (!phys_enc)
|
if (!phys_enc)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -1582,11 +1585,17 @@ static int sde_encoder_phys_cmd_wait_for_commit_done(
|
|||||||
if (cmd_enc->autorefresh.cfg.enable)
|
if (cmd_enc->autorefresh.cfg.enable)
|
||||||
rc = _sde_encoder_phys_cmd_wait_for_autorefresh_done(
|
rc = _sde_encoder_phys_cmd_wait_for_autorefresh_done(
|
||||||
phys_enc);
|
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 */
|
/* wait for posted start or serialize trigger */
|
||||||
if ((atomic_read(&phys_enc->pending_kickoff_cnt) > 1) ||
|
pending_cnt = atomic_read(&phys_enc->pending_kickoff_cnt);
|
||||||
(!rc && phys_enc->frame_trigger_mode == FRAME_DONE_WAIT_SERIALIZE))
|
if ((pending_cnt > 1) ||
|
||||||
|
(pending_cnt && (scheduler_status & BIT(0))) ||
|
||||||
|
(!rc && phys_enc->frame_trigger_mode == FRAME_DONE_WAIT_SERIALIZE))
|
||||||
goto wait_for_idle;
|
goto wait_for_idle;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@@ -1601,7 +1610,8 @@ wait_for_idle:
|
|||||||
phys_enc->hw_pp->idx - PINGPONG_0,
|
phys_enc->hw_pp->idx - PINGPONG_0,
|
||||||
phys_enc->frame_trigger_mode,
|
phys_enc->frame_trigger_mode,
|
||||||
atomic_read(&phys_enc->pending_kickoff_cnt),
|
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",
|
SDE_ERROR("pp:%d failed wait_for_idle: %d\n",
|
||||||
phys_enc->hw_pp->idx - PINGPONG_0, rc);
|
phys_enc->hw_pp->idx - PINGPONG_0, rc);
|
||||||
if (phys_enc->enable_state == SDE_ENC_ERR_NEEDS_HW_RESET)
|
if (phys_enc->enable_state == SDE_ENC_ERR_NEEDS_HW_RESET)
|
||||||
|
Reference in New Issue
Block a user