Skip to content

Commit 18e7551

Browse files
Nicholas Kazlauskasalexdeucher
authored andcommitted
drm/amd/display: Fix DMCUB loading sequence for DCN3.2
[Why] New sequence from HW for reset and firmware reloading has been provided that aims to stabilize the reload sequence in the case the firmware is hung or has outstanding requests. [How] Update the sequence to remove the DMUIF reset and the redundant writes in the release. Reviewed-by: Sreeja Golui <sreeja.golui@amd.com> Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Signed-off-by: Ray Wu <ray.wu@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
1 parent 44343e8 commit 18e7551

File tree

2 files changed

+35
-26
lines changed

2 files changed

+35
-26
lines changed

drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -89,44 +89,50 @@ static inline void dmub_dcn32_translate_addr(const union dmub_addr *addr_in,
8989
void dmub_dcn32_reset(struct dmub_srv *dmub)
9090
{
9191
union dmub_gpint_data_register cmd;
92-
const uint32_t timeout = 30;
93-
uint32_t in_reset, scratch, i;
92+
const uint32_t timeout = 100000;
93+
uint32_t in_reset, is_enabled, scratch, i, pwait_mode;
9494

9595
REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset);
96+
REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_enabled);
9697

97-
if (in_reset == 0) {
98+
if (in_reset == 0 && is_enabled != 0) {
9899
cmd.bits.status = 1;
99100
cmd.bits.command_code = DMUB_GPINT__STOP_FW;
100101
cmd.bits.param = 0;
101102

102103
dmub->hw_funcs.set_gpint(dmub, cmd);
103104

104-
/**
105-
* Timeout covers both the ACK and the wait
106-
* for remaining work to finish.
107-
*
108-
* This is mostly bound by the PHY disable sequence.
109-
* Each register check will be greater than 1us, so
110-
* don't bother using udelay.
111-
*/
112-
113105
for (i = 0; i < timeout; ++i) {
114106
if (dmub->hw_funcs.is_gpint_acked(dmub, cmd))
115107
break;
108+
109+
udelay(1);
116110
}
117111

118112
for (i = 0; i < timeout; ++i) {
119-
scratch = dmub->hw_funcs.get_gpint_response(dmub);
113+
scratch = REG_READ(DMCUB_SCRATCH7);
120114
if (scratch == DMUB_GPINT__STOP_FW_RESPONSE)
121115
break;
116+
117+
udelay(1);
122118
}
123119

120+
for (i = 0; i < timeout; ++i) {
121+
REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &pwait_mode);
122+
if (pwait_mode & (1 << 0))
123+
break;
124+
125+
udelay(1);
126+
}
124127
/* Force reset in case we timed out, DMCUB is likely hung. */
125128
}
126129

127-
REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 1);
128-
REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0);
129-
REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1);
130+
if (is_enabled) {
131+
REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 1);
132+
udelay(1);
133+
REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0);
134+
}
135+
130136
REG_WRITE(DMCUB_INBOX1_RPTR, 0);
131137
REG_WRITE(DMCUB_INBOX1_WPTR, 0);
132138
REG_WRITE(DMCUB_OUTBOX1_RPTR, 0);
@@ -135,7 +141,7 @@ void dmub_dcn32_reset(struct dmub_srv *dmub)
135141
REG_WRITE(DMCUB_OUTBOX0_WPTR, 0);
136142
REG_WRITE(DMCUB_SCRATCH0, 0);
137143

138-
/* Clear the GPINT command manually so we don't reset again. */
144+
/* Clear the GPINT command manually so we don't send anything during boot. */
139145
cmd.all = 0;
140146
dmub->hw_funcs.set_gpint(dmub, cmd);
141147
}
@@ -419,8 +425,8 @@ uint32_t dmub_dcn32_get_current_time(struct dmub_srv *dmub)
419425

