]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd/display: Add common modes to analog displays without EDID
authorTimur Kristóf <timur.kristof@gmail.com>
Fri, 26 Sep 2025 18:02:01 +0000 (20:02 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 28 Oct 2025 14:10:05 +0000 (10:10 -0400)
When the EDID of an analog display is not available, we can't
know the possible modes supported by the display. However, we
still need to offer the user to select from a variety of common
modes. It will be up to the user to select the best one, though.

This is how it works on other operating systems as well as the
legacy display code path in amdgpu.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

index a235a5b611860826d2bddeb7dccf275dbc22a66d..dc091ccab46e2f094737b0c7dd982e3d552edc35 100644 (file)
@@ -8412,7 +8412,7 @@ static void amdgpu_dm_get_native_mode(struct drm_connector *connector)
 
 static struct drm_display_mode *
 amdgpu_dm_create_common_mode(struct drm_encoder *encoder,
-                            char *name,
+                            const char *name,
                             int hdisplay, int vdisplay)
 {
        struct drm_device *dev = encoder->dev;
@@ -8434,6 +8434,24 @@ amdgpu_dm_create_common_mode(struct drm_encoder *encoder,
 
 }
 
+static const struct amdgpu_dm_mode_size {
+       char name[DRM_DISPLAY_MODE_LEN];
+       int w;
+       int h;
+} common_modes[] = {
+       {  "640x480",  640,  480},
+       {  "800x600",  800,  600},
+       { "1024x768", 1024,  768},
+       { "1280x720", 1280,  720},
+       { "1280x800", 1280,  800},
+       {"1280x1024", 1280, 1024},
+       { "1440x900", 1440,  900},
+       {"1680x1050", 1680, 1050},
+       {"1600x1200", 1600, 1200},
+       {"1920x1080", 1920, 1080},
+       {"1920x1200", 1920, 1200}
+};
+
 static void amdgpu_dm_connector_add_common_modes(struct drm_encoder *encoder,
                                                 struct drm_connector *connector)
 {
@@ -8444,23 +8462,6 @@ static void amdgpu_dm_connector_add_common_modes(struct drm_encoder *encoder,
                                to_amdgpu_dm_connector(connector);
        int i;
        int n;
-       struct mode_size {
-               char name[DRM_DISPLAY_MODE_LEN];
-               int w;
-               int h;
-       } common_modes[] = {
-               {  "640x480",  640,  480},
-               {  "800x600",  800,  600},
-               { "1024x768", 1024,  768},
-               { "1280x720", 1280,  720},
-               { "1280x800", 1280,  800},
-               {"1280x1024", 1280, 1024},
-               { "1440x900", 1440,  900},
-               {"1680x1050", 1680, 1050},
-               {"1600x1200", 1600, 1200},
-               {"1920x1080", 1920, 1080},
-               {"1920x1200", 1920, 1200}
-       };
 
        if ((connector->connector_type != DRM_MODE_CONNECTOR_eDP) &&
            (connector->connector_type != DRM_MODE_CONNECTOR_LVDS))
@@ -8684,6 +8685,15 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
                if (dc->link_srv->dp_get_encoding_format(verified_link_cap) == DP_128b_132b_ENCODING)
                        amdgpu_dm_connector->num_modes +=
                                drm_add_modes_noedid(connector, 1920, 1080);
+
+               if (amdgpu_dm_connector->dc_sink->edid_caps.analog) {
+                       /* Analog monitor connected by DAC load detection.
+                        * Add common modes. It will be up to the user to select one that works.
+                        */
+                       for (int i = 0; i < ARRAY_SIZE(common_modes); i++)
+                               amdgpu_dm_connector->num_modes += drm_add_modes_noedid(
+                                       connector, common_modes[i].w, common_modes[i].h);
+               }
        } else {
                amdgpu_dm_connector_ddc_get_modes(connector, drm_edid);
                if (encoder)