Modes exceeding a single pipe's dotclock were rejected in mode_valid even
when they could be driven by joining pipes. Iterate the joiner candidates
and allow a mode if it fits with joining, relaxing the dotclock ceiling by
the joined pipe count. Joiner configs needing DSC are pruned for
now, since HDMI DSC comes later.

Signed-off-by: Ankit Nautiyal <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_hdmi.c | 51 ++++++++++++++++++-----
 1 file changed, 40 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c 
b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 2ec7d2a5e7d4..2c7c47a3c61d 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2132,20 +2132,55 @@ intel_hdmi_mode_valid_format(struct intel_connector 
*connector,
        struct intel_display *display = to_intel_display(connector);
        struct intel_hdmi *hdmi = intel_attached_hdmi(connector);
        enum drm_mode_status status;
+       int num_joined_pipes;
 
        status = intel_hdmi_sink_format_valid(connector, mode,
                                              has_hdmi_sink, sink_format);
        if (status != MODE_OK)
                return status;
 
-       status = intel_pfit_mode_valid(display, mode, sink_format, 0);
-       if (status != MODE_OK)
+       status = intel_hdmi_tmds_mode_clock_valid(&connector->base, clock,
+                                                 has_hdmi_sink, sink_format);
+
+       if (status == MODE_OK)
+               return status;
+
+       /*
+        * Joiner is supported only with FRL mode.
+        * If a mode is not supported with TMDS and FRL is not supported,
+        * prune the mode.
+        */
+       if (status != MODE_OK && !intel_hdmi_can_support_frl(hdmi))
                return status;
 
-       status = intel_hdmi_tmds_mode_clock_valid(&connector->base, clock, 
has_hdmi_sink, sink_format);
+       for_each_joiner_candidate(connector, mode, num_joined_pipes) {
+               if (intel_joiner_needs_dsc(display, num_joined_pipes)) {
+                       status = MODE_CLOCK_HIGH;
+                       continue;
+               }
+
+               status = intel_pfit_mode_valid(display, mode, sink_format,
+                                              num_joined_pipes);
+               if (status != MODE_OK)
+                       continue;
+
+               status = intel_mode_valid_max_plane_size(display, mode,
+                                                        num_joined_pipes);
+               if (status != MODE_OK)
+                       continue;
+
+               if (!intel_dp_dotclk_valid(display, clock, mode->htotal, 0,
+                                          num_joined_pipes)) {
+                       status = MODE_CLOCK_HIGH;
+                       continue;
+               }
 
-       if (status != MODE_OK && intel_hdmi_can_support_frl(hdmi))
                status = intel_hdmi_frl_mode_clock_valid(connector, mode, 
sink_format);
+               if (status != MODE_OK)
+                       continue;
+
+               break;
+       }
 
        return status;
 }
@@ -2160,7 +2195,6 @@ intel_hdmi_mode_valid(struct drm_connector *_connector,
        const struct drm_display_info *info = &connector->base.display_info;
        enum drm_mode_status status;
        int clock = mode->clock;
-       int max_dotclk = display->cdclk.max_dotclk_freq;
        bool has_hdmi_sink = intel_has_hdmi_sink(hdmi, connector->base.state);
 
        status = intel_cpu_transcoder_mode_valid(display, mode);
@@ -2170,9 +2204,6 @@ intel_hdmi_mode_valid(struct drm_connector *_connector,
        if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == 
DRM_MODE_FLAG_3D_FRAME_PACKING)
                clock *= 2;
 
-       if (clock > max_dotclk)
-               return MODE_CLOCK_HIGH;
-
        if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
                if (!has_hdmi_sink)
                        return MODE_CLOCK_LOW;
@@ -2197,10 +2228,8 @@ intel_hdmi_mode_valid(struct drm_connector *_connector,
                        status = intel_hdmi_mode_valid_format(connector, mode, 
clock, has_hdmi_sink,
                                                              
INTEL_OUTPUT_FORMAT_YCBCR420);
        }
-       if (status != MODE_OK)
-               return status;
 
-       return intel_mode_valid_max_plane_size(display, mode, 1);
+       return status;
 }
 
 bool intel_hdmi_bpc_possible(const struct intel_crtc_state *crtc_state,
-- 
2.50.1

Reply via email to