drm/msm/mdp5: Avoid flushing registers when CRTC is disabled

When a CRTC is disabled, no CTL is allocated to it (CRTC->ctl == NULL);
in that case we should not try to FLUSH registers and do nothing instead.

This can happen when we try to move a cursor but the CRTC's CTL
(CONTROL) has not been allocated yet (inactive CRTC).
It can also happens when we .atomic_check()/.atomic_flush() on a
disabled CRTC.

A CTL needs to be kept as long as the CRTC is alive. Releasing it
after the last VBlank is safer than in .atomic_flush().

Signed-off-by: Stephane Viau <sviau@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
Stephane Viau 2015-02-20 16:30:56 -05:00 committed by Rob Clark
parent 8a4247d645
commit ba0312a610

View File

@ -103,8 +103,8 @@ static void crtc_flush_all(struct drm_crtc *crtc)
struct drm_plane *plane;
uint32_t flush_mask = 0;
/* we could have already released CTL in the disable path: */
if (!mdp5_crtc->ctl)
/* this should not happen: */
if (WARN_ON(!mdp5_crtc->ctl))
return;
drm_atomic_crtc_for_each_plane(plane, crtc) {
@ -143,6 +143,11 @@ static void complete_flip(struct drm_crtc *crtc, struct drm_file *file)
drm_atomic_crtc_for_each_plane(plane, crtc) {
mdp5_plane_complete_flip(plane);
}
if (mdp5_crtc->ctl && !crtc->state->enable) {
mdp5_ctl_release(mdp5_crtc->ctl);
mdp5_crtc->ctl = NULL;
}
}
static void unref_cursor_worker(struct drm_flip_work *work, void *val)
@ -386,14 +391,17 @@ static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc)
mdp5_crtc->event = crtc->state->event;
spin_unlock_irqrestore(&dev->event_lock, flags);
/*
* If no CTL has been allocated in mdp5_crtc_atomic_check(),
* it means we are trying to flush a CRTC whose state is disabled:
* nothing else needs to be done.
*/
if (unlikely(!mdp5_crtc->ctl))
return;
blend_setup(crtc);
crtc_flush_all(crtc);
request_pending(crtc, PENDING_FLIP);
if (mdp5_crtc->ctl && !crtc->state->enable) {
mdp5_ctl_release(mdp5_crtc->ctl);
mdp5_crtc->ctl = NULL;
}
}
static int mdp5_crtc_set_property(struct drm_crtc *crtc,
@ -495,6 +503,10 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
uint32_t roi_h;
unsigned long flags;
/* In case the CRTC is disabled, just drop the cursor update */
if (unlikely(!crtc->state->enable))
return 0;
x = (x > 0) ? x : 0;
y = (y > 0) ? y : 0;