Add the extra pixels to the hactive while computing overhead with DSC.

Signed-off-by: Ankit Nautiyal <[email protected]>
---
 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

Reply via email to