@@ -89,44 +89,50 @@ static inline void dmub_dcn32_translate_addr(const union dmub_addr *addr_in,
8989void 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
420426void 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
0 commit comments