Merge tag 'amd-drm-next-6.1-2022-09-08' of https://gitlab.freedesktop.org/agd5f/linux...
[platform/kernel/linux-starfive.git] / drivers / gpu / drm / amd / display / amdgpu_dm / amdgpu_dm_mst_types.c
index ce69292..6ff96b4 100644 (file)
@@ -448,34 +448,13 @@ dm_dp_mst_detect(struct drm_connector *connector,
 }
 
 static int dm_dp_mst_atomic_check(struct drm_connector *connector,
-                               struct drm_atomic_state *state)
+                                 struct drm_atomic_state *state)
 {
-       struct drm_connector_state *new_conn_state =
-                       drm_atomic_get_new_connector_state(state, connector);
-       struct drm_connector_state *old_conn_state =
-                       drm_atomic_get_old_connector_state(state, connector);
        struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
-       struct drm_crtc_state *new_crtc_state;
-       struct drm_dp_mst_topology_mgr *mst_mgr;
-       struct drm_dp_mst_port *mst_port;
+       struct drm_dp_mst_topology_mgr *mst_mgr = &aconnector->mst_port->mst_mgr;
+       struct drm_dp_mst_port *mst_port = aconnector->port;
 
-       mst_port = aconnector->port;
-       mst_mgr = &aconnector->mst_port->mst_mgr;
-
-       if (!old_conn_state->crtc)
-               return 0;
-
-       if (new_conn_state->crtc) {
-               new_crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
-               if (!new_crtc_state ||
-                   !drm_atomic_crtc_needs_modeset(new_crtc_state) ||
-                   new_crtc_state->enable)
-                       return 0;
-               }
-
-       return drm_dp_atomic_release_vcpi_slots(state,
-                                               mst_mgr,
-                                               mst_port);
+       return drm_dp_atomic_release_time_slots(state, mst_mgr, mst_port);
 }
 
 static const struct drm_connector_helper_funcs dm_dp_mst_connector_helper_funcs = {
@@ -619,15 +598,8 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
 
        dc_link_dp_get_max_link_enc_cap(aconnector->dc_link, &max_link_enc_cap);
        aconnector->mst_mgr.cbs = &dm_mst_cbs;
-       drm_dp_mst_topology_mgr_init(
-               &aconnector->mst_mgr,
-               adev_to_drm(dm->adev),
-               &aconnector->dm_dp_aux.aux,
-               16,
-               4,
-               max_link_enc_cap.lane_count,
-               drm_dp_bw_code_to_link_rate(max_link_enc_cap.link_rate),
-               aconnector->connector_id);
+       drm_dp_mst_topology_mgr_init(&aconnector->mst_mgr, adev_to_drm(dm->adev),
+                                    &aconnector->dm_dp_aux.aux, 16, 4, aconnector->connector_id);
 
        drm_connector_attach_dp_subconnector_property(&aconnector->base);
 }
