Account for DSC slice overhead bubbles and adjust the pixel rate while checking the pixel rate against the max dotclock limits.
Signed-off-by: Ankit Nautiyal <[email protected]> --- drivers/gpu/drm/i915/display/intel_dp.c | 19 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_dp.h | 2 ++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 13 +++++++++++++ drivers/gpu/drm/i915/display/intel_vdsc.c | 1 - drivers/gpu/drm/i915/display/intel_vdsc.h | 3 +++ 5 files changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 9f73a1307b6c..a6a1a803d860 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1442,6 +1442,8 @@ bool intel_dp_has_dsc(const struct intel_connector *connector) bool intel_dp_pixel_rate_fits_dotclk(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; @@ -1449,6 +1451,12 @@ bool intel_dp_pixel_rate_fits_dotclk(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; } @@ -1579,8 +1587,13 @@ intel_dp_mode_valid(struct drm_connector *_connector, if (status != MODE_OK) continue; + if (!dsc) + dsc_slice_count = 0; + if (intel_dp_pixel_rate_fits_dotclk(display, target_clock, + mode->htotal, + dsc_slice_count, num_joined_pipes)) { status = MODE_OK; break; @@ -2898,6 +2911,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, for (i = 0; i < ARRAY_SIZE(joiner_candidates); i++) { enum joiner_type joiner = joiner_candidates[i]; + int dsc_slice_count = 0; if (joiner == FORCED_JOINER) { if (!connector->force_joined_pipes) @@ -2939,8 +2953,13 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, if (ret) continue; + if (crtc_state->dsc.compression_enable) + dsc_slice_count = intel_dsc_line_slice_count(&crtc_state->dsc.slice_config); + if (intel_dp_pixel_rate_fits_dotclk(display, adjusted_mode->crtc_clock, + adjusted_mode->crtc_htotal, + dsc_slice_count, num_joined_pipes)) { ret = 0; break; diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 0c1cd843bd0a..78b457b11f07 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -235,6 +235,8 @@ int intel_dp_sdp_min_guardband(const struct intel_crtc_state *crtc_state, int intel_dp_hdisplay_limit(struct intel_display *display); bool intel_dp_pixel_rate_fits_dotclk(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 7c957351467e..25d229843459 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -710,6 +710,7 @@ static int mst_stream_compute_config(struct intel_encoder *encoder, for (i = 0; i < ARRAY_SIZE(joiner_candidates); i++) { enum joiner_type joiner = joiner_candidates[i]; + int dsc_slice_count = 0; ret = -EINVAL; @@ -741,8 +742,12 @@ static int mst_stream_compute_config(struct intel_encoder *encoder, if (ret) continue; + dsc_slice_count = intel_dp_mst_dsc_get_slice_count(connector, pipe_config); + if (intel_dp_pixel_rate_fits_dotclk(display, adjusted_mode->clock, + adjusted_mode->htotal, + dsc_slice_count, num_joined_pipes)) { ret = 0; break; @@ -1542,6 +1547,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *_connector, for (i = 0; i < ARRAY_SIZE(joiner_candidates); i++) { enum joiner_type joiner = joiner_candidates[i]; + int dsc_slice_count = 0; *status = MODE_CLOCK_HIGH; @@ -1569,6 +1575,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; @@ -1593,6 +1604,8 @@ mst_connector_mode_valid_ctx(struct drm_connector *_connector, if (intel_dp_pixel_rate_fits_dotclk(display, mode->clock, + mode->htotal, + dsc_slice_count, num_joined_pipes)) { *status = MODE_OK; break; 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
