[PATCH 035/103] drm/amd/display: Fix MST daisy chain SST not light up
Harry Wentland
harry.wentland at amd.com
Tue Oct 10 22:40:04 UTC 2017
From: Jerry Zuo <Jerry.Zuo at amd.com>
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 at amd.com>
Reviewed-by: Roman Li <Roman.Li at amd.com>
Acked-by: Harry Wentland <Harry.Wentland at 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 343645e4070b..11a10c1c0adb 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
@@ -172,14 +172,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;
}
@@ -341,66 +387,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.14.1
More information about the amd-gfx
mailing list