Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: Wait DMCUB to idle state before reset.

[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>

authored by

hengzhou and committed by
Alex Deucher
92909cde 8440f575

+11 -3
+1 -1
drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
··· 62 62 int ref_dppclk; 63 63 //int dtbclk_khz[MAX_PIPES];/* TODO needs to be removed */ 64 64 //int audio_dtbclk_khz;/* TODO needs to be removed */ 65 - //int ref_dtbclk_khz;/* TODO needs to be removed */ 65 + int ref_dtbclk_khz;/* TODO needs to be removed */ 66 66 }; 67 67 68 68 struct dtbclk_dto_params {
+8 -1
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
··· 84 84 { 85 85 union dmub_gpint_data_register cmd; 86 86 const uint32_t timeout = 100; 87 - uint32_t in_reset, scratch, i; 87 + uint32_t in_reset, scratch, i, pwait_mode; 88 88 89 89 REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset); 90 90 ··· 115 115 udelay(1); 116 116 } 117 117 118 + for (i = 0; i < timeout; ++i) { 119 + REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &pwait_mode); 120 + if (pwait_mode & (1 << 0)) 121 + break; 122 + 123 + udelay(1); 124 + } 118 125 /* Force reset in case we timed out, DMCUB is likely hung. */ 119 126 } 120 127
+2 -1
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h
··· 151 151 DMUB_SF(DCN_VM_FB_OFFSET, FB_OFFSET) \ 152 152 DMUB_SF(DMCUB_INBOX0_WPTR, DMCUB_INBOX0_WPTR) \ 153 153 DMUB_SF(DMCUB_INTERRUPT_ENABLE, DMCUB_GPINT_IH_INT_EN) \ 154 - DMUB_SF(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK) 154 + DMUB_SF(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK) \ 155 + DMUB_SF(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS) 155 156 156 157 struct dmub_srv_dcn31_reg_offset { 157 158 #define DMUB_SR(reg) uint32_t reg;