Use intel_dp_effective_data_rate() to calculate the required link BW for
eDP, DP-SST and MST links. This ensures that the BW is calculated the
same way for all DP output types, during mode validation as well as
during state computation. This approach also allows for accounting with
BW overheads due to the SSC, DSC, FEC being enabled on a link, as well
as due to the MST symbol alignment on the link. Accounting for these
overheads will be added by follow-up changes.

This way also computes the stream BW on a UHBR link correctly, using the
corresponding symbol size to effective data size ratio (i.e. ~97% link
BW utilization for UHBR vs. only ~80% for non-UHBR).

Signed-off-by: Imre Deak <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_dp.c       | 40 +++++++++++--------
 drivers/gpu/drm/i915/display/intel_dp.h       |  4 +-
 .../drm/i915/display/intel_dp_link_training.c |  4 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  4 +-
 4 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 4556a57db7c02..aa55a81a9a9bf 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -453,15 +453,15 @@ int intel_dp_link_bw_overhead(int link_clock, int 
lane_count, int hdisplay,
 /*
  * The required data bandwidth for a mode with given pixel clock and bpp. This
  * is the required net bandwidth independent of the data bandwidth efficiency.
- *
- * TODO: check if callers of this functions should use
- * intel_dp_effective_data_rate() instead.
  */
-int
-intel_dp_link_required(int pixel_clock, int bpp)
+int intel_dp_link_required(int link_clock, int lane_count,
+                          int mode_clock, int mode_hdisplay,
+                          int link_bpp_x16, unsigned long bw_overhead_flags)
 {
-       /* pixel_clock is in kHz, divide bpp by 8 for bit to Byte conversion */
-       return DIV_ROUND_UP(pixel_clock * bpp, 8);
+       int bw_overhead = intel_dp_link_bw_overhead(link_clock, lane_count, 
mode_hdisplay,
+                                                   0, link_bpp_x16, 
bw_overhead_flags);
+
+       return intel_dp_effective_data_rate(mode_clock, link_bpp_x16, 
bw_overhead);
 }
 
 /**
@@ -1531,7 +1531,9 @@ intel_dp_mode_valid(struct drm_connector *_connector,
        max_rate = intel_dp_max_link_data_rate(intel_dp, max_link_clock, 
max_lanes);
 
        link_bpp_x16 = intel_dp_mode_min_link_bpp_x16(connector, mode);
-       mode_rate = intel_dp_link_required(target_clock, 
fxp_q4_to_int_roundup(link_bpp_x16));
+       mode_rate = intel_dp_link_required(max_link_clock, max_lanes,
+                                          target_clock, mode->hdisplay,
+                                          link_bpp_x16, 0);
 
        if (intel_dp_has_dsc(connector)) {
                int pipe_bpp;
@@ -1838,7 +1840,7 @@ intel_dp_compute_link_config_wide(struct intel_dp 
*intel_dp,
                                  const struct link_config_limits *limits)
 {
        int bpp, i, lane_count, clock = intel_dp_mode_clock(pipe_config, 
conn_state);
-       int mode_rate, link_rate, link_avail;
+       int link_rate, link_avail;
 
        for (bpp = fxp_q4_to_int(limits->link.max_bpp_x16);
             bpp >= fxp_q4_to_int(limits->link.min_bpp_x16);
@@ -1846,8 +1848,6 @@ intel_dp_compute_link_config_wide(struct intel_dp 
*intel_dp,
                int link_bpp_x16 =
                        
intel_dp_output_format_link_bpp_x16(pipe_config->output_format, bpp);
 
-               mode_rate = intel_dp_link_required(clock, 
fxp_q4_to_int_roundup(link_bpp_x16));
-
                for (i = 0; i < intel_dp->num_common_rates; i++) {
                        link_rate = intel_dp_common_rate(intel_dp, i);
                        if (link_rate < limits->min_rate ||
@@ -1857,11 +1857,17 @@ intel_dp_compute_link_config_wide(struct intel_dp 
*intel_dp,
                        for (lane_count = limits->min_lane_count;
                             lane_count <= limits->max_lane_count;
                             lane_count <<= 1) {
+                               const struct drm_display_mode *adjusted_mode =
+                                       &pipe_config->hw.adjusted_mode;
+                               int mode_rate =
+                                       intel_dp_link_required(link_rate, 
lane_count,
+                                                              clock, 
adjusted_mode->hdisplay,
+                                                              link_bpp_x16, 0);
+
                                link_avail = 
intel_dp_max_link_data_rate(intel_dp,
                                                                         
link_rate,
                                                                         
lane_count);
 
-
                                if (mode_rate <= link_avail) {
                                        pipe_config->lane_count = lane_count;
                                        pipe_config->pipe_bpp = bpp;
@@ -2724,11 +2730,13 @@ int intel_dp_config_required_rate(const struct 
intel_crtc_state *crtc_state)
 {
        const struct drm_display_mode *adjusted_mode =
                &crtc_state->hw.adjusted_mode;
-       int bpp = crtc_state->dsc.compression_enable ?
-               fxp_q4_to_int_roundup(crtc_state->dsc.compressed_bpp_x16) :
-               crtc_state->pipe_bpp;
+       int link_bpp_x16 = crtc_state->dsc.compression_enable ?
+               crtc_state->dsc.compressed_bpp_x16 :
+               fxp_q4_from_int(crtc_state->pipe_bpp);
 
-       return intel_dp_link_required(adjusted_mode->crtc_clock, bpp);
+       return intel_dp_link_required(crtc_state->port_clock, 
crtc_state->lane_count,
+                                     adjusted_mode->crtc_clock, 
adjusted_mode->hdisplay,
+                                     link_bpp_x16, 0);
 }
 
 bool intel_dp_joiner_needs_dsc(struct intel_display *display,
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index d7f9410129f49..30eebb8cad6d2 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -119,7 +119,9 @@ bool intel_dp_source_supports_tps4(struct intel_display 
*display);
 
 int intel_dp_link_bw_overhead(int link_clock, int lane_count, int hdisplay,
                              int dsc_slice_count, int bpp_x16, unsigned long 
flags);
-int intel_dp_link_required(int pixel_clock, int bpp);
+int intel_dp_link_required(int link_clock, int lane_count,
+                          int mode_clock, int mode_hdisplay,
+                          int link_bpp_x16, unsigned long bw_overhead_flags);
 int intel_dp_effective_data_rate(int pixel_clock, int bpp_x16,
                                 int bw_overhead);
 int intel_dp_max_link_data_rate(struct intel_dp *intel_dp,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c 
b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index aad5fe14962f9..54c585c59b900 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -1195,7 +1195,9 @@ static bool 
intel_dp_can_link_train_fallback_for_edp(struct intel_dp *intel_dp,
                intel_panel_preferred_fixed_mode(intel_dp->attached_connector);
        int mode_rate, max_rate;
 
-       mode_rate = intel_dp_link_required(fixed_mode->clock, 18);
+       mode_rate = intel_dp_link_required(link_rate, lane_count,
+                                          fixed_mode->clock, 
fixed_mode->hdisplay,
+                                          fxp_q4_from_int(18), 0);
        max_rate = intel_dp_max_link_data_rate(intel_dp, link_rate, lane_count);
        if (mode_rate > max_rate)
                return false;
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index c1058b4a85d02..e4dd6b4ca0512 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -1489,7 +1489,9 @@ mst_connector_mode_valid_ctx(struct drm_connector 
*_connector,
 
        max_rate = intel_dp_max_link_data_rate(intel_dp,
                                               max_link_clock, max_lanes);
-       mode_rate = intel_dp_link_required(mode->clock, min_bpp);
+       mode_rate = intel_dp_link_required(max_link_clock, max_lanes,
+                                          mode->clock, mode->hdisplay,
+                                          fxp_q4_from_int(min_bpp), 0);
 
        /*
         * TODO:
-- 
2.49.1

Reply via email to