Merge "disp: msm: sde: handle vsync wait status check during timeout"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
96488f7e23
@@ -481,12 +481,9 @@ int sde_encoder_helper_wait_for_irq(struct sde_encoder_phys *phys_enc,
|
||||
unsigned long flags;
|
||||
|
||||
SDE_EVT32(DRMID(phys_enc->parent), intr_idx,
|
||||
irq->hw_idx, irq->irq_idx,
|
||||
phys_enc->hw_pp->idx - PINGPONG_0,
|
||||
atomic_read(wait_info->atomic_cnt));
|
||||
SDE_DEBUG_PHYS(phys_enc,
|
||||
"done but irq %d not triggered\n",
|
||||
irq->irq_idx);
|
||||
irq->hw_idx, irq->irq_idx, phys_enc->hw_pp->idx - PINGPONG_0,
|
||||
atomic_read(wait_info->atomic_cnt), SDE_EVTLOG_FUNC_CASE1);
|
||||
SDE_DEBUG_PHYS(phys_enc, "done but irq %d not triggered\n", irq->irq_idx);
|
||||
local_irq_save(flags);
|
||||
irq->cb.func(phys_enc, irq->irq_idx);
|
||||
local_irq_restore(flags);
|
||||
@@ -503,7 +500,7 @@ int sde_encoder_helper_wait_for_irq(struct sde_encoder_phys *phys_enc,
|
||||
ret = 0;
|
||||
SDE_EVT32(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
|
||||
irq->irq_idx, phys_enc->hw_pp->idx - PINGPONG_0,
|
||||
atomic_read(wait_info->atomic_cnt));
|
||||
atomic_read(wait_info->atomic_cnt), SDE_EVTLOG_FUNC_CASE2);
|
||||
}
|
||||
|
||||
SDE_EVT32_VERBOSE(DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
|
||||
@@ -5573,8 +5570,13 @@ int sde_encoder_wait_for_event(struct drm_encoder *drm_enc,
|
||||
SDE_ATRACE_BEGIN(atrace_buf);
|
||||
ret = fn_wait(phys);
|
||||
SDE_ATRACE_END(atrace_buf);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
SDE_ERROR_ENC(sde_enc, "intf_type:%d, event:%d i:%d, failed:%d\n",
|
||||
sde_enc->disp_info.intf_type, event, i, ret);
|
||||
SDE_EVT32(DRMID(drm_enc), sde_enc->disp_info.intf_type, event,
|
||||
i, ret, SDE_EVTLOG_ERROR);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -888,17 +888,21 @@ static int _sde_encoder_phys_vid_wait_for_vblank(
|
||||
struct sde_encoder_phys *phys_enc, bool notify)
|
||||
{
|
||||
struct sde_encoder_wait_info wait_info = {0};
|
||||
int ret = 0;
|
||||
int ret = 0, new_cnt;
|
||||
u32 event = SDE_ENCODER_FRAME_EVENT_ERROR |
|
||||
SDE_ENCODER_FRAME_EVENT_SIGNAL_RELEASE_FENCE |
|
||||
SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE;
|
||||
struct drm_connector *conn;
|
||||
struct sde_hw_ctl *hw_ctl;
|
||||
u32 flush_register = 0xebad;
|
||||
bool timeout = false;
|
||||
|
||||
if (!phys_enc) {
|
||||
if (!phys_enc || !phys_enc->hw_ctl) {
|
||||
pr_err("invalid encoder\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hw_ctl = phys_enc->hw_ctl;
|
||||
conn = phys_enc->connector;
|
||||
|
||||
wait_info.wq = &phys_enc->pending_kickoff_wq;
|
||||
@@ -909,20 +913,36 @@ static int _sde_encoder_phys_vid_wait_for_vblank(
|
||||
ret = sde_encoder_helper_wait_for_irq(phys_enc, INTR_IDX_VSYNC,
|
||||
&wait_info);
|
||||
|
||||
if (notify && (ret == -ETIMEDOUT) &&
|
||||
atomic_add_unless(&phys_enc->pending_retire_fence_cnt, -1, 0) &&
|
||||
phys_enc->parent_ops.handle_frame_done) {
|
||||
phys_enc->parent_ops.handle_frame_done(
|
||||
phys_enc->parent, phys_enc, event);
|
||||
if (ret == -ETIMEDOUT) {
|
||||
new_cnt = atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0);
|
||||
timeout = true;
|
||||
|
||||
if (sde_encoder_recovery_events_enabled(phys_enc->parent))
|
||||
sde_connector_event_notify(conn,
|
||||
DRM_EVENT_SDE_HW_RECOVERY,
|
||||
/*
|
||||
* Reset ret when flush register is consumed. This handles a race condition between
|
||||
* irq wait timeout handler reading the register status and the actual IRQ handler
|
||||
*/
|
||||
if (hw_ctl->ops.get_flush_register)
|
||||
flush_register = hw_ctl->ops.get_flush_register(hw_ctl);
|
||||
if (!flush_register)
|
||||
ret = 0;
|
||||
|
||||
SDE_EVT32(DRMID(phys_enc->parent), new_cnt, flush_register, ret,
|
||||
SDE_EVTLOG_FUNC_CASE1);
|
||||
}
|
||||
|
||||
if (notify && timeout && atomic_add_unless(&phys_enc->pending_retire_fence_cnt, -1, 0)
|
||||
&& phys_enc->parent_ops.handle_frame_done) {
|
||||
phys_enc->parent_ops.handle_frame_done(phys_enc->parent, phys_enc, event);
|
||||
|
||||
/* notify only on actual timeout cases */
|
||||
if ((ret == -ETIMEDOUT) && sde_encoder_recovery_events_enabled(phys_enc->parent))
|
||||
sde_connector_event_notify(conn, DRM_EVENT_SDE_HW_RECOVERY,
|
||||
sizeof(uint8_t), SDE_RECOVERY_HARD_RESET);
|
||||
}
|
||||
|
||||
SDE_EVT32(DRMID(phys_enc->parent), event, notify, ret,
|
||||
ret ? SDE_EVTLOG_FATAL : 0);
|
||||
SDE_EVT32(DRMID(phys_enc->parent), event, notify, timeout, ret,
|
||||
ret ? SDE_EVTLOG_FATAL : 0, SDE_EVTLOG_FUNC_EXIT);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@@ -1639,7 +1639,10 @@ static void sde_kms_wait_for_commit_done(struct msm_kms *kms,
|
||||
ret = sde_encoder_wait_for_event(encoder, cwb_disabling ?
|
||||
MSM_ENC_TX_COMPLETE : MSM_ENC_COMMIT_DONE);
|
||||
if (ret && ret != -EWOULDBLOCK) {
|
||||
SDE_ERROR("wait for commit done returned %d\n", ret);
|
||||
SDE_ERROR("crtc:%d, enc:%d, cwb_d:%d, wait for commit done failed ret:%d\n",
|
||||
DRMID(crtc), DRMID(encoder), cwb_disabling, ret);
|
||||
SDE_EVT32(DRMID(crtc), DRMID(encoder), cwb_disabling,
|
||||
ret, SDE_EVTLOG_ERROR);
|
||||
sde_crtc_request_frame_reset(crtc, encoder);
|
||||
break;
|
||||
}
|
||||
|
Reference in New Issue
Block a user