On Thu, Jan 29, 2026 at 10:41:52PM +0530, Ankit Nautiyal wrote: > Account for DSC slice overhead bubbles and adjust the pixel rate while > checking the pixel rate against the max dotclock limits. > > v2: Add missing assignment for dsc_slice_count in > mst_connector_mode_valid_ctx(). (Imre) > > Signed-off-by: Ankit Nautiyal <[email protected]> > --- > drivers/gpu/drm/i915/display/intel_dp.c | 20 ++++++++++++++++++++ > drivers/gpu/drm/i915/display/intel_dp.h | 2 ++ > drivers/gpu/drm/i915/display/intel_dp_mst.c | 19 +++++++++++++++++++ > drivers/gpu/drm/i915/display/intel_vdsc.c | 1 - > drivers/gpu/drm/i915/display/intel_vdsc.h | 3 +++ > 5 files changed, 44 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c > b/drivers/gpu/drm/i915/display/intel_dp.c > index 69a87c5933b1..798a0d192b72 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp.c > +++ b/drivers/gpu/drm/i915/display/intel_dp.c > @@ -1414,6 +1414,8 @@ bool intel_dp_can_join(struct intel_display *display, > > bool intel_dp_dotclk_valid(struct intel_display *display, > int target_clock, > + int htotal, > + int dsc_slice_count, > int num_joined_pipes) > { > int max_dotclk = display->cdclk.max_dotclk_freq; > @@ -1421,6 +1423,12 @@ bool intel_dp_dotclk_valid(struct intel_display > *display, > > effective_dotclk_limit = max_dotclk * num_joined_pipes; > > + if (dsc_slice_count) > + target_clock = > intel_dsc_get_pixel_rate_with_dsc_bubbles(display, > + > target_clock, > + htotal, > + > dsc_slice_count); > + > return target_clock <= effective_dotclk_limit; > } > > @@ -1553,8 +1561,13 @@ intel_dp_mode_valid(struct drm_connector *_connector, > if (status != MODE_OK) > continue; > > + if (!dsc) > + dsc_slice_count = 0; > + > if (!intel_dp_dotclk_valid(display, > target_clock, > + mode->htotal, > + dsc_slice_count, > num_joined_pipes)) > continue; > > @@ -2787,6 +2800,7 @@ intel_dp_compute_link_for_joined_pipes(struct > intel_encoder *encoder, > struct intel_dp *intel_dp = enc_to_intel_dp(encoder); > struct link_config_limits limits; > bool dsc_needed, joiner_needs_dsc; > + int dsc_slice_count = 0; > int ret = 0; > > joiner_needs_dsc = intel_dp_joiner_needs_dsc(display, num_joined_pipes); > @@ -2815,6 +2829,8 @@ intel_dp_compute_link_for_joined_pipes(struct > intel_encoder *encoder, > if (ret || > !intel_dp_dotclk_valid(display, > adjusted_mode->crtc_clock, > + adjusted_mode->crtc_htotal, > + dsc_slice_count,
Nit: It's odd to pass dsc_slice_count instead of a literal 0 in this uncompressed case. The variable could be then also better scoped. The same applies to mst_stream_compute_link_for_joined_pipes(). Regardless of the above: Reviewed-by: Imre Deak <[email protected]> > num_joined_pipes)) > dsc_needed = true; > } > @@ -2841,8 +2857,12 @@ intel_dp_compute_link_for_joined_pipes(struct > intel_encoder *encoder, > if (ret < 0) > return ret; > > + dsc_slice_count = > intel_dsc_line_slice_count(&pipe_config->dsc.slice_config); > + > if (!intel_dp_dotclk_valid(display, > adjusted_mode->crtc_clock, > + adjusted_mode->crtc_htotal, > + dsc_slice_count, > num_joined_pipes)) > return -EINVAL; > } > diff --git a/drivers/gpu/drm/i915/display/intel_dp.h > b/drivers/gpu/drm/i915/display/intel_dp.h > index edeb09372d1e..95a38763a367 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp.h > +++ b/drivers/gpu/drm/i915/display/intel_dp.h > @@ -226,6 +226,8 @@ bool intel_dp_can_join(struct intel_display *display, > int num_joined_pipes); > bool intel_dp_dotclk_valid(struct intel_display *display, > int target_clock, > + int htotal, > + int dsc_slice_count, > int num_joined_pipes); > > #endif /* __INTEL_DP_H__ */ > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c > b/drivers/gpu/drm/i915/display/intel_dp_mst.c > index 129ea3e3916e..1c4b3014ba33 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c > @@ -608,6 +608,7 @@ static int > mst_stream_compute_link_for_joined_pipes(struct intel_encoder *encode > to_intel_connector(conn_state->connector); > struct link_config_limits limits; > bool dsc_needed, joiner_needs_dsc; > + int dsc_slice_count = 0; > int ret = 0; > > joiner_needs_dsc = intel_dp_joiner_needs_dsc(display, num_joined_pipes); > @@ -626,6 +627,8 @@ static int > mst_stream_compute_link_for_joined_pipes(struct intel_encoder *encode > if (ret || > !intel_dp_dotclk_valid(display, > adjusted_mode->clock, > + adjusted_mode->htotal, > + dsc_slice_count, > num_joined_pipes)) > dsc_needed = true; > } > @@ -670,8 +673,12 @@ static int > mst_stream_compute_link_for_joined_pipes(struct intel_encoder *encode > if (ret) > return ret; > > + dsc_slice_count = intel_dp_mst_dsc_get_slice_count(connector, > pipe_config); > + > if (!intel_dp_dotclk_valid(display, > adjusted_mode->clock, > + adjusted_mode->htotal, > + dsc_slice_count, > num_joined_pipes)) > return -EINVAL; > } > @@ -1531,6 +1538,8 @@ mst_connector_mode_valid_ctx(struct drm_connector > *_connector, > } > > for (num_pipes = 1; num_pipes <= I915_MAX_PIPES; num_pipes++) { > + int dsc_slice_count = 0; > + > *status = MODE_CLOCK_HIGH; > > if (connector->force_joined_pipes && > @@ -1553,6 +1562,11 @@ mst_connector_mode_valid_ctx(struct drm_connector > *_connector, > */ > int pipe_bpp = intel_dp_dsc_compute_max_bpp(connector, > U8_MAX); > > + dsc_slice_count = > intel_dp_dsc_get_slice_count(connector, > + > mode->clock, > + > mode->hdisplay, > + > num_joined_pipes); > + > if (!drm_dp_is_uhbr_rate(max_link_clock)) > bw_overhead_flags |= DRM_DP_BW_OVERHEAD_FEC; > > @@ -1575,8 +1589,13 @@ mst_connector_mode_valid_ctx(struct drm_connector > *_connector, > if (*status != MODE_OK) > continue; > > + if (!dsc) > + dsc_slice_count = 0; > + > if (!intel_dp_dotclk_valid(display, > mode->clock, > + mode->htotal, > + dsc_slice_count, > num_joined_pipes)) > *status = MODE_CLOCK_HIGH; > > diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c > b/drivers/gpu/drm/i915/display/intel_vdsc.c > index 642a89270d8e..7e53201b3cb1 100644 > --- a/drivers/gpu/drm/i915/display/intel_vdsc.c > +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c > @@ -1104,7 +1104,6 @@ void intel_vdsc_state_dump(struct drm_printer *p, int > indent, > drm_dsc_dump_config(p, indent, &crtc_state->dsc.config); > } > > -static > int intel_dsc_get_pixel_rate_with_dsc_bubbles(struct intel_display *display, > int pixel_rate, int htotal, > int dsc_horizontal_slices) > diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h > b/drivers/gpu/drm/i915/display/intel_vdsc.h > index aeb17670307b..f4d5b37293cf 100644 > --- a/drivers/gpu/drm/i915/display/intel_vdsc.h > +++ b/drivers/gpu/drm/i915/display/intel_vdsc.h > @@ -41,5 +41,8 @@ void intel_vdsc_state_dump(struct drm_printer *p, int > indent, > const struct intel_crtc_state *crtc_state); > int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state); > unsigned int intel_vdsc_prefill_lines(const struct intel_crtc_state > *crtc_state); > +int intel_dsc_get_pixel_rate_with_dsc_bubbles(struct intel_display *display, > + int pixel_rate, int htotal, > + int dsc_horizontal_slices); > > #endif /* __INTEL_VDSC_H__ */ > -- > 2.45.2 >
