On Thu, 2025-11-27 at 19:49 +0200, Imre Deak wrote: > 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:
Reviewed-by: Luca Coelho <[email protected]> -- Cheers, Luca.
