diff mbox series

[08/10] drm/i915/display: Account for pixel replication in pipe_src

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

Commit Message

Ankit Nautiyal Oct. 17, 2024, 8:23 a.m. UTC
With DSC pixel replication, extra pixels are added in the last slice
of the last pipe. Due to this the total hactive gets increased by few
pixels. Adjust the computation for pipe source width to account for
pixel replication.

Furthermore if the pipe source width is odd, add one more to make
the pipe source width even, as per the Bspec.

These extra pixels will be take care by the Splitter logic in
hardware.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 30 ++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 20bb27aa880b..4f6fbee1ca7c 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -2514,15 +2514,41 @@  void intel_encoder_get_config(struct intel_encoder *encoder,
 	intel_crtc_readout_derived_state(crtc_state);
 }
 
+static int intel_splitter_adjust_pipe_width(int width, int pixel_replication_count, int num_pipes)
+{
+	int pipe_src_width;
+
+	/*
+	 * With ultrajoiner and 12 DSC slices case, addition of extra pixels (padding)
+	 * is required.
+	 * Pixel replication is required due to the rounding of slice_width (Hactive / slice_count)
+	 * One extra pixel is added if the pipe src width becomes odd, to make it even.
+	 *
+	 * Splitter HW takes care of these by removing odd pixel from each pipe.
+	 * It removes replicated pixels from the last pipe.
+	 */
+	width += pixel_replication_count;
+
+	pipe_src_width = width / num_pipes;
+
+	if (pipe_src_width % 2 == 0)
+		return width;
+
+	return width + num_pipes;
+}
+
 static void intel_joiner_compute_pipe_src(struct intel_crtc_state *crtc_state)
 {
 	int num_pipes = intel_crtc_num_joined_pipes(crtc_state);
 	int width, height;
+	int pixel_replication_count = crtc_state->dsc.pixel_replication_count;
 
-	if (num_pipes == 1)
+	if (num_pipes == 1 && !pixel_replication_count)
 		return;
 
-	width = drm_rect_width(&crtc_state->pipe_src);
+	width = intel_splitter_adjust_pipe_width(drm_rect_width(&crtc_state->pipe_src),
+						 pixel_replication_count, num_pipes);
+
 	height = drm_rect_height(&crtc_state->pipe_src);
 
 	drm_rect_init(&crtc_state->pipe_src, 0, 0,