On Thu, Feb 18, 2016 at 09:54:43AM +0100, Maarten Lankhorst wrote:
> Because encoder <-> connector mapping is fixed when not moving to
> another crtc we can just reject connectors trying to steal an encoder
> from a connector not part of the state. This won't break MST on i915
> because in that case connectors will be part of the state if you switch
> them between crtc's. If they're not they stay on the same crtc, and
> encoder stealing would have failed anyway.

We must do this for backwards compat. setCrtc on a connector that needs an
encoder already used on some other crtc is supposed to disable that
encoder (and the entire pipe if it's all unused) if we need it.
-Daniel

> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> ---
>  drivers/gpu/drm/drm_atomic_helper.c | 43 
> +++++++++++++++++--------------------
>  1 file changed, 20 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> b/drivers/gpu/drm/drm_atomic_helper.c
> index fa708559542c..b2028d592483 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -92,14 +92,21 @@ check_pending_encoder_assignment(struct drm_atomic_state 
> *state,
>                                int conn_idx)
>  {
>       struct drm_connector *connector;
> -     struct drm_connector_state *conn_state;
> -     int i;
>  
> -     for_each_connector_in_state(state, connector, conn_state, i) {
> -             if (i >= conn_idx)
> -                     break;
> +     drm_for_each_connector(connector, state->dev) {
> +             struct drm_connector_state *conn_state =
> +                     drm_atomic_get_existing_connector_state(state,
> +                                                             connector);
>  
> -             if (conn_state->best_encoder == new_encoder)
> +             if (!conn_state) {
> +                     if (connector->state->best_encoder == new_encoder)
> +                             return false;
> +
> +                     continue;
> +             }
> +
> +             if (drm_connector_index(connector) < conn_idx &&
> +                 conn_state->best_encoder == new_encoder)
>                       return false;
>       }
>  
> @@ -149,29 +156,19 @@ set_best_encoder(struct drm_atomic_state *state,
>  
>  static int
>  steal_encoder(struct drm_atomic_state *state,
> -           struct drm_encoder *encoder)
> +           struct drm_encoder *encoder,
> +           int conn_idx)
>  {
> -     struct drm_mode_config *config = &state->dev->mode_config;
>       struct drm_crtc_state *crtc_state;
>       struct drm_connector *connector;
>       struct drm_connector_state *connector_state;
> +     int i;
>  
> -     /*
> -      * We can only steal an encoder coming from a connector, which means we
> -      * must already hold the connection_mutex.
> -      */
> -     WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
> -
> -     list_for_each_entry(connector, &config->connector_list, head) {
> +     for_each_connector_in_state(state, connector, connector_state, i) {
>               struct drm_crtc *encoder_crtc;
>  
> -             if (connector->state->best_encoder != encoder)
> -                     continue;
> -
> -             connector_state = drm_atomic_get_connector_state(state,
> -                                                              connector);
> -             if (IS_ERR(connector_state))
> -                     return PTR_ERR(connector_state);
> +             if (i >= conn_idx)
> +                     break;
>  
>               if (connector_state->best_encoder != encoder ||
>                   WARN_ON(!connector_state->crtc))
> @@ -279,7 +276,7 @@ update_connector_routing(struct drm_atomic_state *state,
>               return -EINVAL;
>       }
>  
> -     ret = steal_encoder(state, new_encoder);
> +     ret = steal_encoder(state, new_encoder, conn_idx);
>       if (ret) {
>               DRM_DEBUG_ATOMIC("Encoder stealing failed for 
> [CONNECTOR:%d:%s]\n",
>                                connector->base.id,
> -- 
> 2.1.0
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

Reply via email to