Merge "disp: msm: sde: handle vsync wait status check during timeout"

Цей коміт міститься в:
qctecmdr
2022-06-26 21:14:57 -07:00
зафіксовано Gerrit - the friendly Code Review server
джерело 0682377d91 4672a64057
коміт 96488f7e23
3 змінених файлів з 46 додано та 21 видалено

Переглянути файл

@@ -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;
}