@@ -732,6 +704,7 @@ static int bpp_x16_from_pbn(struct dsc_mst_fairness_params param, int pbn)
 }
 
 static bool increase_dsc_bpp(struct drm_atomic_state *state,
+                            struct drm_dp_mst_topology_state *mst_state,
                             struct dc_link *dc_link,
                             struct dsc_mst_fairness_params *params,
                             struct dsc_mst_fairness_vars *vars,
@@ -744,12 +717,9 @@ static bool increase_dsc_bpp(struct drm_atomic_state *state,
        int min_initial_slack;
        int next_index;
        int remaining_to_increase = 0;
-       int pbn_per_timeslot;
        int link_timeslots_used;
        int fair_pbn_alloc;
 
-       pbn_per_timeslot = dm_mst_get_pbn_divider(dc_link);
-
        for (i = 0; i < count; i++) {
                if (vars[i + k].dsc_enabled) {
                        initial_slack[i] =
@@ -780,46 +750,43 @@ static bool increase_dsc_bpp(struct drm_atomic_state *state,
                link_timeslots_used = 0;
 
                for (i = 0; i < count; i++)
-                       link_timeslots_used += DIV_ROUND_UP(vars[i + k].pbn, pbn_per_timeslot);
+                       link_timeslots_used += DIV_ROUND_UP(vars[i + k].pbn, mst_state->pbn_div);
 
-               fair_pbn_alloc = (63 - link_timeslots_used) / remaining_to_increase * pbn_per_timeslot;
+               fair_pbn_alloc =
+                       (63 - link_timeslots_used) / remaining_to_increase * mst_state->pbn_div;
 
                if (initial_slack[next_index] > fair_pbn_alloc) {
                        vars[next_index].pbn += fair_pbn_alloc;
-                       if (drm_dp_atomic_find_vcpi_slots(state,
+                       if (drm_dp_atomic_find_time_slots(state,
                                                          params[next_index].port->mgr,
                                                          params[next_index].port,
-                                                         vars[next_index].pbn,
-                                                         pbn_per_timeslot) < 0)
+                                                         vars[next_index].pbn) < 0)
                                return false;
                        if (!drm_dp_mst_atomic_check(state)) {
                                vars[next_index].bpp_x16 = bpp_x16_from_pbn(params[next_index], vars[next_index].pbn);
                        } else {
                                vars[next_index].pbn -= fair_pbn_alloc;
-                               if (drm_dp_atomic_find_vcpi_slots(state,
+                               if (drm_dp_atomic_find_time_slots(state,
                                                                  params[next_index].port->mgr,
                                                                  params[next_index].port,
-                                                                 vars[next_index].pbn,
-                                                                 pbn_per_timeslot) < 0)
+                                                                 vars[next_index].pbn) < 0)
                                        return false;
                        }
                } else {
                        vars[next_index].pbn += initial_slack[next_index];
-                       if (drm_dp_atomic_find_vcpi_slots(state,
+                       if (drm_dp_atomic_find_time_slots(state,
                                                          params[next_index].port->mgr,
                                                          params[next_index].port,
-                                                         vars[next_index].pbn,
-                                                         pbn_per_timeslot) < 0)
+                                                         vars[next_index].pbn) < 0)
                                return false;
                        if (!drm_dp_mst_atomic_check(state)) {
                                vars[next_index].bpp_x16 = params[next_index].bw_range.max_target_bpp_x16;
                        } else {
                                vars[next_index].pbn -= initial_slack[next_index];
-                               if (drm_dp_atomic_find_vcpi_slots(state,
+                               if (drm_dp_atomic_find_time_slots(state,
                                                                  params[next_index].port->mgr,
                                                                  params[next_index].port,
-                                                                 vars[next_index].pbn,
-                                                                 pbn_per_timeslot) < 0)
+                                                                 vars[next_index].pbn) < 0)
                                        return false;
                        }
                }
@@ -873,11 +840,10 @@ static bool try_disable_dsc(struct drm_atomic_state *state,
                        break;
 
                vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps);
-               if (drm_dp_atomic_find_vcpi_slots(state,
+               if (drm_dp_atomic_find_time_slots(state,
                                                  params[next_index].port->mgr,
                                                  params[next_index].port,
-                                                 vars[next_index].pbn,
-                                                 dm_mst_get_pbn_divider(dc_link)) < 0)
+                                                 vars[next_index].pbn) < 0)
                        return false;
 
                if (!drm_dp_mst_atomic_check(state)) {
@@ -885,11 +851,10 @@ static bool try_disable_dsc(struct drm_atomic_state *state,
                        vars[next_index].bpp_x16 = 0;
                } else {
                        vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps);
-                       if (drm_dp_atomic_find_vcpi_slots(state,
+                       if (drm_dp_atomic_find_time_slots(state,
                                                          params[next_index].port->mgr,
                                                          params[next_index].port,
-                                                         vars[next_index].pbn,
-                                                         dm_mst_get_pbn_divider(dc_link)) < 0)
+                                                         vars[next_index].pbn) < 0)
                                return false;
                }
 
@@ -903,17 +868,27 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
                                             struct dc_state *dc_state,
                                             struct dc_link *dc_link,
                                             struct dsc_mst_fairness_vars *vars,
+                                            struct drm_dp_mst_topology_mgr *mgr,
                                             int *link_vars_start_index)
 {
-       int i, k;
        struct dc_stream_state *stream;
        struct dsc_mst_fairness_params params[MAX_PIPES];
        struct amdgpu_dm_connector *aconnector;
+       struct drm_dp_mst_topology_state *mst_state = drm_atomic_get_mst_topology_state(state, mgr);
        int count = 0;
+       int i, k;
        bool debugfs_overwrite = false;
 
        memset(params, 0, sizeof(params));
 
+       if (IS_ERR(mst_state))
+               return false;
+
+       mst_state->pbn_div = dm_mst_get_pbn_divider(dc_link);
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+       drm_dp_mst_update_slots(mst_state, dc_link_dp_mst_decide_link_encoding_format(dc_link));
+#endif
+
        /* Set up params */
        for (i = 0; i < dc_state->stream_count; i++) {
                struct dc_dsc_policy dsc_policy = {0};
@@ -972,11 +947,8 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
                vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps);
                vars[i + k].dsc_enabled = false;
                vars[i + k].bpp_x16 = 0;
-               if (drm_dp_atomic_find_vcpi_slots(state,
-                                                params[i].port->mgr,
-                                                params[i].port,
-                                                vars[i + k].pbn,
-                                                dm_mst_get_pbn_divider(dc_link)) < 0)
+               if (drm_dp_atomic_find_time_slots(state, params[i].port->mgr, params[i].port,
+                                                 vars[i + k].pbn) < 0)
                        return false;
        }
        if (!drm_dp_mst_atomic_check(state) && !debugfs_overwrite) {
@@ -990,21 +962,15 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
                        vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps);
                        vars[i + k].dsc_enabled = true;
                        vars[i + k].bpp_x16 = params[i].bw_range.min_target_bpp_x16;
-                       if (drm_dp_atomic_find_vcpi_slots(state,
-                                                         params[i].port->mgr,
-                                                         params[i].port,
-                                                         vars[i + k].pbn,
-                                                         dm_mst_get_pbn_divider(dc_link)) < 0)
+                       if (drm_dp_atomic_find_time_slots(state, params[i].port->mgr,
+                                                         params[i].port, vars[i + k].pbn) < 0)
                                return false;
                } else {
                        vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps);
                        vars[i + k].dsc_enabled = false;
                        vars[i + k].bpp_x16 = 0;
-                       if (drm_dp_atomic_find_vcpi_slots(state,
-                                                         params[i].port->mgr,
-                                                         params[i].port,
-                                                         vars[i + k].pbn,
-                                                         dm_mst_get_pbn_divider(dc_link)) < 0)
+                       if (drm_dp_atomic_find_time_slots(state, params[i].port->mgr,
+                                                         params[i].port, vars[i + k].pbn) < 0)
                                return false;
                }
        }
@@ -1012,7 +978,7 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
                return false;
 
        /* Optimize degree of compression */
-       if (!increase_dsc_bpp(state, dc_link, params, vars, count, k))
+       if (!increase_dsc_bpp(state, mst_state, dc_link, params, vars, count, k))
                return false;
 
        if (!try_disable_dsc(state, dc_link, params, vars, count, k))
@@ -1158,8 +1124,9 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
                        continue;
 
                mutex_lock(&aconnector->mst_mgr.lock);
-               if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link,
-                       vars, &link_vars_start_index)) {
+               if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link, vars,
+                                                     &aconnector->mst_mgr,
+                                                     &link_vars_start_index)) {
                        mutex_unlock(&aconnector->mst_mgr.lock);
                        return false;
                }
@@ -1217,10 +1184,8 @@ static bool
                        continue;
 
                mutex_lock(&aconnector->mst_mgr.lock);
-               if (!compute_mst_dsc_configs_for_link(state,
-                                                     dc_state,
-                                                     stream->link,
-                                                     vars,
+               if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link, vars,
+                                                     &aconnector->mst_mgr,
                                                      &link_vars_start_index)) {
                        mutex_unlock(&aconnector->mst_mgr.lock);
                        return false;