From: Mikita Lipski <mikita.lip...@amd.com>

[why]
Since for DSC MST connector's PBN is claculated differently
due to compression, we have to recalculate both PBN and
VCPI slots for that connector.

[how]
The function iterates through all the active streams to
find, which have DSC enabled, then recalculates PBN for
it and calls drm_dp_helper_update_vcpi_slots_for_dsc to
update connector's VCPI slots.

v2: - use drm_dp_mst_atomic_enable_dsc per port to
enable/disable DSC

v3: - Iterate through connector states from the state passed
    - On each connector state get stream from dc_state,
instead CRTC state

Cc: Jerry Zuo <jerry....@amd.com>
Cc: Harry Wentland <harry.wentl...@amd.com>
Cc: Lyude Paul <ly...@redhat.com>
Cc: Manasi Navare <manasi.d.nav...@intel.com>
Signed-off-by: Mikita Lipski <mikita.lip...@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 76 +++++++++++++++++--
 1 file changed, 71 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 93a230d956ee..2ac3a2f0b452 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4986,6 +4986,69 @@ const struct drm_encoder_helper_funcs 
amdgpu_dm_encoder_helper_funcs = {
        .atomic_check = dm_encoder_helper_atomic_check
 };
 
+static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
+                                           struct dc_state *dc_state)
+{
+       struct dc_stream_state *stream = NULL;
+       struct drm_connector *connector;
+       struct drm_connector_state *new_con_state, *old_con_state;
+       struct amdgpu_dm_connector *aconnector;
+       struct dm_connector_state *dm_conn_state;
+       int i, j, clock, bpp;
+       int vcpi, pbn_div, pbn = 0;
+
+       for_each_oldnew_connector_in_state(state, connector, old_con_state, 
new_con_state, i) {
+
+               aconnector = to_amdgpu_dm_connector(connector);
+
+               if (!aconnector->port)
+                       continue;
+
+               if (!new_con_state || !new_con_state->crtc)
+                       continue;
+
+               dm_conn_state = to_dm_connector_state(new_con_state);
+
+               for (j = 0; j < dc_state->stream_count; j++) {
+                       stream = dc_state->streams[j];
+                       if (!stream)
+                               continue;
+
+                       if ((struct 
amdgpu_dm_connector*)stream->dm_stream_context == aconnector)
+                               break;
+
+                       stream = NULL;
+               }
+
+               if (!stream)
+                       continue;
+
+               if (stream->timing.flags.DSC != 1) {
+                       drm_dp_mst_atomic_enable_dsc(state,
+                                                    aconnector->port,
+                                                    dm_conn_state->pbn,
+                                                    0,
+                                                    false);
+                       continue;
+               }
+
+               pbn_div = dm_mst_get_pbn_divider(stream->link);
+               bpp = stream->timing.dsc_cfg.bits_per_pixel;
+               clock = stream->timing.pix_clk_100hz / 10;
+               pbn = drm_dp_calc_pbn_mode(clock, bpp, true);
+               vcpi = drm_dp_mst_atomic_enable_dsc(state,
+                                                   aconnector->port,
+                                                   pbn, pbn_div,
+                                                   true);
+               if (vcpi < 0)
+                       return vcpi;
+
+               dm_conn_state->pbn = pbn;
+               dm_conn_state->vcpi_slots = vcpi;
+       }
+       return 0;
+}
+
 static void dm_drm_plane_reset(struct drm_plane *plane)
 {
        struct dm_plane_state *amdgpu_state = NULL;
@@ -8022,11 +8085,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
        if (ret)
                goto fail;
 
-       /* Perform validation of MST topology in the state*/
-       ret = drm_dp_mst_atomic_check(state);
-       if (ret)
-               goto fail;
-
        if (state->legacy_cursor_update) {
                /*
                 * This is a fast cursor update coming from the plane update
@@ -8098,6 +8156,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
                if (!compute_mst_dsc_configs_for_state(state, 
dm_state->context))
                        goto fail;
 
+               ret = dm_update_mst_vcpi_slots_for_dsc(state, 
dm_state->context);
+               if (ret)
+                       goto fail;
+
                if (dc_validate_global_state(dc, dm_state->context, false) != 
DC_OK) {
                        ret = -EINVAL;
                        goto fail;
@@ -8126,6 +8188,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
                                dc_retain_state(old_dm_state->context);
                }
        }
+       /* Perform validation of MST topology in the state*/
+       ret = drm_dp_mst_atomic_check(state);
+       if (ret)
+               goto fail;
 
        /* Store the overall update type for use later in atomic check. */
        for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to