diff mbox series

[10/16] drm/i915/dp_mst: Account for pixel replication for MST overhead with DSC

Message ID 20241023065257.190035-11-ankit.k.nautiyal@intel.com (mailing list archive)
State New
Headers show
Series Add support for 3 VDSC engines 12 slices | expand

Commit Message

Nautiyal, Ankit K Oct. 23, 2024, 6:52 a.m. UTC
Add the extra pixels to the hactive while computing overhead with DSC.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
---
 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 mbox series

Patch

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__ */