[PATCH 01/12] drm/amd/display: Fix black screen after DP/HDMI hot-plug

Aurabindo Pillai aurabindo.pillai at amd.com
Wed Oct 7 12:42:13 UTC 2020


From: Stylon Wang <stylon.wang at 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 at amd.com>
Acked-by: Aurabindo Pillai <aurabindo.pillai at amd.com>
Cc: <stable at 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,
-- 
2.25.1



More information about the amd-gfx mailing list