mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 23:22:31 +02:00
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>
This commit is contained in:
parent
44343e8b25
commit
18e755155c
|
|
@ -89,44 +89,50 @@ static inline void dmub_dcn32_translate_addr(const union dmub_addr *addr_in,
|
|||
void dmub_dcn32_reset(struct dmub_srv *dmub)
|
||||
{
|
||||
union dmub_gpint_data_register cmd;
|
||||
const uint32_t timeout = 30;
|
||||
uint32_t in_reset, scratch, i;
|
||||
const uint32_t timeout = 100000;
|
||||
uint32_t in_reset, is_enabled, scratch, i, pwait_mode;
|
||||
|
||||
REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset);
|
||||
REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_enabled);
|
||||
|
||||
if (in_reset == 0) {
|
||||
if (in_reset == 0 && is_enabled != 0) {
|
||||
cmd.bits.status = 1;
|
||||
cmd.bits.command_code = DMUB_GPINT__STOP_FW;
|
||||
cmd.bits.param = 0;
|
||||
|
||||
dmub->hw_funcs.set_gpint(dmub, cmd);
|
||||
|
||||
/**
|
||||
* Timeout covers both the ACK and the wait
|
||||
* for remaining work to finish.
|
||||
*
|
||||
* This is mostly bound by the PHY disable sequence.
|
||||
* Each register check will be greater than 1us, so
|
||||
* don't bother using udelay.
|
||||
*/
|
||||
|
||||
for (i = 0; i < timeout; ++i) {
|
||||
if (dmub->hw_funcs.is_gpint_acked(dmub, cmd))
|
||||
break;
|
||||
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < timeout; ++i) {
|
||||
scratch = dmub->hw_funcs.get_gpint_response(dmub);
|
||||
scratch = REG_READ(DMCUB_SCRATCH7);
|
||||
if (scratch == DMUB_GPINT__STOP_FW_RESPONSE)
|
||||
break;
|
||||
|
||||
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. */
|
||||
}
|
||||
|
||||
REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 1);
|
||||
REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0);
|
||||
REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1);
|
||||
if (is_enabled) {
|
||||
REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 1);
|
||||
udelay(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);
|
||||
|
|
@ -135,7 +141,7 @@ void dmub_dcn32_reset(struct dmub_srv *dmub)
|
|||
REG_WRITE(DMCUB_OUTBOX0_WPTR, 0);
|
||||
REG_WRITE(DMCUB_SCRATCH0, 0);
|
||||
|
||||
/* Clear the GPINT command manually so we don't reset again. */
|
||||
/* Clear the GPINT command manually so we don't send anything during boot. */
|
||||
cmd.all = 0;
|
||||
dmub->hw_funcs.set_gpint(dmub, cmd);
|
||||
}
|
||||
|
|
@ -419,8 +425,8 @@ uint32_t dmub_dcn32_get_current_time(struct dmub_srv *dmub)
|
|||
|
||||
void dmub_dcn32_get_diagnostic_data(struct dmub_srv *dmub)
|
||||
{
|
||||
uint32_t is_dmub_enabled, is_soft_reset, is_sec_reset;
|
||||
uint32_t is_traceport_enabled, is_cw0_enabled, is_cw6_enabled;
|
||||
uint32_t is_dmub_enabled, is_soft_reset, is_pwait;
|
||||
uint32_t is_traceport_enabled, is_cw6_enabled;
|
||||
struct dmub_timeout_info timeout = {0};
|
||||
|
||||
if (!dmub)
|
||||
|
|
@ -470,18 +476,15 @@ void dmub_dcn32_get_diagnostic_data(struct dmub_srv *dmub)
|
|||
REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled);
|
||||
dmub->debug.is_dmcub_enabled = is_dmub_enabled;
|
||||
|
||||
REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &is_pwait);
|
||||
dmub->debug.is_pwait = is_pwait;
|
||||
|
||||
REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &is_soft_reset);
|
||||
dmub->debug.is_dmcub_soft_reset = is_soft_reset;
|
||||
|
||||
REG_GET(DMCUB_SEC_CNTL, DMCUB_SEC_RESET_STATUS, &is_sec_reset);
|
||||
dmub->debug.is_dmcub_secure_reset = is_sec_reset;
|
||||
|
||||
REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled);
|
||||
dmub->debug.is_traceport_en = is_traceport_enabled;
|
||||
|
||||
REG_GET(DMCUB_REGION3_CW0_TOP_ADDRESS, DMCUB_REGION3_CW0_ENABLE, &is_cw0_enabled);
|
||||
dmub->debug.is_cw0_enabled = is_cw0_enabled;
|
||||
|
||||
REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled);
|
||||
dmub->debug.is_cw6_enabled = is_cw6_enabled;
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,9 @@ struct dmub_srv;
|
|||
DMUB_SR(DMCUB_REGION5_OFFSET) \
|
||||
DMUB_SR(DMCUB_REGION5_OFFSET_HIGH) \
|
||||
DMUB_SR(DMCUB_REGION5_TOP_ADDRESS) \
|
||||
DMUB_SR(DMCUB_REGION6_OFFSET) \
|
||||
DMUB_SR(DMCUB_REGION6_OFFSET_HIGH) \
|
||||
DMUB_SR(DMCUB_REGION6_TOP_ADDRESS) \
|
||||
DMUB_SR(DMCUB_SCRATCH0) \
|
||||
DMUB_SR(DMCUB_SCRATCH1) \
|
||||
DMUB_SR(DMCUB_SCRATCH2) \
|
||||
|
|
@ -155,6 +158,8 @@ struct dmub_srv;
|
|||
DMUB_SF(DMCUB_REGION4_TOP_ADDRESS, DMCUB_REGION4_ENABLE) \
|
||||
DMUB_SF(DMCUB_REGION5_TOP_ADDRESS, DMCUB_REGION5_TOP_ADDRESS) \
|
||||
DMUB_SF(DMCUB_REGION5_TOP_ADDRESS, DMCUB_REGION5_ENABLE) \
|
||||
DMUB_SF(DMCUB_REGION6_TOP_ADDRESS, DMCUB_REGION6_TOP_ADDRESS) \
|
||||
DMUB_SF(DMCUB_REGION6_TOP_ADDRESS, DMCUB_REGION6_ENABLE) \
|
||||
DMUB_SF(CC_DC_PIPE_DIS, DC_DMCUB_ENABLE) \
|
||||
DMUB_SF(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET) \
|
||||
DMUB_SF(DCN_VM_FB_LOCATION_BASE, FB_BASE) \
|
||||
|
|
@ -162,7 +167,8 @@ struct dmub_srv;
|
|||
DMUB_SF(DMCUB_INBOX0_WPTR, DMCUB_INBOX0_WPTR) \
|
||||
DMUB_SF(DMCUB_REGION3_TMR_AXI_SPACE, DMCUB_REGION3_TMR_AXI_SPACE) \
|
||||
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_dcn32_reg_offset {
|
||||
#define DMUB_SR(reg) uint32_t reg;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user