From: Fangzhi Zuo <[email protected]>

[Why]
Selecting an unadvertised custom mode without scaling can send an
unsupported timing directly to the display.

[How]
Post a warning when this selection is made and advise to choose an
advertised/native mode when visual defect is observed.

Reviewed-by: Roman Li <[email protected]>
Signed-off-by: Fangzhi Zuo <[email protected]>
Signed-off-by: Ray Wu <[email protected]>
---
 .../display/amdgpu_dm/amdgpu_dm_connector.c   | 36 ++++++++++++-------
 .../display/amdgpu_dm/amdgpu_dm_connector.h   |  2 +-
 2 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
index 2ef1483869f9..324634e9cb16 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
@@ -1397,6 +1397,21 @@ static void apply_dsc_policy_for_stream(struct 
amdgpu_dm_connector *aconnector,
 }
 #endif
 
+STATIC_IFN_KUNIT bool is_duplicate_mode(struct amdgpu_dm_connector *aconnector,
+                                       const struct drm_display_mode *mode)
+{
+       struct drm_display_mode *m;
+
+       list_for_each_entry(m, &aconnector->base.probed_modes, head) {
+               if (drm_mode_equal(m, mode))
+                       return true;
+       }
+
+       return false;
+}
+
+EXPORT_IF_KUNIT(is_duplicate_mode);
+
 void amdgpu_dm_update_stream_scaling_settings(struct drm_device *dev,
                                           const struct drm_display_mode *mode,
                                           const struct dm_connector_state 
*dm_state,
@@ -1473,6 +1488,7 @@ create_stream_for_sink(struct drm_connector *connector,
        struct drm_display_mode *freesync_mode = NULL;
        bool native_mode_found = false;
        bool recalculate_timing = false;
+       bool unadvertised_mode = false;
        bool scale = dm_state->scaling != RMX_OFF;
        int mode_refresh;
        int preferred_refresh = 0;
@@ -1559,6 +1575,13 @@ create_stream_for_sink(struct drm_connector *connector,
                                        &mode, preferred_mode, scale);
 
                        preferred_refresh = drm_mode_vrefresh(preferred_mode);
+                       unadvertised_mode = !is_duplicate_mode(aconnector, 
drm_mode);
+
+                       if (unadvertised_mode && dm_state->scaling == RMX_OFF)
+                               drm_dbg_driver(dev,
+                                              "Unadvertised mode %dx%d@%d with 
RMX_OFF\n",
+                                              drm_mode->hdisplay, 
drm_mode->vdisplay,
+                                              drm_mode_vrefresh(drm_mode));
                }
        }
 
@@ -2961,19 +2984,6 @@ STATIC_IFN_KUNIT void 
amdgpu_dm_connector_ddc_get_modes(struct drm_connector *co
 }
 EXPORT_IF_KUNIT(amdgpu_dm_connector_ddc_get_modes);
 
-STATIC_IFN_KUNIT bool is_duplicate_mode(struct amdgpu_dm_connector *aconnector,
-                             struct drm_display_mode *mode)
-{
-       struct drm_display_mode *m;
-
-       list_for_each_entry(m, &aconnector->base.probed_modes, head) {
-               if (drm_mode_equal(m, mode))
-                       return true;
-       }
-
-       return false;
-}
-EXPORT_IF_KUNIT(is_duplicate_mode);
 
 STATIC_IFN_KUNIT uint add_fs_modes(struct amdgpu_dm_connector *aconnector)
 {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.h
index 79698deacf61..7bfbb6853833 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.h
@@ -214,7 +214,7 @@ bool adjust_colour_depth_from_display_info(struct 
dc_crtc_timing *timing_out,
                                           const struct drm_display_info *info);
 
 int to_drm_connector_type(enum signal_type st, uint32_t connector_id);
-bool is_duplicate_mode(struct amdgpu_dm_connector *aconnector, struct 
drm_display_mode *mode);
+bool is_duplicate_mode(struct amdgpu_dm_connector *aconnector, const struct 
drm_display_mode *mode);
 enum dc_aspect_ratio get_aspect_ratio(const struct drm_display_mode *mode_in);
 void copy_crtc_timing_for_drm_display_mode(const struct drm_display_mode 
*src_mode,
                                           struct drm_display_mode *dst_mode);
-- 
2.43.0

Reply via email to