Add the extra pixels to the hactive while computing overhead with DSC. Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@xxxxxxxxx> --- drivers/gpu/drm/i915/display/intel_dp.h | 1 + drivers/gpu/drm/i915/display/intel_dp_mst.c | 18 ++++++++++++++++-- drivers/gpu/drm/i915/display/intel_vdsc.c | 20 ++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_vdsc.h | 6 ++++++ 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 60baf4072dc9..e90a9dc1a8f5 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -20,6 +20,7 @@ struct intel_atomic_state; struct intel_connector; struct intel_crtc_state; struct intel_digital_port; +struct intel_display; struct intel_dp; struct intel_encoder; diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 1a2ff3e1cb68..2bd33e1b318e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -92,20 +92,34 @@ static int intel_dp_mst_bw_overhead(const struct intel_crtc_state *crtc_state, const struct intel_connector *connector, bool ssc, int dsc_slice_count, int bpp_x16) { + struct intel_display *display = to_intel_display(crtc_state); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; unsigned long flags = DRM_DP_BW_OVERHEAD_MST; int overhead; + int replicated_pixels = 0; flags |= intel_dp_is_uhbr(crtc_state) ? DRM_DP_BW_OVERHEAD_UHBR : 0; flags |= ssc ? DRM_DP_BW_OVERHEAD_SSC_REF_CLK : 0; flags |= crtc_state->fec_enable ? DRM_DP_BW_OVERHEAD_FEC : 0; - if (dsc_slice_count) + if (dsc_slice_count) { flags |= DRM_DP_BW_OVERHEAD_DSC; + /* + * When hdisplay is not divisible by dsc_slice_count, extra pixels + * are added to last slice. Need to account for the extra overhead due + * to these extra pixels. + */ + if (adjusted_mode->hdisplay % dsc_slice_count) + replicated_pixels = + intel_dsc_get_replicated_pixels(display, + adjusted_mode->hdisplay, + dsc_slice_count, + crtc_state->output_format); + } overhead = drm_dp_bw_overhead(crtc_state->lane_count, - adjusted_mode->hdisplay, + adjusted_mode->hdisplay + replicated_pixels, dsc_slice_count, bpp_x16, flags); diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index 8b1639a94438..9eaf608995dc 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -1040,3 +1040,23 @@ void intel_vdsc_state_dump(struct drm_printer *p, int indent, intel_vdsc_dump_state(p, indent, crtc_state); drm_dsc_dump_config(p, indent, &crtc_state->dsc.config); } + +int intel_dsc_get_replicated_pixels(struct intel_display *display, + int mode_hdisplay, + int slice_count, + enum intel_output_format output_format) +{ + int replicated_pixels; + int slice_width = DIV_ROUND_UP(mode_hdisplay, slice_count); + + if (!HAS_PIXEL_REPLICATION(display)) + return 0; + + /* Odd slice width is not supported by YCbCr420 format */ + if (slice_width % 2 && output_format == INTEL_OUTPUT_FORMAT_YCBCR420) + return 0; + + replicated_pixels = (slice_width * slice_count) - mode_hdisplay; + + return replicated_pixels; +} diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h index 290b2e9b3482..41b8b5c5866e 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.h +++ b/drivers/gpu/drm/i915/display/intel_vdsc.h @@ -10,9 +10,11 @@ struct drm_printer; +enum intel_output_format; enum transcoder; struct intel_crtc; struct intel_crtc_state; +struct intel_display; struct intel_encoder; bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state); @@ -31,5 +33,9 @@ void intel_dsc_dp_pps_write(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); void intel_vdsc_state_dump(struct drm_printer *p, int indent, const struct intel_crtc_state *crtc_state); +int intel_dsc_get_replicated_pixels(struct intel_display *display, + int mode_hdisplay, + int slice_count, + enum intel_output_format output_format); #endif /* __INTEL_VDSC_H__ */ -- 2.45.2