For YCbCr420 output, scaler is required for downsampling.
Scaler can be used only when source size smaller than max_src_w and
max_src_h as defined by for the platform.
So go for native YCbCr420 only if there are no scaler constraints.

v2: Corrected max-width based on Display Version.

v3: Updated max-width as per latest Bspec change.

Signed-off-by: Ankit Nautiyal <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 41 ++++++++++++++++++++++---
 1 file changed, 37 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 81fbef30c469..f99bf52171fd 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -804,11 +804,36 @@ u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
        return 0;
 }
 
+static bool
+ycbcr420_scaler_constraints(struct drm_i915_private *i915,
+                           const struct drm_display_mode *mode)
+{
+       int max_src_w, max_src_h;
+
+       if (DISPLAY_VER(i915) < 11) {
+               max_src_w = 4096;
+               max_src_h = 4096;
+       } else if (DISPLAY_VER(i915) < 12) {
+               max_src_w = 5120;
+               max_src_h = 4096;
+       } else if (DISPLAY_VER(i915) < 14) {
+               max_src_w = 5120;
+               max_src_h = 8192;
+       } else {
+               max_src_w = 4096;
+               max_src_h = 8192;
+       }
+
+       return mode->hdisplay > max_src_w || mode->vdisplay > max_src_h;
+}
+
 static enum intel_output_format
 intel_dp_output_format(struct intel_connector *connector,
+                      const struct drm_display_mode *mode,
                       enum intel_output_format sink_format)
 {
        struct intel_dp *intel_dp = intel_attached_dp(connector);
+       struct drm_i915_private *i915 = to_i915(connector->base.dev);
 
        if (!connector->base.ycbcr_420_allowed ||
            sink_format != INTEL_OUTPUT_FORMAT_YCBCR420)
@@ -820,8 +845,15 @@ intel_dp_output_format(struct intel_connector *connector,
 
        if (intel_dp->dfp.ycbcr_444_to_420)
                return INTEL_OUTPUT_FORMAT_YCBCR444;
-       else
+
+       /*
+        * For YCbCr420 output, scaler is required for downsampling
+        * So go for native YCbCr420 only if there are no scaler constraints.
+        */
+       if (!ycbcr420_scaler_constraints(i915, mode))
                return INTEL_OUTPUT_FORMAT_YCBCR420;
+
+       return INTEL_OUTPUT_FORMAT_RGB;
 }
 
 int intel_dp_min_bpp(enum intel_output_format output_format)
@@ -857,7 +889,7 @@ intel_dp_mode_min_output_bpp(struct intel_connector 
*connector,
        else
                sink_format = INTEL_OUTPUT_FORMAT_RGB;
 
-       output_format = intel_dp_output_format(connector, sink_format);
+       output_format = intel_dp_output_format(connector, mode, sink_format);
 
        return intel_dp_output_bpp(output_format, 
intel_dp_min_bpp(output_format));
 }
@@ -2053,7 +2085,8 @@ intel_dp_compute_output_format(struct intel_encoder 
*encoder,
                crtc_state->sink_format = INTEL_OUTPUT_FORMAT_RGB;
        }
 
-       crtc_state->output_format = intel_dp_output_format(connector, 
crtc_state->sink_format);
+       crtc_state->output_format = intel_dp_output_format(connector, 
adjusted_mode,
+                                                          
crtc_state->sink_format);
 
        ret = intel_dp_compute_link_config(encoder, crtc_state, conn_state,
                                           respect_downstream_limits);
@@ -2063,7 +2096,7 @@ intel_dp_compute_output_format(struct intel_encoder 
*encoder,
                        return ret;
 
                crtc_state->sink_format = INTEL_OUTPUT_FORMAT_YCBCR420;
-               crtc_state->output_format = intel_dp_output_format(connector,
+               crtc_state->output_format = intel_dp_output_format(connector, 
adjusted_mode,
                                                                   
crtc_state->sink_format);
                ret = intel_dp_compute_link_config(encoder, crtc_state, 
conn_state,
                                                   respect_downstream_limits);
-- 
2.25.1

Reply via email to