Commit 41a52059 authored by Rob Clark's avatar Rob Clark

drm/msm/dpu: handle_frame_done() from vblank irq

Previously the callback was called from whoever called wait_for_vblank(),
but that isn't a great plan when wait_for_vblank() stops getting called,
and results in frame_done_timer expiring.
Signed-off-by: default avatarRob Clark <robdclark@chromium.org>
Reviewed-by: default avatarSean Paul <sean@poorly.run>
Signed-off-by: default avatarRob Clark <robdclark@chromium.org>
parent fe9df3f5
...@@ -313,12 +313,7 @@ static void dpu_crtc_frame_event_work(struct kthread_work *work) ...@@ -313,12 +313,7 @@ static void dpu_crtc_frame_event_work(struct kthread_work *work)
| DPU_ENCODER_FRAME_EVENT_PANEL_DEAD)) { | DPU_ENCODER_FRAME_EVENT_PANEL_DEAD)) {
if (atomic_read(&dpu_crtc->frame_pending) < 1) { if (atomic_read(&dpu_crtc->frame_pending) < 1) {
/* this should not happen */ /* ignore vblank when not pending */
DRM_ERROR("crtc%d ev:%u ts:%lld frame_pending:%d\n",
crtc->base.id,
fevent->event,
ktime_to_ns(fevent->ts),
atomic_read(&dpu_crtc->frame_pending));
} else if (atomic_dec_return(&dpu_crtc->frame_pending) == 0) { } else if (atomic_dec_return(&dpu_crtc->frame_pending) == 0) {
/* release bandwidth and other resources */ /* release bandwidth and other resources */
trace_dpu_crtc_frame_event_done(DRMID(crtc), trace_dpu_crtc_frame_event_done(DRMID(crtc),
......
...@@ -324,6 +324,10 @@ static void dpu_encoder_phys_vid_vblank_irq(void *arg, int irq_idx) ...@@ -324,6 +324,10 @@ static void dpu_encoder_phys_vid_vblank_irq(void *arg, int irq_idx)
/* Signal any waiting atomic commit thread */ /* Signal any waiting atomic commit thread */
wake_up_all(&phys_enc->pending_kickoff_wq); wake_up_all(&phys_enc->pending_kickoff_wq);
phys_enc->parent_ops->handle_frame_done(phys_enc->parent, phys_enc,
DPU_ENCODER_FRAME_EVENT_DONE);
DPU_ATRACE_END("vblank_irq"); DPU_ATRACE_END("vblank_irq");
} }
...@@ -483,8 +487,8 @@ static void dpu_encoder_phys_vid_get_hw_resources( ...@@ -483,8 +487,8 @@ static void dpu_encoder_phys_vid_get_hw_resources(
hw_res->intfs[phys_enc->intf_idx - INTF_0] = INTF_MODE_VIDEO; hw_res->intfs[phys_enc->intf_idx - INTF_0] = INTF_MODE_VIDEO;
} }
static int _dpu_encoder_phys_vid_wait_for_vblank( static int dpu_encoder_phys_vid_wait_for_vblank(
struct dpu_encoder_phys *phys_enc, bool notify) struct dpu_encoder_phys *phys_enc)
{ {
struct dpu_encoder_wait_info wait_info; struct dpu_encoder_wait_info wait_info;
int ret; int ret;
...@@ -499,10 +503,6 @@ static int _dpu_encoder_phys_vid_wait_for_vblank( ...@@ -499,10 +503,6 @@ static int _dpu_encoder_phys_vid_wait_for_vblank(
wait_info.timeout_ms = KICKOFF_TIMEOUT_MS; wait_info.timeout_ms = KICKOFF_TIMEOUT_MS;
if (!dpu_encoder_phys_vid_is_master(phys_enc)) { if (!dpu_encoder_phys_vid_is_master(phys_enc)) {
if (notify && phys_enc->parent_ops->handle_frame_done)
phys_enc->parent_ops->handle_frame_done(
phys_enc->parent, phys_enc,
DPU_ENCODER_FRAME_EVENT_DONE);
return 0; return 0;
} }
...@@ -512,20 +512,11 @@ static int _dpu_encoder_phys_vid_wait_for_vblank( ...@@ -512,20 +512,11 @@ static int _dpu_encoder_phys_vid_wait_for_vblank(
if (ret == -ETIMEDOUT) { if (ret == -ETIMEDOUT) {
dpu_encoder_helper_report_irq_timeout(phys_enc, INTR_IDX_VSYNC); dpu_encoder_helper_report_irq_timeout(phys_enc, INTR_IDX_VSYNC);
} else if (!ret && notify && phys_enc->parent_ops->handle_frame_done) }
phys_enc->parent_ops->handle_frame_done(
phys_enc->parent, phys_enc,
DPU_ENCODER_FRAME_EVENT_DONE);
return ret; return ret;
} }
static int dpu_encoder_phys_vid_wait_for_vblank(
struct dpu_encoder_phys *phys_enc)
{
return _dpu_encoder_phys_vid_wait_for_vblank(phys_enc, true);
}
static int dpu_encoder_phys_vid_wait_for_commit_done( static int dpu_encoder_phys_vid_wait_for_commit_done(
struct dpu_encoder_phys *phys_enc) struct dpu_encoder_phys *phys_enc)
{ {
...@@ -615,7 +606,7 @@ static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc) ...@@ -615,7 +606,7 @@ static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc)
* scanout buffer) don't latch properly.. * scanout buffer) don't latch properly..
*/ */
if (dpu_encoder_phys_vid_is_master(phys_enc)) { if (dpu_encoder_phys_vid_is_master(phys_enc)) {
ret = _dpu_encoder_phys_vid_wait_for_vblank(phys_enc, false); ret = dpu_encoder_phys_vid_wait_for_vblank(phys_enc);
if (ret) { if (ret) {
atomic_set(&phys_enc->pending_kickoff_cnt, 0); atomic_set(&phys_enc->pending_kickoff_cnt, 0);
DRM_ERROR("wait disable failed: id:%u intf:%d ret:%d\n", DRM_ERROR("wait disable failed: id:%u intf:%d ret:%d\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment