drm/amd/display: Wait DMCUB to idle state before reset.
authorhengzhou <Hengyong.Zhou@amd.com>
Sat, 7 May 2022 01:43:08 +0000 (09:43 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 1 Jun 2022 19:56:48 +0000 (15:56 -0400)
[WHY]
Very low rate to cause memory access issue while resetting
DMCUB after the halt command was sent to it.
The process of stopping fw of DMCUB may be timeout, that means
it is not in idle state, such as the window frames may still be
kept in cache, so reset by force will cause MMHUB hang.

[HOW]
After the halt command was sent, keep checking the DMCUB state until
it is idle.

Reviewed-by: Eric Yang <Eric.Yang2@amd.com>
Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Jasdeep Dhillon <jdhillon@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: hengzhou <Hengyong.Zhou@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h

index 4c880b6..c702191 100644 (file)
@@ -62,7 +62,7 @@ struct dccg {
        int ref_dppclk;
        //int dtbclk_khz[MAX_PIPES];/* TODO needs to be removed */
        //int audio_dtbclk_khz;/* TODO needs to be removed */
-       //int ref_dtbclk_khz;/* TODO needs to be removed */
+       int ref_dtbclk_khz;/* TODO needs to be removed */
 };
 
 struct dtbclk_dto_params {
index 7c9330a..8d45748 100644 (file)
@@ -84,7 +84,7 @@ 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;
+       uint32_t in_reset, scratch, i, pwait_mode;
 
        REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset);
 
@@ -115,6 +115,13 @@ void dmub_dcn31_reset(struct dmub_srv *dmub)
                        udelay(1);
                }
 
+               for (i = 0; i < timeout; ++i) {
+                       REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &pwait_mode);
+                       if (pwait_mode & (1 << 0))
+                               break;
+
+                       udelay(1);
+               }
                /* Force reset in case we timed out, DMCUB is likely hung. */
        }
 
index 59ddc81..f6db6f8 100644 (file)
@@ -151,7 +151,8 @@ struct dmub_srv;
        DMUB_SF(DCN_VM_FB_OFFSET, FB_OFFSET) \
        DMUB_SF(DMCUB_INBOX0_WPTR, DMCUB_INBOX0_WPTR) \
        DMUB_SF(DMCUB_INTERRUPT_ENABLE, DMCUB_GPINT_IH_INT_EN) \
-       DMUB_SF(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK)
+       DMUB_SF(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK) \
+       DMUB_SF(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS)
 
 struct dmub_srv_dcn31_reg_offset {
 #define DMUB_SR(reg) uint32_t reg;