Make use of the added MST helpers to find, allocate and release link bw
for atomic modesets.

Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 39 +++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_dp_mst.c  | 36 ++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_drv.h     |  3 +++
 3 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index d8effd4..cefaee7 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14109,6 +14109,40 @@ static int calc_watermark_data(struct drm_atomic_state 
*state)
        return 0;
 }
 
+static int intel_mst_clear_config(struct drm_atomic_state *state)
+{
+       struct drm_crtc_state *crtc_state;
+       struct drm_crtc *crtc;
+       struct drm_connector *connector;
+       struct drm_connector_state *connector_state;
+       int i, j;
+
+       for_each_crtc_in_state(state, crtc, crtc_state, i) {
+               if (!crtc_state->active_changed || crtc_state->active)
+                       continue;
+
+               for_each_connector_in_state(state, connector, connector_state, 
j) {
+                       struct intel_encoder *encoder;
+                       struct drm_crtc *curr_crtc;
+                       int slots;
+
+                       encoder = 
to_intel_encoder(connector->state->best_encoder);
+                       if (encoder->type != INTEL_OUTPUT_DP_MST)
+                               continue;
+
+                       curr_crtc = connector->state->crtc;
+                       if (curr_crtc && crtc == curr_crtc) {
+                               slots = 
to_intel_crtc_state(crtc->state)->dp_m_n.tu;
+                               return intel_dp_mst_reset_vcpi(encoder,
+                                                              connector_state,
+                                                              slots);
+                       }
+               }
+       }
+
+       return 0;
+}
+
 /**
  * intel_atomic_check - validate state object
  * @dev: drm device
@@ -14179,8 +14213,11 @@ static int intel_atomic_check(struct drm_device *dev,
        }
 
        if (any_ms) {
-               ret = intel_modeset_checks(state);
+               ret = intel_mst_clear_config(state);
+               if (ret)
+                       return ret;
 
+               ret = intel_modeset_checks(state);
                if (ret)
                        return ret;
        } else {
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c 
b/drivers/gpu/drm/i915/intel_dp_mst.c
index 02a1e2c..331909b 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -44,6 +44,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder 
*encoder,
        int lane_count, slots;
        const struct drm_display_mode *adjusted_mode = 
&pipe_config->base.adjusted_mode;
        int mst_pbn;
+       struct drm_dp_mst_topology_state *topology_state;
 
        pipe_config->has_pch_encoder = false;
        bpp = 24;
@@ -65,7 +66,18 @@ static bool intel_dp_mst_compute_config(struct intel_encoder 
*encoder,
        mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, bpp);
 
        pipe_config->pbn = mst_pbn;
-       slots = drm_dp_find_vcpi_slots(&intel_dp->mst_mgr, mst_pbn);
+
+       topology_state = drm_atomic_get_mst_topology_state(state,
+                                                          &intel_dp->mst_mgr);
+       if (topology_state == NULL)
+               return false;
+
+       slots = drm_dp_atomic_find_vcpi_slots(topology_state, connector->port,
+                                             mst_pbn);
+       if (slots < 0) {
+               DRM_DEBUG_KMS("not enough link bw for this mode\n");
+               return false;
+       }
 
        intel_link_compute_m_n(bpp, lane_count,
                               adjusted_mode->crtc_clock,
@@ -78,6 +90,28 @@ static bool intel_dp_mst_compute_config(struct intel_encoder 
*encoder,
 
 }
 
+int intel_dp_mst_reset_vcpi(struct intel_encoder *encoder,
+                            struct drm_connector_state *conn_state, int slots)
+{
+       struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+       struct drm_dp_mst_topology_mgr *mgr  = &intel_mst->primary->dp.mst_mgr;
+       struct drm_dp_mst_topology_state *topology_state;
+       struct intel_connector *connector =
+               to_intel_connector(conn_state->connector);
+       int released;
+
+       topology_state = drm_atomic_get_mst_topology_state(conn_state->state, 
mgr);
+       if (IS_ERR(topology_state))
+               return PTR_ERR(topology_state);
+
+       released = drm_dp_atomic_release_vcpi_slots(topology_state, 
connector->port);
+
+       if (WARN_ON(released != slots))
+               return -EINVAL;
+
+       return 0;
+}
+
 static void intel_mst_disable_dp(struct intel_encoder *encoder,
                                 struct intel_crtc_state *old_crtc_state,
                                 struct drm_connector_state *old_conn_state)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 025e4c8..2dccbfd 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1487,6 +1487,9 @@ int intel_dp_aux_init_backlight_funcs(struct 
intel_connector *intel_connector);
 /* intel_dp_mst.c */
 int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int 
conn_id);
 void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);
+int intel_dp_mst_reset_vcpi(struct intel_encoder *encoder,
+                            struct drm_connector_state *conn_state,
+                            int slots);
 /* intel_dsi.c */
 void intel_dsi_init(struct drm_i915_private *dev_priv);
 
-- 
2.7.4

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

Reply via email to