Realistically when these happen the driver is in a pretty bad state. Future calls later in the driver such as dm_read_reg_func() can hang causing soft lockups on CPUs and never letting the module load finish. If one of these problems happens abort the hw init or resume sequence. Signed-off-by: Mario Limonciello <mario.limonciello@xxxxxxx> --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 41 ++++++++++++------- 1 file changed, 27 insertions(+), 14 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 95807d035a153..e7ebc26070d6b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1291,8 +1291,10 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) /* Wait for firmware load to finish. */ status = dmub_srv_wait_for_auto_load(dmub_srv, 100000); - if (status != DMUB_STATUS_OK) - DRM_WARN("Wait for DMUB auto-load failed: %d\n", status); + if (status != DMUB_STATUS_OK) { + drm_err(adev->dm.ddev, "Wait for DMUB auto-load failed: %d\n", status); + return -EINVAL; + } /* Init DMCU and ABM if available. */ if (dmcu && abm) { @@ -1336,7 +1338,7 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) return 0; } -static void dm_dmub_hw_resume(struct amdgpu_device *adev) +static int dm_dmub_hw_resume(struct amdgpu_device *adev) { struct dmub_srv *dmub_srv = adev->dm.dmub_srv; enum dmub_status status; @@ -1345,24 +1347,30 @@ static void dm_dmub_hw_resume(struct amdgpu_device *adev) if (!dmub_srv) { /* DMUB isn't supported on the ASIC. */ - return; + return 0; } status = dmub_srv_is_hw_init(dmub_srv, &init); if (status != DMUB_STATUS_OK) - DRM_WARN("DMUB hardware init check failed: %d\n", status); + drm_warn(adev->dm.ddev, "DMUB hardware init check failed: %d\n", status); if (status == DMUB_STATUS_OK && init) { /* Wait for firmware load to finish. */ status = dmub_srv_wait_for_auto_load(dmub_srv, 100000); - if (status != DMUB_STATUS_OK) - DRM_WARN("Wait for DMUB auto-load failed: %d\n", status); - } else { - /* Perform the full hardware initialization. */ - r = dm_dmub_hw_init(adev); - if (r) - DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r); + if (status != DMUB_STATUS_OK) { + drm_err(adev->dm.ddev, "Wait for DMUB auto-load failed: %d\n", status); + return -EINVAL; + } + + return 0; } + + /* Perform the full hardware initialization. */ + r = dm_dmub_hw_init(adev); + if (r) + drm_err(adev->dm.ddev, "DMUB interface failed to initialize: status=%d\n", r); + + return r; } static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_addr_space_config *pa_config) @@ -3244,9 +3252,12 @@ static int dm_resume(struct amdgpu_ip_block *ip_block) link_enc_cfg_copy(adev->dm.dc->current_state, dc_state); r = dm_dmub_hw_init(adev); - if (r) + + if (r) { drm_err(adev->dm.ddev, "DMUB interface failed to initialize: status=%d\n", r); + return r; + } dc_dmub_srv_set_power_state(dm->dc->ctx->dmub_srv, DC_ACPI_CM_POWER_STATE_D0); dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0); @@ -3292,7 +3303,9 @@ static int dm_resume(struct amdgpu_ip_block *ip_block) /* TODO: Remove dc_state->dccg, use dc->dccg directly. */ /* Before powering on DC we need to re-initialize DMUB. */ - dm_dmub_hw_resume(adev); + r = dm_dmub_hw_resume(adev); + if (r) + return r; /* Re-enable outbox interrupts for DPIA. */ if (dc_is_dmub_outbox_supported(adev->dm.dc)) { -- 2.43.0