[PATCH 3/3] drm/atomic: Refuse to steal encoders from connectors not part of the state.
Daniel Vetter
daniel at ffwll.ch
Thu Feb 18 11:07:08 UTC 2016
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
More information about the dri-devel
mailing list