For cloned outputs, don't pick a default resolution of 1024x768 as
most hardware can do better. Instead look through the modes of all
connectors to find a common mode for all of them.

Signed-off-by: Thomas Zimmermann <[email protected]>
---
 drivers/gpu/drm/drm_client_modeset.c | 54 +++++++++++++++++-----------
 1 file changed, 34 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/drm_client_modeset.c 
b/drivers/gpu/drm/drm_client_modeset.c
index 31af5cf37a09..67b422dc8e7f 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -266,7 +266,7 @@ static bool drm_client_target_cloned(struct drm_device *dev,
 {
        int count, i, j;
        bool can_clone = false;
-       struct drm_display_mode *dmt_mode, *mode;
+       struct drm_display_mode *mode, *common_mode = NULL;
 
        /* only contemplate cloning in the single crtc case */
        if (dev->mode_config.num_crtc > 1)
@@ -309,35 +309,49 @@ static bool drm_client_target_cloned(struct drm_device 
*dev,
                return true;
        }
 
-       /* try and find a 1024x768 mode on each connector */
-       can_clone = true;
-       dmt_mode = drm_mode_find_dmt(dev, 1024, 768, 60, false);
-
-       if (!dmt_mode)
-               goto fail;
+       /* try and find a mode common among connectors */
 
+       can_clone = false;
        for (i = 0; i < connector_count; i++) {
                if (!enabled[i])
                        continue;
 
-               list_for_each_entry(mode, &connectors[i]->modes, head) {
-                       if (drm_mode_match(mode, dmt_mode,
-                                          DRM_MODE_MATCH_TIMINGS |
-                                          DRM_MODE_MATCH_CLOCK |
-                                          DRM_MODE_MATCH_FLAGS |
-                                          DRM_MODE_MATCH_3D_FLAGS))
-                               modes[i] = mode;
+               list_for_each_entry(common_mode, &connectors[i]->modes, head) {
+                       can_clone = true;
+
+                       for (j = 1; j < connector_count; j++) {
+                               if (!enabled[i])
+                                       continue;
+
+                               can_clone = false;
+                               list_for_each_entry(mode, 
&connectors[j]->modes, head) {
+                                       can_clone = drm_mode_match(common_mode, 
mode,
+                                                                  
DRM_MODE_MATCH_TIMINGS |
+                                                           
DRM_MODE_MATCH_CLOCK |
+                                                           
DRM_MODE_MATCH_FLAGS |
+                                                           
DRM_MODE_MATCH_3D_FLAGS);
+                                       if (can_clone)
+                                               break; // found common mode on 
connector
+                               }
+                               if (!can_clone)
+                                       break; // try next common mode
+                       }
+                       if (can_clone)
+                               break; // found common mode among all connectors
                }
-               if (!modes[i])
-                       can_clone = false;
+               break;
        }
-       kfree(dmt_mode);
-
        if (can_clone) {
-               drm_dbg_kms(dev, "can clone using 1024x768\n");
+               for (i = 0; i < connector_count; i++) {
+                       if (!enabled[i])
+                               continue;
+                       modes[i] = common_mode;
+
+               }
+               drm_dbg_kms(dev, "can clone using" DRM_MODE_FMT "\n", 
DRM_MODE_ARG(common_mode));
                return true;
        }
-fail:
+
        drm_info(dev, "kms: can't enable cloning when we probably wanted 
to.\n");
        return false;
 }
-- 
2.45.2

Reply via email to