aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2498-drm-amd-display-Fix-MST-daisy-chain-SST-not-light-up.patch
blob: b8cbe7dbc78d2e90b889bf0aca3c6628dc5cef15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
From ba1069b1dac576d2896eec6e731e30b1e98b750a Mon Sep 17 00:00:00 2001
From: Jerry Zuo <Jerry.Zuo@amd.com>
Date: Wed, 20 Sep 2017 15:04:52 -0400
Subject: [PATCH 2498/4131] drm/amd/display: Fix MST daisy chain SST not light
 up

In SST daisy chain scenario, edid is getting read in mst hotplug
routine. It is getting conflict with drm send_enum_path_resources
kernel thread in terms of i2c bus which is getting locked up in
such case.

Have edid being read in get_mode hook, instead of in hotplug
routine.

Signed-off-by: Jerry Zuo <Jerry.Zuo@amd.com>
Reviewed-by: Roman Li <Roman.Li@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c    | 110 +++++++++------------
 1 file changed, 49 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 0ece622..633e9b7 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -176,14 +176,60 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = {
 	.atomic_get_property = amdgpu_dm_connector_atomic_get_property
 };
 
+static int dm_connector_update_modes(struct drm_connector *connector,
+				struct edid *edid)
+{
+	int ret;
+
+	ret = drm_add_edid_modes(connector, edid);
+	drm_edid_to_eld(connector, edid);
+
+	return ret;
+}
+
 static int dm_dp_mst_get_modes(struct drm_connector *connector)
 {
 	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
 	int ret = 0;
 
-	ret = drm_add_edid_modes(&aconnector->base, aconnector->edid);
+	if (!aconnector)
+		return dm_connector_update_modes(connector, NULL);
+
+	if (!aconnector->edid) {
+		struct edid *edid;
+		struct dc_sink *dc_sink;
+		struct dc_sink_init_data init_params = {
+				.link = aconnector->dc_link,
+				.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
+		edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
 
-	drm_edid_to_eld(&aconnector->base, aconnector->edid);
+		if (!edid) {
+			drm_mode_connector_update_edid_property(
+				&aconnector->base,
+				NULL);
+			return ret;
+		}
+
+		aconnector->edid = edid;
+
+		dc_sink = dc_link_add_remote_sink(
+			aconnector->dc_link,
+			(uint8_t *)edid,
+			(edid->extensions + 1) * EDID_LENGTH,
+			&init_params);
+
+		dc_sink->priv = aconnector;
+		aconnector->dc_sink = dc_sink;
+
+		if (aconnector->dc_sink)
+			amdgpu_dm_add_sink_to_freesync_module(
+					connector, edid);
+
+		drm_mode_connector_update_edid_property(
+						&aconnector->base, edid);
+	}
+
+	ret = dm_connector_update_modes(connector, aconnector->edid);
 
 	return ret;
 }
@@ -345,66 +391,8 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
 {
 	struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr);
 	struct drm_device *dev = master->base.dev;
-	struct amdgpu_device *adev = dev->dev_private;
-	struct drm_connector *connector;
-	struct amdgpu_dm_connector *aconnector;
-	struct edid *edid;
-	struct dc_sink *dc_sink;
-
-	drm_modeset_lock_all(dev);
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		aconnector = to_amdgpu_dm_connector(connector);
-		if (aconnector->port &&
-				aconnector->port->pdt != DP_PEER_DEVICE_NONE &&
-				aconnector->port->pdt != DP_PEER_DEVICE_MST_BRANCHING &&
-				!aconnector->dc_sink) {
-			/*
-			 * This is plug in case, where port has been created but
-			 * sink hasn't been created yet
-			 */
-			if (!aconnector->edid) {
-				struct dc_sink_init_data init_params = {
-						.link = aconnector->dc_link,
-						.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST};
-				edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
-
-				if (!edid) {
-					drm_mode_connector_update_edid_property(
-						&aconnector->base,
-						NULL);
-					continue;
-				}
-
-				aconnector->edid = edid;
-
-				dc_sink = dc_link_add_remote_sink(
-					aconnector->dc_link,
-					(uint8_t *)edid,
-					(edid->extensions + 1) * EDID_LENGTH,
-					&init_params);
-
-				dc_sink->priv = aconnector;
-				aconnector->dc_sink = dc_sink;
-
-				if (aconnector->dc_sink)
-					amdgpu_dm_add_sink_to_freesync_module(
-							connector,
-							edid);
-
-				dm_restore_drm_connector_state(connector->dev, connector);
-			} else
-				edid = aconnector->edid;
-
-			DRM_DEBUG_KMS("edid retrieved %p\n", edid);
-
-			drm_mode_connector_update_edid_property(
-				&aconnector->base,
-				aconnector->edid);
-		}
-	}
-	drm_modeset_unlock_all(dev);
 
-	schedule_work(&adev->dm.mst_hotplug_work);
+	drm_kms_helper_hotplug_event(dev);
 }
 
 static void dm_dp_mst_register_connector(struct drm_connector *connector)
-- 
2.7.4