@@ -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;
}
}
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@intel.com> --- drivers/gpu/drm/i915/display/intel_dp.c | 47 +++++++++++++++---------- 1 file changed, 28 insertions(+), 19 deletions(-)