420426
void dmub_dcn32_get_diagnostic_data(struct dmub_srv *dmub)
421427
{
422-
uint32_t is_dmub_enabled, is_soft_reset, is_sec_reset;
423-
uint32_t is_traceport_enabled, is_cw0_enabled, is_cw6_enabled;
428+
uint32_t is_dmub_enabled, is_soft_reset, is_pwait;
429+
uint32_t is_traceport_enabled, is_cw6_enabled;
424430
struct dmub_timeout_info timeout = {0};
425431

426432
if (!dmub)
@@ -470,18 +476,15 @@ void dmub_dcn32_get_diagnostic_data(struct dmub_srv *dmub)
470476
REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled);
471477
dmub->debug.is_dmcub_enabled = is_dmub_enabled;
472478

479+
REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &is_pwait);
480+
dmub->debug.is_pwait = is_pwait;
481+
473482
REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &is_soft_reset);
474483
dmub->debug.is_dmcub_soft_reset = is_soft_reset;
475484

476-
REG_GET(DMCUB_SEC_CNTL, DMCUB_SEC_RESET_STATUS, &is_sec_reset);
477-
dmub->debug.is_dmcub_secure_reset = is_sec_reset;
478-
479485
REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled);
480486
dmub->debug.is_traceport_en = is_traceport_enabled;
481487

482-
REG_GET(DMCUB_REGION3_CW0_TOP_ADDRESS, DMCUB_REGION3_CW0_ENABLE, &is_cw0_enabled);
483-
dmub->debug.is_cw0_enabled = is_cw0_enabled;
484-
485488
REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled);
486489
dmub->debug.is_cw6_enabled = is_cw6_enabled;
487490

drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ struct dmub_srv;
8989
DMUB_SR(DMCUB_REGION5_OFFSET) \
9090
DMUB_SR(DMCUB_REGION5_OFFSET_HIGH) \
9191
DMUB_SR(DMCUB_REGION5_TOP_ADDRESS) \
92+
DMUB_SR(DMCUB_REGION6_OFFSET) \
93+
DMUB_SR(DMCUB_REGION6_OFFSET_HIGH) \
94+
DMUB_SR(DMCUB_REGION6_TOP_ADDRESS) \
9295
DMUB_SR(DMCUB_SCRATCH0) \
9396
DMUB_SR(DMCUB_SCRATCH1) \
9497
DMUB_SR(DMCUB_SCRATCH2) \
@@ -155,14 +158,17 @@ struct dmub_srv;
155158
DMUB_SF(DMCUB_REGION4_TOP_ADDRESS, DMCUB_REGION4_ENABLE) \
156159
DMUB_SF(DMCUB_REGION5_TOP_ADDRESS, DMCUB_REGION5_TOP_ADDRESS) \
157160
DMUB_SF(DMCUB_REGION5_TOP_ADDRESS, DMCUB_REGION5_ENABLE) \
161+
DMUB_SF(DMCUB_REGION6_TOP_ADDRESS, DMCUB_REGION6_TOP_ADDRESS) \
162+
DMUB_SF(DMCUB_REGION6_TOP_ADDRESS, DMCUB_REGION6_ENABLE) \
158163
DMUB_SF(CC_DC_PIPE_DIS, DC_DMCUB_ENABLE) \
159164
DMUB_SF(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET) \
160165
DMUB_SF(DCN_VM_FB_LOCATION_BASE, FB_BASE) \
161166
DMUB_SF(DCN_VM_FB_OFFSET, FB_OFFSET) \
162167
DMUB_SF(DMCUB_INBOX0_WPTR, DMCUB_INBOX0_WPTR) \
163168
DMUB_SF(DMCUB_REGION3_TMR_AXI_SPACE, DMCUB_REGION3_TMR_AXI_SPACE) \
164169
DMUB_SF(DMCUB_INTERRUPT_ENABLE, DMCUB_GPINT_IH_INT_EN) \
165-
DMUB_SF(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK)
170+
DMUB_SF(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK) \
171+
DMUB_SF(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS)
166172

167173
struct dmub_srv_dcn32_reg_offset {
168174
#define DMUB_SR(reg) uint32_t reg;

0 commit comments

Comments
 (0)