A diff to make this v3. Found when running this through IGT bat. - Keeping an encoder but moving it to a different crtc resulted, in encoder_mask not being updated. - Add some paranoia when best_encoder was already updated to a different encoder in steal_encoder. This could happen in theory. - Relax the WARN_ON(!crtc) when resuming after resume and add an explanation what the WARN_ON is for. --- diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 1ac35072e14f..e5534dc9c4b4 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -137,7 +137,13 @@ set_best_encoder(struct drm_atomic_state *state, /* Unset the encoder_mask in the old crtc state. */ crtc = conn_state->connector->state->crtc; - WARN_ON(!crtc); + /* A NULL crtc is an error here because we should have + * duplicated a NULL best_encoder when crtc was NULL. + * As an exception restoring duplicated atomic state + * during resume is allowed, so don't warn when + * best_encoder is equal to encoder we intend to set. + */ + WARN_ON(!crtc && encoder != conn_state->best_encoder); if (crtc) { crtc_state = drm_atomic_get_existing_crtc_state(state, crtc); @@ -199,6 +205,9 @@ steal_encoder(struct drm_atomic_state *state, if (IS_ERR(connector_state)) return PTR_ERR(connector_state); + if (connector_state->best_encoder != encoder) + continue; + set_best_encoder(state, connector_state, NULL); } @@ -276,6 +285,8 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx) } if (new_encoder == connector_state->best_encoder) { + set_best_encoder(state, connector_state, new_encoder); + DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d:%s]\n", connector->base.id, connector->name, _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel