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 <[email protected]>
---
 .../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

Reply via email to