When setcrtc is called and steals the last connector away from a crtc it's turned off because it can't stay configured without connectors. The framebuffer is still preserved however, and that causes troubles in the IGT stress test kms_flip.flips-vs-fences which tries to use as many pins as possible and hangs on the third crtc because of framebuffer pins on the first 2 crtc's. Cc: stable@xxxxxxxxxxxxxxx #v4.3 Signed-off-by: Maarten Lankhorst <maarten.lankhorst@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/intel_display.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5e520ae5f42e..d95d8acae51f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13571,15 +13571,17 @@ intel_prepare_plane_fb(struct drm_plane *plane, struct intel_plane *intel_plane = to_intel_plane(plane); struct drm_i915_gem_object *obj = intel_fb_obj(fb); struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->state->fb); + struct drm_crtc_state *crtc_state; int ret = 0; if (!obj && !old_obj) return 0; - if (old_obj) { - struct drm_crtc_state *crtc_state = - drm_atomic_get_existing_crtc_state(new_state->state, plane->state->crtc); + crtc_state = drm_atomic_get_existing_crtc_state(new_state->state, + new_state->crtc ?: + plane->state->crtc); + if (old_obj) { /* Big Hammer, we also need to ensure that any pending * MI_WAIT_FOR_EVENT inside a user batch buffer on the * current scanout is retired before unpinning the old @@ -13599,7 +13601,7 @@ intel_prepare_plane_fb(struct drm_plane *plane, return ret; } - if (!obj) { + if (!obj || !crtc_state->enable) { ret = 0; } else if (plane->type == DRM_PLANE_TYPE_CURSOR && INTEL_INFO(dev)->cursor_needs_physical) { @@ -13644,15 +13646,22 @@ intel_cleanup_plane_fb(struct drm_plane *plane, struct intel_plane_state *old_intel_state; struct drm_i915_gem_object *old_obj = intel_fb_obj(old_state->fb); struct drm_i915_gem_object *obj = intel_fb_obj(plane->state->fb); + struct drm_crtc_state *old_crtc_state; old_intel_state = to_intel_plane_state(old_state); if (!obj && !old_obj) return; - if (old_obj && (plane->type != DRM_PLANE_TYPE_CURSOR || - !INTEL_INFO(dev)->cursor_needs_physical)) + old_crtc_state = drm_atomic_get_existing_crtc_state(old_state->state, + old_state->crtc ?: + plane->state->crtc); + + if (old_obj && old_crtc_state->enable && + (plane->type != DRM_PLANE_TYPE_CURSOR || + !INTEL_INFO(dev)->cursor_needs_physical)) { intel_unpin_fb_obj(old_state->fb, old_state); + } /* prepare_fb aborted? */ if ((old_obj && (old_obj->frontbuffer_bits & intel_plane->frontbuffer_bit)) || -- 2.1.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx