drm/amd/display: Increase halt timeout for DMCUB to 1s
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Thu, 13 Feb 2025 22:40:29 +0000 (17:40 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 25 Feb 2025 16:45:11 +0000 (11:45 -0500)
[Why]
If we soft reset before halt finishes and there are outstanding
memory transactions then the memory interface may produce unexpected
results, such as out of order transactions when the firmware next runs.

These can manifest as random or unexpected load/store violations.

[How]
Increase the timeout before soft reset to ensure the DMCUB has quiesced.

Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Zaeem Mohamed <zaeem.mohamed@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c

index 3d0bba602b53a7e308b9d3bfc26628ce200b232a..1fac75dfc650c9a218b6d0466ad2ce18a53d5b4b 100644 (file)
@@ -83,8 +83,8 @@ static inline void dmub_dcn31_translate_addr(const union dmub_addr *addr_in,
 void dmub_dcn31_reset(struct dmub_srv *dmub)
 {
        union dmub_gpint_data_register cmd;
-       const uint32_t timeout = 100;
-       uint32_t in_reset, scratch, i, pwait_mode;
+       const uint32_t timeout = 1000000;
+       uint32_t in_reset, is_enabled, scratch, i, pwait_mode;
 
        REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset);
 
@@ -125,9 +125,14 @@ void dmub_dcn31_reset(struct dmub_srv *dmub)
                /* Force reset in case we timed out, DMCUB is likely hung. */
        }
 
-       REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 1);
-       REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0);
-       REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1);
+       REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_enabled);
+
+       if (is_enabled) {
+               REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 1);
+               REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1);
+               REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0);
+       }
+
        REG_WRITE(DMCUB_INBOX1_RPTR, 0);
        REG_WRITE(DMCUB_INBOX1_WPTR, 0);
        REG_WRITE(DMCUB_OUTBOX1_RPTR, 0);
index e5e77bd3c31ea1b569d9d8574c0f9f49ef44a731..652173b10401d32869469c6062c5a7a37d110e02 100644 (file)
@@ -88,7 +88,7 @@ static inline void dmub_dcn35_translate_addr(const union dmub_addr *addr_in,
 void dmub_dcn35_reset(struct dmub_srv *dmub)
 {
        union dmub_gpint_data_register cmd;
-       const uint32_t timeout = 100;
+       const uint32_t timeout = 1000000;
        uint32_t in_reset, is_enabled, scratch, i, pwait_mode;
 
        REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset);