aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJerry (Fangzhi) Zuo <Jerry.Zuo@amd.com>2017-12-01 13:26:05 -0500
committerAlex Deucher <alexander.deucher@amd.com>2017-12-20 14:46:38 -0500
commit391ef035200f8c3c808fcb91deb86e605419caa7 (patch)
tree45bb2348eb95f14be685f0ab6e720a8759a1a03b
parent23bfb33181d2af0109672b5f25f542378e7a01b1 (diff)
drm/amd/display: Fix rehook MST display not light back on
Original applied dm_restore_drm_connector_state() has got removed. Set link status to BAD before hotplug() event could trigger another modeset from userspace. The fix "Fix MST daisy chain SST not light up" commit makes so it is trying to create a stream prior to dc_sink. That makes dc_sink is not present in create_stream_for_sink(). Signed-off-by: Jerry (Fangzhi) Zuo <Jerry.Zuo@amd.com> Reviewed-by: Roman Li <Roman.Li@amd.com> Acked-by: Harry Wentland <harry.wentland@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c13
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h2
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c51
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h1
4 files changed, 62 insertions, 5 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 232c7ea7baa8..1ce4c98385e3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2351,7 +2351,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
2351 const struct dm_connector_state *dm_state) 2351 const struct dm_connector_state *dm_state)
2352{ 2352{
2353 struct drm_display_mode *preferred_mode = NULL; 2353 struct drm_display_mode *preferred_mode = NULL;
2354 const struct drm_connector *drm_connector; 2354 struct drm_connector *drm_connector;
2355 struct dc_stream_state *stream = NULL; 2355 struct dc_stream_state *stream = NULL;
2356 struct drm_display_mode mode = *drm_mode; 2356 struct drm_display_mode mode = *drm_mode;
2357 bool native_mode_found = false; 2357 bool native_mode_found = false;
@@ -2370,11 +2370,13 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
2370 2370
2371 if (!aconnector->dc_sink) { 2371 if (!aconnector->dc_sink) {
2372 /* 2372 /*
2373 * Exclude MST from creating fake_sink 2373 * Create dc_sink when necessary to MST
2374 * TODO: need to enable MST into fake_sink feature 2374 * Don't apply fake_sink to MST
2375 */ 2375 */
2376 if (aconnector->mst_port) 2376 if (aconnector->mst_port) {
2377 goto stream_create_fail; 2377 dm_dp_mst_dc_sink_create(drm_connector);
2378 goto mst_dc_sink_create_done;
2379 }
2378 2380
2379 if (create_fake_sink(aconnector)) 2381 if (create_fake_sink(aconnector))
2380 goto stream_create_fail; 2382 goto stream_create_fail;
@@ -2425,6 +2427,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
2425stream_create_fail: 2427stream_create_fail:
2426dm_state_null: 2428dm_state_null:
2427drm_connector_null: 2429drm_connector_null:
2430mst_dc_sink_create_done:
2428 return stream; 2431 return stream;
2429} 2432}
2430 2433
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 8a1e4f5dbd64..2faa77a7eeda 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -189,6 +189,8 @@ struct amdgpu_dm_connector {
189 struct mutex hpd_lock; 189 struct mutex hpd_lock;
190 190
191 bool fake_enable; 191 bool fake_enable;
192
193 bool mst_connected;
192}; 194};
193 195
194#define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base) 196#define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base)
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 707928b88448..f3d87f418d2e 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
@@ -180,6 +180,42 @@ static int dm_connector_update_modes(struct drm_connector *connector,
180 return drm_add_edid_modes(connector, edid); 180 return drm_add_edid_modes(connector, edid);
181} 181}
182 182
183void dm_dp_mst_dc_sink_create(struct drm_connector *connector)
184{
185 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
186 struct edid *edid;
187 struct dc_sink *dc_sink;
188 struct dc_sink_init_data init_params = {
189 .link = aconnector->dc_link,
190 .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
191
192 edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
193
194 if (!edid) {
195 drm_mode_connector_update_edid_property(
196 &aconnector->base,
197 NULL);
198 return;
199 }
200
201 aconnector->edid = edid;
202
203 dc_sink = dc_link_add_remote_sink(
204 aconnector->dc_link,
205 (uint8_t *)aconnector->edid,
206 (aconnector->edid->extensions + 1) * EDID_LENGTH,
207 &init_params);
208
209 dc_sink->priv = aconnector;
210 aconnector->dc_sink = dc_sink;
211
212 amdgpu_dm_add_sink_to_freesync_module(
213 connector, aconnector->edid);
214
215 drm_mode_connector_update_edid_property(
216 &aconnector->base, aconnector->edid);
217}
218
183static int dm_dp_mst_get_modes(struct drm_connector *connector) 219static int dm_dp_mst_get_modes(struct drm_connector *connector)
184{ 220{
185 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); 221 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
@@ -306,6 +342,7 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
306 drm_mode_connector_set_path_property(connector, pathprop); 342 drm_mode_connector_set_path_property(connector, pathprop);
307 343
308 drm_connector_list_iter_end(&conn_iter); 344 drm_connector_list_iter_end(&conn_iter);
345 aconnector->mst_connected = true;
309 return &aconnector->base; 346 return &aconnector->base;
310 } 347 }
311 } 348 }
@@ -358,6 +395,8 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
358 */ 395 */
359 amdgpu_dm_connector_funcs_reset(connector); 396 amdgpu_dm_connector_funcs_reset(connector);
360 397
398 aconnector->mst_connected = true;
399
361 DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n", 400 DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n",
362 aconnector, connector->base.id, aconnector->mst_port); 401 aconnector, connector->base.id, aconnector->mst_port);
363 402
@@ -389,6 +428,8 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
389 drm_mode_connector_update_edid_property( 428 drm_mode_connector_update_edid_property(
390 &aconnector->base, 429 &aconnector->base,
391 NULL); 430 NULL);
431
432 aconnector->mst_connected = false;
392} 433}
393 434
394static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) 435static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
@@ -399,10 +440,18 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
399 drm_kms_helper_hotplug_event(dev); 440 drm_kms_helper_hotplug_event(dev);
400} 441}
401 442
443static void dm_dp_mst_link_status_reset(struct drm_connector *connector)
444{
445 mutex_lock(&connector->dev->mode_config.mutex);
446 drm_mode_connector_set_link_status_property(connector, DRM_MODE_LINK_STATUS_BAD);
447 mutex_unlock(&connector->dev->mode_config.mutex);
448}
449
402static void dm_dp_mst_register_connector(struct drm_connector *connector) 450static void dm_dp_mst_register_connector(struct drm_connector *connector)
403{ 451{
404 struct drm_device *dev = connector->dev; 452 struct drm_device *dev = connector->dev;
405 struct amdgpu_device *adev = dev->dev_private; 453 struct amdgpu_device *adev = dev->dev_private;
454 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
406 455
407 if (adev->mode_info.rfbdev) 456 if (adev->mode_info.rfbdev)
408 drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector); 457 drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector);
@@ -411,6 +460,8 @@ static void dm_dp_mst_register_connector(struct drm_connector *connector)
411 460
412 drm_connector_register(connector); 461 drm_connector_register(connector);
413 462
463 if (aconnector->mst_connected)
464 dm_dp_mst_link_status_reset(connector);
414} 465}
415 466
416static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { 467static const struct drm_dp_mst_topology_cbs dm_mst_cbs = {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
index 2da851b40042..8cf51da26657 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
@@ -31,5 +31,6 @@ struct amdgpu_dm_connector;
31 31
32void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, 32void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
33 struct amdgpu_dm_connector *aconnector); 33 struct amdgpu_dm_connector *aconnector);
34void dm_dp_mst_dc_sink_create(struct drm_connector *connector);
34 35
35#endif 36#endif