From: Stylon Wang <stylon.wang@xxxxxxx> [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@xxxxxxx> Acked-by: Aurabindo Pillai <aurabindo.pillai@xxxxxxx> Cc: <stable@xxxxxxxxxxxxxxx> --- .../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, -- 2.25.1