From: Stylon Wang stylon.wang@amd.com
[Why] When restoring connector state we relies on drm_connector->status to check if the connector with matching crtc is connected. But that status is only updated later when user space calls DRM_IOCTL_MODE_GETCONNECTOR and then calls fillsmodes(). This causes connectors being incorrectly reported as not connected when we hot-plug the cable.
[How] Instead of checking drm_connector->status directly, use helper amdgpu_dm_connector_detect() to check for connectivity.
Signed-off-by: Stylon Wang stylon.wang@amd.com Acked-by: Aurabindo Pillai aurabindo.pillai@amd.com Cc: stable@vger.kernel.org --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 3cf4e08931bb..dfcea66ee23c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1735,25 +1735,6 @@ static int dm_suspend(void *handle) return 0; }
-static struct amdgpu_dm_connector * -amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state, - struct drm_crtc *crtc) -{ - uint32_t i; - struct drm_connector_state *new_con_state; - struct drm_connector *connector; - struct drm_crtc *crtc_from_state; - - for_each_new_connector_in_state(state, connector, new_con_state, i) { - crtc_from_state = new_con_state->crtc; - - if (crtc_from_state == crtc) - return to_amdgpu_dm_connector(connector); - } - - return NULL; -} - static void emulated_link_detect(struct dc_link *link) { struct dc_sink_init_data sink_init_data = { 0 }; @@ -5003,7 +4984,8 @@ amdgpu_dm_connector_detect(struct drm_connector *connector, bool force) !aconnector->fake_enable) connected = (aconnector->dc_sink != NULL); else - connected = (aconnector->base.force == DRM_FORCE_ON); + connected = (aconnector->base.force == DRM_FORCE_ON || + aconnector->base.force == DRM_FORCE_ON_DIGITAL);
return (connected ? connector_status_connected : connector_status_disconnected); @@ -8090,6 +8072,29 @@ static void reset_freesync_config_for_crtc( sizeof(new_crtc_state->vrr_infopacket)); }
+static struct amdgpu_dm_connector * +amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state, + struct drm_crtc *crtc) +{ + uint32_t i; + struct drm_connector_state *new_con_state; + struct drm_connector *connector; + struct drm_crtc *crtc_from_state; + + for_each_new_connector_in_state(state, connector, new_con_state, i) { + struct amdgpu_dm_connector *aconnector = + to_amdgpu_dm_connector(connector); + crtc_from_state = new_con_state->crtc; + + if (crtc_from_state == crtc + && connector != NULL + && amdgpu_dm_connector_detect(connector, false) == connector_status_connected) + return aconnector; + } + + return NULL; +} + static int dm_update_crtc_state(struct amdgpu_display_manager *dm, struct drm_atomic_state *state, struct drm_crtc *crtc,
linux-stable-mirror@lists.linaro.org