aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJerry (Fangzhi) Zuo <Jerry.Zuo@amd.com>2018-10-30 14:37:16 -0400
committerAlex Deucher <alexander.deucher@amd.com>2018-11-07 18:20:56 -0500
commit0e6613e46fed29316f33acf86e1d1568288638b5 (patch)
tree6a59a30d6495243e81c80467dde6492a168c18f3
parent8be17ac95f8451b51f636622d8d4b8674334f468 (diff)
drm/amd/display: Drop reusing drm connector for MST
[why] It is not safe to keep existing connector while entire topology has been removed. Could lead potential impact to uapi. Entirely unregister all the connectors on the topology, and use a new set of connectors when the topology is plugged back on. [How] Remove the drm connector entirely each time when the corresponding MST topology is gone. When hotunplug a connector (e.g., DP2) 1. Remove connector from userspace. 2. Drop it's reference. When hotplug back on: 1. Detect new topology, and create new connectors. 2. Notify userspace with sysfs hotplug event. 3. Reprobe new connectors, and reassign CRTC from old (e.g., DP2) to new (e.g., DP3) connector. Signed-off-by: Jerry (Fangzhi) Zuo <Jerry.Zuo@amd.com> Reviewed-by: Harry Wentland <harry.wentland@amd.com> Reviewed-by: Lyude Paul <lyude@redhat.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-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.c40
2 files changed, 7 insertions, 35 deletions
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 978b34a5011c..924a38a1fc44 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -160,8 +160,6 @@ struct amdgpu_dm_connector {
160 struct mutex hpd_lock; 160 struct mutex hpd_lock;
161 161
162 bool fake_enable; 162 bool fake_enable;
163
164 bool mst_connected;
165}; 163};
166 164
167#define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base) 165#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 03e98967d6c2..31126eb23a74 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
@@ -320,25 +320,6 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
320 struct amdgpu_device *adev = dev->dev_private; 320 struct amdgpu_device *adev = dev->dev_private;
321 struct amdgpu_dm_connector *aconnector; 321 struct amdgpu_dm_connector *aconnector;
322 struct drm_connector *connector; 322 struct drm_connector *connector;
323 struct drm_connector_list_iter conn_iter;
324
325 drm_connector_list_iter_begin(dev, &conn_iter);
326 drm_for_each_connector_iter(connector, &conn_iter) {
327 aconnector = to_amdgpu_dm_connector(connector);
328 if (aconnector->mst_port == master
329 && !aconnector->port) {
330 DRM_INFO("DM_MST: reusing connector: %p [id: %d] [master: %p]\n",
331 aconnector, connector->base.id, aconnector->mst_port);
332
333 aconnector->port = port;
334 drm_connector_set_path_property(connector, pathprop);
335
336 drm_connector_list_iter_end(&conn_iter);
337 aconnector->mst_connected = true;
338 return &aconnector->base;
339 }
340 }
341 drm_connector_list_iter_end(&conn_iter);
342 323
343 aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL); 324 aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
344 if (!aconnector) 325 if (!aconnector)
@@ -387,8 +368,6 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
387 */ 368 */
388 amdgpu_dm_connector_funcs_reset(connector); 369 amdgpu_dm_connector_funcs_reset(connector);
389 370
390 aconnector->mst_connected = true;
391
392 DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n", 371 DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n",
393 aconnector, connector->base.id, aconnector->mst_port); 372 aconnector, connector->base.id, aconnector->mst_port);
394 373
@@ -400,6 +379,9 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
400static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, 379static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
401 struct drm_connector *connector) 380 struct drm_connector *connector)
402{ 381{
382 struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr);
383 struct drm_device *dev = master->base.dev;
384 struct amdgpu_device *adev = dev->dev_private;
403 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); 385 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
404 386
405 DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n", 387 DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n",
@@ -413,7 +395,10 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
413 aconnector->dc_sink = NULL; 395 aconnector->dc_sink = NULL;
414 } 396 }
415 397
416 aconnector->mst_connected = false; 398 drm_connector_unregister(connector);
399 if (adev->mode_info.rfbdev)
400 drm_fb_helper_remove_one_connector(&adev->mode_info.rfbdev->helper, connector);
401 drm_connector_put(connector);
417} 402}
418 403
419static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) 404static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
@@ -424,18 +409,10 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
424 drm_kms_helper_hotplug_event(dev); 409 drm_kms_helper_hotplug_event(dev);
425} 410}
426 411
427static void dm_dp_mst_link_status_reset(struct drm_connector *connector)
428{
429 mutex_lock(&connector->dev->mode_config.mutex);
430 drm_connector_set_link_status_property(connector, DRM_MODE_LINK_STATUS_BAD);
431 mutex_unlock(&connector->dev->mode_config.mutex);
432}
433
434static void dm_dp_mst_register_connector(struct drm_connector *connector) 412static void dm_dp_mst_register_connector(struct drm_connector *connector)
435{ 413{
436 struct drm_device *dev = connector->dev; 414 struct drm_device *dev = connector->dev;
437 struct amdgpu_device *adev = dev->dev_private; 415 struct amdgpu_device *adev = dev->dev_private;
438 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
439 416
440 if (adev->mode_info.rfbdev) 417 if (adev->mode_info.rfbdev)
441 drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector); 418 drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector);
@@ -443,9 +420,6 @@ static void dm_dp_mst_register_connector(struct drm_connector *connector)
443 DRM_ERROR("adev->mode_info.rfbdev is NULL\n"); 420 DRM_ERROR("adev->mode_info.rfbdev is NULL\n");
444 421
445 drm_connector_register(connector); 422 drm_connector_register(connector);
446
447 if (aconnector->mst_connected)
448 dm_dp_mst_link_status_reset(connector);
449} 423}
450 424
451static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { 425static const struct drm_dp_mst_topology_cbs dm_mst_cbs = {