[PATCH 5/5] drm/amd/display: Make DMUB auto-load failures fatal
Mario Limonciello
mario.limonciello at amd.com
Fri Nov 15 06:09:24 UTC 2024
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 at amd.com>
---
.../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
More information about the amd-gfx
mailing list