From f9d376470bfb1187d53754556030188837d119f4 Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Thu, 29 Dec 2016 13:21:31 -0500 Subject: [PATCH] drm/amd/display: [MST] Fix startup sequence v3. Problem: MST topology discovery was started before fbdev init causing kernel panic on boot. Fix: Defer MST to late init hook, after fbdev strucutres already initilized. v2: Add explicit late_init hook function in DAL. v3: Change signature of detect_mst_link_for_all_connectors from void* to drm_dev* Change-Id: I288eb3ceb475907f79af1ba4357ce041930fa487 Signed-off-by: Andrey Grodzovsky Reviewed-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 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 2db54dd7a2593..e7c1935c4bbb1 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -373,27 +373,39 @@ static int dm_sw_fini(void *handle) return 0; } -static void detect_link_for_all_connectors(struct drm_device *dev) +static int detect_mst_link_for_all_connectors(struct drm_device *dev) { struct amdgpu_connector *aconnector; struct drm_connector *connector; + int ret = 0; drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); list_for_each_entry(connector, &dev->mode_config.connector_list, head) { aconnector = to_amdgpu_connector(connector); - if (aconnector->dc_link->type == dc_connection_mst_branch) { - DRM_INFO("DM_MST: starting TM on aconnector: %p [id: %d]\n", - aconnector, aconnector->base.base.id); - - if (drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, true) < 0) { - DRM_ERROR("DM_MST: Failed to start MST\n"); - ((struct dc_link *)aconnector->dc_link)->type = dc_connection_single; + if (aconnector->dc_link->type == dc_connection_mst_branch) { + DRM_INFO("DM_MST: starting TM on aconnector: %p [id: %d]\n", + aconnector, aconnector->base.base.id); + + ret = drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, true); + if (ret < 0) { + DRM_ERROR("DM_MST: Failed to start MST\n"); + ((struct dc_link *)aconnector->dc_link)->type = dc_connection_single; + return ret; } - } + } } drm_modeset_unlock(&dev->mode_config.connection_mutex); + return ret; +} + +static int dm_late_init(void *handle) +{ + struct drm_device *dev = ((struct amdgpu_device *)handle)->ddev; + int r = detect_mst_link_for_all_connectors(dev); + + return r; } static void s3_handle_mst(struct drm_device *dev, bool suspend) @@ -423,11 +435,8 @@ static int dm_hw_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; /* Create DAL display manager */ amdgpu_dm_init(adev); - amdgpu_dm_hpd_init(adev); - detect_link_for_all_connectors(adev->ddev); - return 0; } @@ -686,7 +695,7 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev ) static const struct amd_ip_funcs amdgpu_dm_funcs = { .name = "dm", .early_init = dm_early_init, - .late_init = NULL, + .late_init = dm_late_init, .sw_init = dm_sw_init, .sw_fini = dm_sw_fini, .hw_init = dm_hw_init,