[PATCH 13/16] drm/i915/dp: Enable DSC pixel replication
Ankit Nautiyal
ankit.k.nautiyal at intel.com
Mon Oct 21 12:34:11 UTC 2024
Allow DSC slice count that do not divide the hactive evenly by adding
extra pixels (replicated pixels).
Check if the pixel replication is supported and store the no. of
replicated pixel count in crtc_state.
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal at intel.com>
---
drivers/gpu/drm/i915/display/intel_dp.c | 20 +++++++++++++--
drivers/gpu/drm/i915/display/intel_dp.h | 1 +
drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 ++
drivers/gpu/drm/i915/display/intel_vdsc.c | 28 +++++++++++++++------
drivers/gpu/drm/i915/display/intel_vdsc.h | 3 +++
5 files changed, 44 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index f35d6fc376c8..433a629c2bae 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -992,9 +992,11 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector,
int mode_clock, int mode_hdisplay,
+ enum intel_output_format output_format,
int num_joined_pipes)
{
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_display *display = to_intel_display(connector);
+ struct drm_i915_private *i915 = to_i915(display->drm);
u8 min_slice_count, i;
int max_slice_width;
@@ -1047,7 +1049,11 @@ u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector,
if (num_joined_pipes > 1 && valid_dsc_slicecount[i] < 2)
continue;
- if (mode_hdisplay % test_slice_count)
+ if (mode_hdisplay % test_slice_count &&
+ !intel_dsc_can_use_pixel_replication(display,
+ mode_hdisplay,
+ test_slice_count,
+ output_format))
continue;
if (min_slice_count <= test_slice_count)
@@ -1474,6 +1480,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
intel_dp_dsc_get_slice_count(connector,
target_clock,
mode->hdisplay,
+ output_format,
num_joined_pipes);
}
@@ -2366,6 +2373,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
int timeslots,
bool compute_pipe_bpp)
{
+ struct intel_display *display = to_intel_display(intel_dp);
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
const struct intel_connector *connector =
@@ -2428,6 +2436,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
intel_dp_dsc_get_slice_count(connector,
adjusted_mode->crtc_clock,
adjusted_mode->crtc_hdisplay,
+ pipe_config->output_format,
num_joined_pipes);
if (!dsc_dp_slice_count) {
drm_dbg_kms(&dev_priv->drm,
@@ -2437,6 +2446,13 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
pipe_config->dsc.slice_count = dsc_dp_slice_count;
}
+
+ pipe_config->dsc.replicated_pixels =
+ intel_dsc_get_replicated_pixels(display,
+ adjusted_mode->crtc_hdisplay,
+ pipe_config->dsc.slice_count,
+ pipe_config->output_format);
+
/*
* VDSC engine operates at 1 Pixel per clock, so if peak pixel rate
* is greater than the maximum Cdclock and if slice count is even
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index e90a9dc1a8f5..7460675c16f6 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -150,6 +150,7 @@ int intel_dp_dsc_sink_max_compressed_bpp(const struct intel_connector *connector
int bpc);
u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector,
int mode_clock, int mode_hdisplay,
+ enum intel_output_format output_format,
int num_joined_pipes);
int intel_dp_num_joined_pipes(struct intel_dp *intel_dp,
struct intel_connector *connector,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 72130c7748dd..b5c72628d445 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -171,6 +171,7 @@ static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connec
return intel_dp_dsc_get_slice_count(connector,
adjusted_mode->clock,
adjusted_mode->hdisplay,
+ crtc_state->output_format,
num_joined_pipes);
}
@@ -1537,6 +1538,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
intel_dp_dsc_get_slice_count(intel_connector,
target_clock,
mode->hdisplay,
+ INTEL_OUTPUT_FORMAT_RGB,
num_joined_pipes);
}
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
index c3c6a4a4dafd..c279f59fdda8 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -1049,6 +1049,22 @@ void intel_vdsc_state_dump(struct drm_printer *p, int indent,
drm_dsc_dump_config(p, indent, &crtc_state->dsc.config);
}
+bool intel_dsc_can_use_pixel_replication(struct intel_display *display,
+ int mode_hdisplay, u8 slice_count,
+ enum intel_output_format output_format)
+{
+ int slice_width = DIV_ROUND_UP(mode_hdisplay, slice_count);
+
+ if (!HAS_PIXEL_REPLICATION(display))
+ return false;
+
+ /* Odd slice width is not supported by YCbCr420 format */
+ if (slice_width % 2 && output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+ return false;
+
+ return true;
+}
+
int intel_dsc_get_replicated_pixels(struct intel_display *display,
int mode_hdisplay,
int slice_count,
@@ -1057,14 +1073,10 @@ int intel_dsc_get_replicated_pixels(struct intel_display *display,
int replicated_pixels;
int slice_width = DIV_ROUND_UP(mode_hdisplay, slice_count);
- if (!HAS_PIXEL_REPLICATION(display))
- return 0;
-
- if (mode_hdisplay % slice_count == 0)
- return 0;
-
- /* Odd slice width is not supported by YCbCr420 format */
- if (slice_width % 2 && output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+ if (!intel_dsc_can_use_pixel_replication(display,
+ mode_hdisplay,
+ slice_count,
+ output_format))
return 0;
replicated_pixels = (slice_width * slice_count) - mode_hdisplay;
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h
index 41b8b5c5866e..3611fc53840d 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
@@ -33,6 +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);
+bool intel_dsc_can_use_pixel_replication(struct intel_display *display,
+ int mode_hdisplay, u8 slice_count,
+ enum intel_output_format output_format);
int intel_dsc_get_replicated_pixels(struct intel_display *display,
int mode_hdisplay,
int slice_count,
--
2.45.2
More information about the Intel-gfx
mailing list