drm/i915/dp_mst: Fix payload removal during output disabling
authorImre Deak <imre.deak@intel.com>
Mon, 6 Feb 2023 11:48:56 +0000 (13:48 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 13 Apr 2023 14:55:37 +0000 (16:55 +0200)
commit eb50912ec931913e70640cecf75cb993fd26995f upstream.

Use the correct old/new topology and payload states in
intel_mst_disable_dp(). So far drm_atomic_get_mst_topology_state() it
used returned either the old state, in case the state was added already
earlier during the atomic check phase or otherwise the new state (but
the latter could fail, which can't be handled in the enable/disable
hooks). After the first patch in the patchset, the state should always
get added already during the check phase, so here we can get the
old/new states without a failure.

drm_dp_remove_payload() should use time_slots from the old payload state
and vc_start_slot in the new one. It should update the new payload
states to reflect the sink's current payload table after the payload is
removed. Pass the new topology state and the old and new payload states
accordingly.

This also fixes a problem where the payload allocations for multiple MST
streams on the same link got inconsistent after a few commits, as
during payload removal the old instead of the new payload state got
updated, so the subsequent enabling sequence and commits used a stale
payload state.

v2: Constify the old payload state pointer. (Ville)

Cc: Lyude Paul <lyude@redhat.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: stable@vger.kernel.org # 6.1
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Acked-by: Lyude Paul <lyude@redhat.com>
Acked-by: Daniel Vetter <daniel@ffwll.ch>
Acked-by: Wayne Lin <wayne.lin@amd.com>
Acked-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230206114856.2665066-4-imre.deak@intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/i915/display/intel_dp_mst.c

index 256afff75b0a60d742fc1b5bd4b928d96d10163d..9a6822256ddf6a98a98c6136c614cbec6c6f8fca 100644 (file)
@@ -364,10 +364,14 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
        struct intel_dp *intel_dp = &dig_port->dp;
        struct intel_connector *connector =
                to_intel_connector(old_conn_state->connector);
-       struct drm_dp_mst_topology_state *mst_state =
-               drm_atomic_get_mst_topology_state(&state->base, &intel_dp->mst_mgr);
-       struct drm_dp_mst_atomic_payload *payload =
-               drm_atomic_get_mst_payload_state(mst_state, connector->port);
+       struct drm_dp_mst_topology_state *old_mst_state =
+               drm_atomic_get_old_mst_topology_state(&state->base, &intel_dp->mst_mgr);
+       struct drm_dp_mst_topology_state *new_mst_state =
+               drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr);
+       const struct drm_dp_mst_atomic_payload *old_payload =
+               drm_atomic_get_mst_payload_state(old_mst_state, connector->port);
+       struct drm_dp_mst_atomic_payload *new_payload =
+               drm_atomic_get_mst_payload_state(new_mst_state, connector->port);
        struct drm_i915_private *i915 = to_i915(connector->base.dev);
 
        drm_dbg_kms(&i915->drm, "active links %d\n",
@@ -375,8 +379,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
 
        intel_hdcp_disable(intel_mst->connector);
 
-       drm_dp_remove_payload(&intel_dp->mst_mgr, mst_state,
-                             payload, payload);
+       drm_dp_remove_payload(&intel_dp->mst_mgr, new_mst_state,
+                             old_payload, new_payload);
 
        intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state);
 }