drm/amd/display: Trigger modesets on MST DSC connectors
authorMikita Lipski <mikita.lipski@amd.com>
Tue, 12 Nov 2019 14:14:15 +0000 (09:14 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 9 Jan 2020 23:07:48 +0000 (18:07 -0500)
Whenever a connector on an MST network is attached, detached, or
undergoes a modeset, the DSC configs for each stream on that
topology will be recalculated. This can change their required
bandwidth, requiring a full reprogramming, as though a modeset
was performed, even if that stream did not change timing.

Therefore, whenever a crtc has drm_atomic_crtc_needs_modeset,
for each crtc that shares a MST topology with that stream and
supports DSC, add that crtc (and all affected connectors and
planes) to the atomic state and set mode_changed on its state

v2: Do this check only on Navi and before adding connectors
and planes on modesetting crtcs

v3: Call the drm_dp_mst_add_affected_dsc_crtcs() to update
all affected CRTCs

Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: David Francis <David.Francis@amd.com>
Signed-off-by: Mikita Lipski <mikita.lipski@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

index 052e76448c75ebbebc96431d3031d72472a31977..b998b038247751a70d8e74d648ea4ed06595087f 100644 (file)
@@ -7893,6 +7893,29 @@ cleanup:
        return ret;
 }
 
+static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm_crtc *crtc)
+{
+       struct drm_connector *connector;
+       struct drm_connector_state *conn_state;
+       struct amdgpu_dm_connector *aconnector = NULL;
+       int i;
+       for_each_new_connector_in_state(state, connector, conn_state, i) {
+               if (conn_state->crtc != crtc)
+                       continue;
+
+               aconnector = to_amdgpu_dm_connector(connector);
+               if (!aconnector->port || !aconnector->mst_port)
+                       aconnector = NULL;
+               else
+                       break;
+       }
+
+       if (!aconnector)
+               return 0;
+
+       return drm_dp_mst_add_affected_dsc_crtcs(state, &aconnector->mst_port->mst_mgr);
+}
+
 /**
  * amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM.
  * @dev: The DRM device
@@ -7945,6 +7968,16 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
        if (ret)
                goto fail;
 
+       if (adev->asic_type >= CHIP_NAVI10) {
+               for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+                       if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
+                               ret = add_affected_mst_dsc_crtcs(state, crtc);
+                               if (ret)
+                                       goto fail;
+                       }
+               }
+       }
+
        for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
                if (!drm_atomic_crtc_needs_modeset(new_crtc_state) &&
                    !new_crtc_state->color_mgmt_changed &&