@@ -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
@@ -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,
@@ -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);
}
@@ -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;
@@ -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,
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@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(-)