If we start disabling the encoders, there is a potential for a pending flip to never occur - and so we will end up waiting indefinitely. References: https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1097315 Cc: Timo Aaltonen <tjaalton at ubuntu.com> Cc: Daniel Vetter <daniel.vetter at ffwll.ch> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk> --- drivers/gpu/drm/i915/intel_display.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index da1ad9c..dbd8895 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3486,14 +3486,14 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) int plane = intel_crtc->plane; u32 reg, temp; - if (!intel_crtc->active) return; + intel_crtc_wait_for_pending_flips(crtc); + for_each_encoder_on_crtc(dev, crtc, encoder) encoder->disable(encoder); - intel_crtc_wait_for_pending_flips(crtc); drm_vblank_off(dev, pipe); intel_crtc_update_cursor(crtc, false); @@ -3570,12 +3570,13 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) if (!intel_crtc->active) return; + intel_crtc_wait_for_pending_flips(crtc); + is_pch_port = haswell_crtc_driving_pch(crtc); for_each_encoder_on_crtc(dev, crtc, encoder) encoder->disable(encoder); - intel_crtc_wait_for_pending_flips(crtc); drm_vblank_off(dev, pipe); intel_crtc_update_cursor(crtc, false); @@ -3687,15 +3688,15 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) int pipe = intel_crtc->pipe; int plane = intel_crtc->plane; - if (!intel_crtc->active) return; + intel_crtc_wait_for_pending_flips(crtc); + for_each_encoder_on_crtc(dev, crtc, encoder) encoder->disable(encoder); /* Give the overlay scaler a chance to disable if it's on this pipe */ - intel_crtc_wait_for_pending_flips(crtc); drm_vblank_off(dev, pipe); intel_crtc_dpms_overlay(intel_crtc, false); intel_crtc_update_cursor(crtc, false); -- 1.7.10.4