This patch adds support to iterate over compressed output bpp as per the fractional step, supported by DP sink. v2: -Avoid ending up with compressed bpp, same as pipe bpp. (Stan) Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@xxxxxxxxx> --- drivers/gpu/drm/i915/display/intel_dp.c | 47 +++++++++++++++---------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 3d08acb4505a..8dede5969af5 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1476,10 +1476,11 @@ static int intel_dp_dsc_compute_params(struct intel_encoder *encoder, return drm_dsc_compute_rc_parameters(vdsc_cfg); } -static bool is_dsc_bw_sufficient(int link_rate, int lane_count, int compressed_bpp, +static bool is_dsc_bw_sufficient(int link_rate, int lane_count, int compressed_bppx16, const struct drm_display_mode *adjusted_mode) { - int mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, compressed_bpp); + int mode_rate = DIV_ROUND_UP(intel_dp_link_required(adjusted_mode->crtc_clock, + compressed_bppx16), 16); int link_avail = intel_dp_max_data_rate(link_rate, lane_count); return mode_rate <= link_avail; @@ -1489,7 +1490,7 @@ static int dsc_compute_link_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct link_config_limits *limits, int pipe_bpp, - u16 compressed_bpp) + u16 compressed_bppx16) { const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; @@ -1513,11 +1514,11 @@ static int dsc_compute_link_config(struct intel_dp *intel_dp, adjusted_mode->crtc_hdisplay, pipe_config->bigjoiner_pipes, pipe_bpp, 64); - if (compressed_bpp > dsc_max_bpp) + if (compressed_bppx16 > dsc_max_bpp << 16) continue; if (!is_dsc_bw_sufficient(link_rate, lane_count, - compressed_bpp, adjusted_mode)) + compressed_bppx16, adjusted_mode)) continue; pipe_config->lane_count = lane_count; @@ -1580,33 +1581,41 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, int pipe_bpp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - u16 compressed_bpp; - int dsc_min_bpp, dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp; + u16 compressed_bppx16; + int dsc_min_bppx16, dsc_src_max_bppx16, dsc_sink_max_bppx16, dsc_max_bppx16; + u8 bppx16_incr = drm_dp_dsc_sink_bpp_incr(intel_dp->dsc_dpcd); + u8 bppx16_step; int ret; - dsc_min_bpp = max(dsc_min_compressed_bppx16(pipe_config) >> 4, 8); + if (DISPLAY_VER(dev_priv) < 14 || bppx16_incr <= 1) + bppx16_step = 16; + else + bppx16_step = 16 / bppx16_incr; + + dsc_min_bppx16 = max((int)dsc_min_compressed_bppx16(pipe_config), 8 << 4); if (DISPLAY_VER(dev_priv) <= 12) - dsc_src_max_bpp = 23; + dsc_src_max_bppx16 = 23 << 4; else - dsc_src_max_bpp = 27; - dsc_sink_max_bpp = dsc_max_sink_compressed_bppx16(intel_dp->dsc_dpcd, - pipe_config, pipe_bpp / 3) >> 4; + dsc_src_max_bppx16 = 27 << 4; + dsc_sink_max_bppx16 = dsc_max_sink_compressed_bppx16(intel_dp->dsc_dpcd, + pipe_config, pipe_bpp / 3); - dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) : dsc_src_max_bpp; + dsc_max_bppx16 = dsc_sink_max_bppx16 ? + min(dsc_sink_max_bppx16, dsc_src_max_bppx16) : dsc_src_max_bppx16; /* Compressed BPP should be less than the Input DSC bpp */ - dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1); + dsc_max_bppx16 = min(dsc_max_bppx16, (pipe_bpp << 4) - bppx16_step); - for (compressed_bpp = dsc_max_bpp; - compressed_bpp >= dsc_min_bpp; - compressed_bpp--) { + for (compressed_bppx16 = dsc_max_bppx16; + compressed_bppx16 >= dsc_min_bppx16; + compressed_bppx16 -= bppx16_step) { ret = dsc_compute_link_config(intel_dp, pipe_config, limits, pipe_bpp, - compressed_bpp); + compressed_bppx16); if (ret == 0) { - pipe_config->dsc.compressed_bpp = compressed_bpp << 4; + pipe_config->dsc.compressed_bpp = compressed_bppx16; return 0; } } -- 2.25.1