From 7830ab1e9772a7fb755d7d6fb9008d693212eaf2 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Mon, 1 Jun 2015 14:14:08 +0300 Subject: [PATCH] drm/i915: Copy the staged config to atomic state before crtc restore The logic in intel_crtc_restore_mode() only setups the connectors for the given crtc in the atomic state used for the mode set. However, the enabled state for all crtcs is updated. That can lead to an incosistency that is caught in drm_atomic_helper_check_modeset() that leads the modeset to be aborted. This regression was introduced in commit 8c7b5ccb729870e606321b3703e2c2e698c49a95 Author: Ander Conselvan de Oliveira Date: Tue Apr 21 17:13:19 2015 +0300 drm/i915: Use atomic helpers for computing changed flags Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90396 Signed-off-by: Ander Conselvan de Oliveira --- drivers/gpu/drm/i915/intel_display.c | 38 +++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ee3adb3..a423d7a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12694,25 +12694,31 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc) * state has been overwritten by the configuration read from HW. We * need to copy the staged config to the atomic state, otherwise the * mode set will just reapply the state the HW is already in. */ - for_each_intel_encoder(dev, encoder) { - if (&encoder->new_crtc->base != crtc) - continue; - - for_each_intel_connector(dev, connector) { - if (connector->new_encoder != encoder) - continue; + for_each_intel_connector(dev, connector) { + struct intel_encoder *matching_encoder = NULL; - connector_state = drm_atomic_get_connector_state(state, &connector->base); - if (IS_ERR(connector_state)) { - DRM_DEBUG_KMS("Failed to add [CONNECTOR:%d:%s] to state: %ld\n", - connector->base.base.id, - connector->base.name, - PTR_ERR(connector_state)); - continue; + for_each_intel_encoder(dev, encoder) { + if (connector->new_encoder == encoder) { + matching_encoder = encoder; + break; } + } - connector_state->crtc = crtc; - connector_state->best_encoder = &encoder->base; + connector_state = drm_atomic_get_connector_state(state, &connector->base); + if (IS_ERR(connector_state)) { + DRM_DEBUG_KMS("Failed to add [CONNECTOR:%d:%s] to state: %ld\n", + connector->base.base.id, + connector->base.name, + PTR_ERR(connector_state)); + continue; + } + + if (matching_encoder) { + connector_state->crtc = &matching_encoder->new_crtc->base; + connector_state->best_encoder = &matching_encoder->base; + } else { + connector_state->crtc = NULL; + connector_state->best_encoder = NULL; } } -- 2.1.0