Skip to content

Commit

Permalink
drm/amd/display: Drop reusing drm connector for MST
Browse files Browse the repository at this point in the history
[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 <[email protected]>
Reviewed-by: Harry Wentland <[email protected]>
Reviewed-by: Lyude Paul <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
  • Loading branch information
Jerry (Fangzhi) Zuo authored and alexdeucher committed Nov 7, 2018
1 parent 8be17ac commit 0e6613e
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 35 deletions.
2 changes: 0 additions & 2 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,6 @@ struct amdgpu_dm_connector {
struct mutex hpd_lock;

bool fake_enable;

bool mst_connected;
};

#define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base)
Expand Down
40 changes: 7 additions & 33 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,25 +320,6 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
struct amdgpu_device *adev = dev->dev_private;
struct amdgpu_dm_connector *aconnector;
struct drm_connector *connector;
struct drm_connector_list_iter conn_iter;

drm_connector_list_iter_begin(dev, &conn_iter);
drm_for_each_connector_iter(connector, &conn_iter) {
aconnector = to_amdgpu_dm_connector(connector);
if (aconnector->mst_port == master
&& !aconnector->port) {
DRM_INFO("DM_MST: reusing connector: %p [id: %d] [master: %p]\n",
aconnector, connector->base.id, aconnector->mst_port);

aconnector->port = port;
drm_connector_set_path_property(connector, pathprop);

drm_connector_list_iter_end(&conn_iter);
aconnector->mst_connected = true;
return &aconnector->base;
}
}
drm_connector_list_iter_end(&conn_iter);

aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
if (!aconnector)
Expand Down Expand Up @@ -387,8 +368,6 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
*/
amdgpu_dm_connector_funcs_reset(connector);

aconnector->mst_connected = true;

DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n",
aconnector, connector->base.id, aconnector->mst_port);

Expand All @@ -400,6 +379,9 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
struct drm_connector *connector)
{
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 amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);

DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n",
Expand All @@ -413,7 +395,10 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
aconnector->dc_sink = NULL;
}

aconnector->mst_connected = false;
drm_connector_unregister(connector);
if (adev->mode_info.rfbdev)
drm_fb_helper_remove_one_connector(&adev->mode_info.rfbdev->helper, connector);
drm_connector_put(connector);
}

static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
Expand All @@ -424,28 +409,17 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
drm_kms_helper_hotplug_event(dev);
}

static void dm_dp_mst_link_status_reset(struct drm_connector *connector)
{
mutex_lock(&connector->dev->mode_config.mutex);
drm_connector_set_link_status_property(connector, DRM_MODE_LINK_STATUS_BAD);
mutex_unlock(&connector->dev->mode_config.mutex);
}

static void dm_dp_mst_register_connector(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct amdgpu_device *adev = dev->dev_private;
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);

if (adev->mode_info.rfbdev)
drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector);
else
DRM_ERROR("adev->mode_info.rfbdev is NULL\n");

drm_connector_register(connector);

if (aconnector->mst_connected)
dm_dp_mst_link_status_reset(connector);
}

static const struct drm_dp_mst_topology_cbs dm_mst_cbs = {
Expand Down

0 comments on commit 0e6613e

Please sign in to comment.