diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dmub/src')
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c | 85 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c | 111 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c | 98 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c | 97 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn36.c | 34 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn36.h | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c | 144 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c | 19 |
14 files changed, 351 insertions, 264 deletions
diff --git a/drivers/gpu/drm/amd/display/dmub/src/Makefile b/drivers/gpu/drm/amd/display/dmub/src/Makefile index a00b9e992292..468b768c11ae 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/Makefile +++ b/drivers/gpu/drm/amd/display/dmub/src/Makefile @@ -26,6 +26,7 @@ DMUB += dmub_dcn31.o dmub_dcn314.o dmub_dcn315.o dmub_dcn316.o DMUB += dmub_dcn32.o DMUB += dmub_dcn35.o DMUB += dmub_dcn351.o +DMUB += dmub_dcn36.o DMUB += dmub_dcn401.o AMD_DAL_DMUB = $(addprefix $(AMDDALPATH)/dmub/src/,$(DMUB)) diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c index e500ca9ae09c..73888c1bea93 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c @@ -414,63 +414,66 @@ uint32_t dmub_dcn20_get_current_time(struct dmub_srv *dmub) return REG_READ(DMCUB_TIMER_CURRENT); } -void dmub_dcn20_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data) +void dmub_dcn20_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; + struct dmub_timeout_info timeout = {0}; - if (!dmub || !diag_data) + if (!dmub) return; - memset(diag_data, 0, sizeof(*diag_data)); - - diag_data->dmcub_version = dmub->fw_version; - - diag_data->scratch[0] = REG_READ(DMCUB_SCRATCH0); - diag_data->scratch[1] = REG_READ(DMCUB_SCRATCH1); - diag_data->scratch[2] = REG_READ(DMCUB_SCRATCH2); - diag_data->scratch[3] = REG_READ(DMCUB_SCRATCH3); - diag_data->scratch[4] = REG_READ(DMCUB_SCRATCH4); - diag_data->scratch[5] = REG_READ(DMCUB_SCRATCH5); - diag_data->scratch[6] = REG_READ(DMCUB_SCRATCH6); - diag_data->scratch[7] = REG_READ(DMCUB_SCRATCH7); - diag_data->scratch[8] = REG_READ(DMCUB_SCRATCH8); - diag_data->scratch[9] = REG_READ(DMCUB_SCRATCH9); - diag_data->scratch[10] = REG_READ(DMCUB_SCRATCH10); - diag_data->scratch[11] = REG_READ(DMCUB_SCRATCH11); - diag_data->scratch[12] = REG_READ(DMCUB_SCRATCH12); - diag_data->scratch[13] = REG_READ(DMCUB_SCRATCH13); - diag_data->scratch[14] = REG_READ(DMCUB_SCRATCH14); - diag_data->scratch[15] = REG_READ(DMCUB_SCRATCH15); - - diag_data->undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); - diag_data->inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); - diag_data->data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); - - diag_data->inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); - diag_data->inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); - diag_data->inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); - - diag_data->inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); - diag_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); - diag_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); + /* timeout data filled externally, cache before resetting memory */ + timeout = dmub->debug.timeout_info; + memset(&dmub->debug, 0, sizeof(dmub->debug)); + dmub->debug.timeout_info = timeout; + + dmub->debug.dmcub_version = dmub->fw_version; + + dmub->debug.scratch[0] = REG_READ(DMCUB_SCRATCH0); + dmub->debug.scratch[1] = REG_READ(DMCUB_SCRATCH1); + dmub->debug.scratch[2] = REG_READ(DMCUB_SCRATCH2); + dmub->debug.scratch[3] = REG_READ(DMCUB_SCRATCH3); + dmub->debug.scratch[4] = REG_READ(DMCUB_SCRATCH4); + dmub->debug.scratch[5] = REG_READ(DMCUB_SCRATCH5); + dmub->debug.scratch[6] = REG_READ(DMCUB_SCRATCH6); + dmub->debug.scratch[7] = REG_READ(DMCUB_SCRATCH7); + dmub->debug.scratch[8] = REG_READ(DMCUB_SCRATCH8); + dmub->debug.scratch[9] = REG_READ(DMCUB_SCRATCH9); + dmub->debug.scratch[10] = REG_READ(DMCUB_SCRATCH10); + dmub->debug.scratch[11] = REG_READ(DMCUB_SCRATCH11); + dmub->debug.scratch[12] = REG_READ(DMCUB_SCRATCH12); + dmub->debug.scratch[13] = REG_READ(DMCUB_SCRATCH13); + dmub->debug.scratch[14] = REG_READ(DMCUB_SCRATCH14); + dmub->debug.scratch[15] = REG_READ(DMCUB_SCRATCH15); + + dmub->debug.undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); + dmub->debug.inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); + dmub->debug.data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); + + dmub->debug.inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); + dmub->debug.inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); + dmub->debug.inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); + + dmub->debug.inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); + dmub->debug.inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); + dmub->debug.inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled); - diag_data->is_dmcub_enabled = is_dmub_enabled; + dmub->debug.is_dmcub_enabled = is_dmub_enabled; REG_GET(DMCUB_CNTL, DMCUB_SOFT_RESET, &is_soft_reset); - diag_data->is_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); - diag_data->is_dmcub_secure_reset = is_sec_reset; + dmub->debug.is_dmcub_secure_reset = is_sec_reset; REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled); - diag_data->is_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); - diag_data->is_cw0_enabled = 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); - diag_data->is_cw6_enabled = is_cw6_enabled; - diag_data->timeout_info = dmub->debug; + dmub->debug.is_cw6_enabled = is_cw6_enabled; } diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h index de287b101848..42c1fb4bc73f 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h @@ -247,6 +247,6 @@ bool dmub_dcn20_use_cached_trace_buffer(struct dmub_srv *dmub); uint32_t dmub_dcn20_get_current_time(struct dmub_srv *dmub); -void dmub_dcn20_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *dmub_oca); +void dmub_dcn20_get_diagnostic_data(struct dmub_srv *dmub); #endif /* _DMUB_DCN20_H_ */ diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c index d9f31b191c69..a308bd604677 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c @@ -83,8 +83,8 @@ static inline void dmub_dcn31_translate_addr(const union dmub_addr *addr_in, 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, pwait_mode; + const uint32_t timeout = 100000; + uint32_t in_reset, is_enabled, scratch, i, pwait_mode; REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset); @@ -108,7 +108,7 @@ void dmub_dcn31_reset(struct dmub_srv *dmub) } 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; @@ -125,9 +125,14 @@ void dmub_dcn31_reset(struct dmub_srv *dmub) /* 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); + REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_enabled); + + if (is_enabled) { + REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 1); + REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 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); @@ -371,6 +376,7 @@ void dmub_dcn31_enable_dmub_boot_options(struct dmub_srv *dmub, const struct dmu boot_options.bits.usb4_cm_version = params->usb4_cm_version; boot_options.bits.dpia_hpd_int_enable_supported = params->dpia_hpd_int_enable_supported; boot_options.bits.power_optimization = params->power_optimization; + boot_options.bits.lower_hbr3_phy_ssc = params->lower_hbr3_phy_ssc; boot_options.bits.sel_mux_phy_c_d_phy_f_g = (dmub->asic == DMUB_ASIC_DCN31B) ? 1 : 0; @@ -408,69 +414,72 @@ uint32_t dmub_dcn31_get_current_time(struct dmub_srv *dmub) return REG_READ(DMCUB_TIMER_CURRENT); } -void dmub_dcn31_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data) +void dmub_dcn31_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; + struct dmub_timeout_info timeout = {0}; - if (!dmub || !diag_data) + if (!dmub) return; - memset(diag_data, 0, sizeof(*diag_data)); - - diag_data->dmcub_version = dmub->fw_version; - - diag_data->scratch[0] = REG_READ(DMCUB_SCRATCH0); - diag_data->scratch[1] = REG_READ(DMCUB_SCRATCH1); - diag_data->scratch[2] = REG_READ(DMCUB_SCRATCH2); - diag_data->scratch[3] = REG_READ(DMCUB_SCRATCH3); - diag_data->scratch[4] = REG_READ(DMCUB_SCRATCH4); - diag_data->scratch[5] = REG_READ(DMCUB_SCRATCH5); - diag_data->scratch[6] = REG_READ(DMCUB_SCRATCH6); - diag_data->scratch[7] = REG_READ(DMCUB_SCRATCH7); - diag_data->scratch[8] = REG_READ(DMCUB_SCRATCH8); - diag_data->scratch[9] = REG_READ(DMCUB_SCRATCH9); - diag_data->scratch[10] = REG_READ(DMCUB_SCRATCH10); - diag_data->scratch[11] = REG_READ(DMCUB_SCRATCH11); - diag_data->scratch[12] = REG_READ(DMCUB_SCRATCH12); - diag_data->scratch[13] = REG_READ(DMCUB_SCRATCH13); - diag_data->scratch[14] = REG_READ(DMCUB_SCRATCH14); - diag_data->scratch[15] = REG_READ(DMCUB_SCRATCH15); - - diag_data->undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); - diag_data->inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); - diag_data->data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); - - diag_data->inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); - diag_data->inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); - diag_data->inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); - - diag_data->inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); - diag_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); - diag_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); - - diag_data->outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR); - diag_data->outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR); - diag_data->outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE); + /* timeout data filled externally, cache before resetting memory */ + timeout = dmub->debug.timeout_info; + memset(&dmub->debug, 0, sizeof(dmub->debug)); + dmub->debug.timeout_info = timeout; + + dmub->debug.dmcub_version = dmub->fw_version; + + dmub->debug.scratch[0] = REG_READ(DMCUB_SCRATCH0); + dmub->debug.scratch[1] = REG_READ(DMCUB_SCRATCH1); + dmub->debug.scratch[2] = REG_READ(DMCUB_SCRATCH2); + dmub->debug.scratch[3] = REG_READ(DMCUB_SCRATCH3); + dmub->debug.scratch[4] = REG_READ(DMCUB_SCRATCH4); + dmub->debug.scratch[5] = REG_READ(DMCUB_SCRATCH5); + dmub->debug.scratch[6] = REG_READ(DMCUB_SCRATCH6); + dmub->debug.scratch[7] = REG_READ(DMCUB_SCRATCH7); + dmub->debug.scratch[8] = REG_READ(DMCUB_SCRATCH8); + dmub->debug.scratch[9] = REG_READ(DMCUB_SCRATCH9); + dmub->debug.scratch[10] = REG_READ(DMCUB_SCRATCH10); + dmub->debug.scratch[11] = REG_READ(DMCUB_SCRATCH11); + dmub->debug.scratch[12] = REG_READ(DMCUB_SCRATCH12); + dmub->debug.scratch[13] = REG_READ(DMCUB_SCRATCH13); + dmub->debug.scratch[14] = REG_READ(DMCUB_SCRATCH14); + dmub->debug.scratch[15] = REG_READ(DMCUB_SCRATCH15); + + dmub->debug.undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); + dmub->debug.inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); + dmub->debug.data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); + + dmub->debug.inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); + dmub->debug.inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); + dmub->debug.inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); + + dmub->debug.inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); + dmub->debug.inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); + dmub->debug.inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); + + dmub->debug.outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR); + dmub->debug.outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR); + dmub->debug.outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE); REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled); - diag_data->is_dmcub_enabled = is_dmub_enabled; + dmub->debug.is_dmcub_enabled = is_dmub_enabled; REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &is_soft_reset); - diag_data->is_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); - diag_data->is_dmcub_secure_reset = is_sec_reset; + dmub->debug.is_dmcub_secure_reset = is_sec_reset; REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled); - diag_data->is_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); - diag_data->is_cw0_enabled = 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); - diag_data->is_cw6_enabled = is_cw6_enabled; - diag_data->timeout_info = dmub->debug; + dmub->debug.is_cw6_enabled = is_cw6_enabled; } bool dmub_dcn31_should_detect(struct dmub_srv *dmub) diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h index eccdab4986ce..1c43ef2bca66 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h @@ -251,7 +251,7 @@ void dmub_dcn31_set_outbox0_rptr(struct dmub_srv *dmub, uint32_t rptr_offset); uint32_t dmub_dcn31_get_current_time(struct dmub_srv *dmub); -void dmub_dcn31_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data); +void dmub_dcn31_get_diagnostic_data(struct dmub_srv *dmub); bool dmub_dcn31_should_detect(struct dmub_srv *dmub); diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c index 9600b7f858b0..e7056205b050 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c @@ -417,73 +417,75 @@ uint32_t dmub_dcn32_get_current_time(struct dmub_srv *dmub) return REG_READ(DMCUB_TIMER_CURRENT); } -void dmub_dcn32_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data) +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; + struct dmub_timeout_info timeout = {0}; - if (!dmub || !diag_data) + if (!dmub) return; - memset(diag_data, 0, sizeof(*diag_data)); - - diag_data->dmcub_version = dmub->fw_version; - - diag_data->scratch[0] = REG_READ(DMCUB_SCRATCH0); - diag_data->scratch[1] = REG_READ(DMCUB_SCRATCH1); - diag_data->scratch[2] = REG_READ(DMCUB_SCRATCH2); - diag_data->scratch[3] = REG_READ(DMCUB_SCRATCH3); - diag_data->scratch[4] = REG_READ(DMCUB_SCRATCH4); - diag_data->scratch[5] = REG_READ(DMCUB_SCRATCH5); - diag_data->scratch[6] = REG_READ(DMCUB_SCRATCH6); - diag_data->scratch[7] = REG_READ(DMCUB_SCRATCH7); - diag_data->scratch[8] = REG_READ(DMCUB_SCRATCH8); - diag_data->scratch[9] = REG_READ(DMCUB_SCRATCH9); - diag_data->scratch[10] = REG_READ(DMCUB_SCRATCH10); - diag_data->scratch[11] = REG_READ(DMCUB_SCRATCH11); - diag_data->scratch[12] = REG_READ(DMCUB_SCRATCH12); - diag_data->scratch[13] = REG_READ(DMCUB_SCRATCH13); - diag_data->scratch[14] = REG_READ(DMCUB_SCRATCH14); - diag_data->scratch[15] = REG_READ(DMCUB_SCRATCH15); - diag_data->scratch[16] = REG_READ(DMCUB_SCRATCH16); - - diag_data->undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); - diag_data->inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); - diag_data->data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); - - diag_data->inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); - diag_data->inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); - diag_data->inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); - - diag_data->inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); - diag_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); - diag_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); - - diag_data->outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR); - diag_data->outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR); - diag_data->outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE); + /* timeout data filled externally, cache before resetting memory */ + timeout = dmub->debug.timeout_info; + memset(&dmub->debug, 0, sizeof(dmub->debug)); + dmub->debug.timeout_info = timeout; + + dmub->debug.dmcub_version = dmub->fw_version; + + dmub->debug.scratch[0] = REG_READ(DMCUB_SCRATCH0); + dmub->debug.scratch[1] = REG_READ(DMCUB_SCRATCH1); + dmub->debug.scratch[2] = REG_READ(DMCUB_SCRATCH2); + dmub->debug.scratch[3] = REG_READ(DMCUB_SCRATCH3); + dmub->debug.scratch[4] = REG_READ(DMCUB_SCRATCH4); + dmub->debug.scratch[5] = REG_READ(DMCUB_SCRATCH5); + dmub->debug.scratch[6] = REG_READ(DMCUB_SCRATCH6); + dmub->debug.scratch[7] = REG_READ(DMCUB_SCRATCH7); + dmub->debug.scratch[8] = REG_READ(DMCUB_SCRATCH8); + dmub->debug.scratch[9] = REG_READ(DMCUB_SCRATCH9); + dmub->debug.scratch[10] = REG_READ(DMCUB_SCRATCH10); + dmub->debug.scratch[11] = REG_READ(DMCUB_SCRATCH11); + dmub->debug.scratch[12] = REG_READ(DMCUB_SCRATCH12); + dmub->debug.scratch[13] = REG_READ(DMCUB_SCRATCH13); + dmub->debug.scratch[14] = REG_READ(DMCUB_SCRATCH14); + dmub->debug.scratch[15] = REG_READ(DMCUB_SCRATCH15); + dmub->debug.scratch[16] = REG_READ(DMCUB_SCRATCH16); + + dmub->debug.undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); + dmub->debug.inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); + dmub->debug.data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); + + dmub->debug.inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); + dmub->debug.inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); + dmub->debug.inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); + + dmub->debug.inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); + dmub->debug.inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); + dmub->debug.inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); + + dmub->debug.outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR); + dmub->debug.outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR); + dmub->debug.outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE); REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled); - diag_data->is_dmcub_enabled = is_dmub_enabled; + dmub->debug.is_dmcub_enabled = is_dmub_enabled; REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &is_soft_reset); - diag_data->is_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); - diag_data->is_dmcub_secure_reset = is_sec_reset; + dmub->debug.is_dmcub_secure_reset = is_sec_reset; REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled); - diag_data->is_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); - diag_data->is_cw0_enabled = 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); - diag_data->is_cw6_enabled = is_cw6_enabled; + dmub->debug.is_cw6_enabled = is_cw6_enabled; - diag_data->gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0); - - diag_data->timeout_info = dmub->debug; + dmub->debug.gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0); } void dmub_dcn32_configure_dmub_in_system_memory(struct dmub_srv *dmub) { diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h index 29c1132951af..1a229450c53d 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h @@ -254,7 +254,7 @@ void dmub_dcn32_set_outbox0_rptr(struct dmub_srv *dmub, uint32_t rptr_offset); uint32_t dmub_dcn32_get_current_time(struct dmub_srv *dmub); -void dmub_dcn32_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data); +void dmub_dcn32_get_diagnostic_data(struct dmub_srv *dmub); void dmub_dcn32_configure_dmub_in_system_memory(struct dmub_srv *dmub); void dmub_dcn32_send_inbox0_cmd(struct dmub_srv *dmub, union dmub_inbox0_data_register data); diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c index e5e77bd3c31e..72a0f078cd1a 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c @@ -88,7 +88,7 @@ static inline void dmub_dcn35_translate_addr(const union dmub_addr *addr_in, void dmub_dcn35_reset(struct dmub_srv *dmub) { union dmub_gpint_data_register cmd; - const uint32_t timeout = 100; + const uint32_t timeout = 100000; uint32_t in_reset, is_enabled, scratch, i, pwait_mode; REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset); @@ -113,7 +113,7 @@ void dmub_dcn35_reset(struct dmub_srv *dmub) } 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; @@ -462,66 +462,69 @@ uint32_t dmub_dcn35_get_current_time(struct dmub_srv *dmub) return REG_READ(DMCUB_TIMER_CURRENT); } -void dmub_dcn35_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data) +void dmub_dcn35_get_diagnostic_data(struct dmub_srv *dmub) { uint32_t is_dmub_enabled, is_soft_reset; uint32_t is_traceport_enabled, is_cw6_enabled; + struct dmub_timeout_info timeout = {0}; - if (!dmub || !diag_data) + if (!dmub) return; - memset(diag_data, 0, sizeof(*diag_data)); - - diag_data->dmcub_version = dmub->fw_version; - - diag_data->scratch[0] = REG_READ(DMCUB_SCRATCH0); - diag_data->scratch[1] = REG_READ(DMCUB_SCRATCH1); - diag_data->scratch[2] = REG_READ(DMCUB_SCRATCH2); - diag_data->scratch[3] = REG_READ(DMCUB_SCRATCH3); - diag_data->scratch[4] = REG_READ(DMCUB_SCRATCH4); - diag_data->scratch[5] = REG_READ(DMCUB_SCRATCH5); - diag_data->scratch[6] = REG_READ(DMCUB_SCRATCH6); - diag_data->scratch[7] = REG_READ(DMCUB_SCRATCH7); - diag_data->scratch[8] = REG_READ(DMCUB_SCRATCH8); - diag_data->scratch[9] = REG_READ(DMCUB_SCRATCH9); - diag_data->scratch[10] = REG_READ(DMCUB_SCRATCH10); - diag_data->scratch[11] = REG_READ(DMCUB_SCRATCH11); - diag_data->scratch[12] = REG_READ(DMCUB_SCRATCH12); - diag_data->scratch[13] = REG_READ(DMCUB_SCRATCH13); - diag_data->scratch[14] = REG_READ(DMCUB_SCRATCH14); - diag_data->scratch[15] = REG_READ(DMCUB_SCRATCH15); - diag_data->scratch[16] = REG_READ(DMCUB_SCRATCH16); - - diag_data->undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); - diag_data->inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); - diag_data->data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); - - diag_data->inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); - diag_data->inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); - diag_data->inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); - - diag_data->inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); - diag_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); - diag_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); - - diag_data->outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR); - diag_data->outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR); - diag_data->outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE); + /* timeout data filled externally, cache before resetting memory */ + timeout = dmub->debug.timeout_info; + memset(&dmub->debug, 0, sizeof(dmub->debug)); + dmub->debug.timeout_info = timeout; + + dmub->debug.dmcub_version = dmub->fw_version; + + dmub->debug.scratch[0] = REG_READ(DMCUB_SCRATCH0); + dmub->debug.scratch[1] = REG_READ(DMCUB_SCRATCH1); + dmub->debug.scratch[2] = REG_READ(DMCUB_SCRATCH2); + dmub->debug.scratch[3] = REG_READ(DMCUB_SCRATCH3); + dmub->debug.scratch[4] = REG_READ(DMCUB_SCRATCH4); + dmub->debug.scratch[5] = REG_READ(DMCUB_SCRATCH5); + dmub->debug.scratch[6] = REG_READ(DMCUB_SCRATCH6); + dmub->debug.scratch[7] = REG_READ(DMCUB_SCRATCH7); + dmub->debug.scratch[8] = REG_READ(DMCUB_SCRATCH8); + dmub->debug.scratch[9] = REG_READ(DMCUB_SCRATCH9); + dmub->debug.scratch[10] = REG_READ(DMCUB_SCRATCH10); + dmub->debug.scratch[11] = REG_READ(DMCUB_SCRATCH11); + dmub->debug.scratch[12] = REG_READ(DMCUB_SCRATCH12); + dmub->debug.scratch[13] = REG_READ(DMCUB_SCRATCH13); + dmub->debug.scratch[14] = REG_READ(DMCUB_SCRATCH14); + dmub->debug.scratch[15] = REG_READ(DMCUB_SCRATCH15); + dmub->debug.scratch[16] = REG_READ(DMCUB_SCRATCH16); + + dmub->debug.undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); + dmub->debug.inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); + dmub->debug.data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); + + dmub->debug.inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); + dmub->debug.inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); + dmub->debug.inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); + + dmub->debug.inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); + dmub->debug.inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); + dmub->debug.inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); + + dmub->debug.outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR); + dmub->debug.outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR); + dmub->debug.outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE); REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled); - diag_data->is_dmcub_enabled = is_dmub_enabled; + dmub->debug.is_dmcub_enabled = is_dmub_enabled; REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &is_soft_reset); - diag_data->is_dmcub_soft_reset = is_soft_reset; + dmub->debug.is_dmcub_soft_reset = is_soft_reset; REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled); - diag_data->is_traceport_en = is_traceport_enabled; + dmub->debug.is_traceport_en = is_traceport_enabled; REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled); - diag_data->is_cw6_enabled = is_cw6_enabled; + dmub->debug.is_cw6_enabled = is_cw6_enabled; - diag_data->gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0); - diag_data->timeout_info = dmub->debug; + dmub->debug.gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0); } void dmub_dcn35_configure_dmub_in_system_memory(struct dmub_srv *dmub) { diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.h index 686e97c00ccc..39fcb7275da5 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.h @@ -269,7 +269,7 @@ void dmub_dcn35_set_outbox0_rptr(struct dmub_srv *dmub, uint32_t rptr_offset); uint32_t dmub_dcn35_get_current_time(struct dmub_srv *dmub); -void dmub_dcn35_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data); +void dmub_dcn35_get_diagnostic_data(struct dmub_srv *dmub); void dmub_dcn35_configure_dmub_in_system_memory(struct dmub_srv *dmub); diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn36.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn36.c new file mode 100644 index 000000000000..b1ce09d48920 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn36.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright 2025 Advanced Micro Devices, Inc. */ + +#include "../dmub_srv.h" +#include "dmub_reg.h" +#include "dmub_dcn36.h" + +#include "dcn/dcn_3_6_0_offset.h" +#include "dcn/dcn_3_6_0_sh_mask.h" + +#define BASE_INNER(seg) ctx->dcn_reg_offsets[seg] +#define CTX dmub +#define REGS dmub->regs_dcn35 +#define REG_OFFSET_EXP(reg_name) BASE(reg##reg_name##_BASE_IDX) + reg##reg_name + +void dmub_srv_dcn36_regs_init(struct dmub_srv *dmub, struct dc_context *ctx) +{ + struct dmub_srv_dcn35_regs *regs = dmub->regs_dcn35; +#define REG_STRUCT regs + +#define DMUB_SR(reg) REG_STRUCT->offset.reg = REG_OFFSET_EXP(reg); + DMUB_DCN35_REGS() + DMCUB_INTERNAL_REGS() +#undef DMUB_SR + +#define DMUB_SF(reg, field) REG_STRUCT->mask.reg##__##field = FD_MASK(reg, field); + DMUB_DCN35_FIELDS() +#undef DMUB_SF + +#define DMUB_SF(reg, field) REG_STRUCT->shift.reg##__##field = FD_SHIFT(reg, field); + DMUB_DCN35_FIELDS() +#undef DMUB_SF +#undef REG_STRUCT +} diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn36.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn36.h new file mode 100644 index 000000000000..57850550f682 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn36.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright 2025 Advanced Micro Devices, Inc. */ + +#ifndef _DMUB_DCN36_H_ +#define _DMUB_DCN36_H_ + +#include "dmub_dcn35.h" + +struct dmub_srv; + +void dmub_srv_dcn36_regs_init(struct dmub_srv *dmub, struct dc_context *ctx); + +#endif /* _DMUB_DCN36_H_ */ diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c index 39a8cb6d7523..e67f7c4784eb 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c @@ -63,8 +63,10 @@ static inline void dmub_dcn401_translate_addr(const union dmub_addr *addr_in, void dmub_dcn401_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_us = 1 * 1000 * 1000; //1s + const uint32_t poll_delay_us = 1; //1us + uint32_t i = 0; + uint32_t in_reset, scratch, pwait_mode; REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset); @@ -75,32 +77,35 @@ void dmub_dcn401_reset(struct dmub_srv *dmub) 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) { + for (i = 0; i < timeout_us; i++) { if (dmub->hw_funcs.is_gpint_acked(dmub, cmd)) break; + + udelay(poll_delay_us); } - for (i = 0; i < timeout; ++i) { + for (; i < timeout_us; i++) { scratch = dmub->hw_funcs.get_gpint_response(dmub); if (scratch == DMUB_GPINT__STOP_FW_RESPONSE) break; + + udelay(poll_delay_us); } - /* Force reset in case we timed out, DMCUB is likely hung. */ + for (; i < timeout_us; i++) { + REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &pwait_mode); + if (pwait_mode & (1 << 0)) + break; + + udelay(poll_delay_us); + } + } + + if (i >= timeout_us) { + /* timeout should never occur */ + BREAK_TO_DEBUGGER(); } - REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 1); - REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0); - REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1); REG_WRITE(DMCUB_INBOX1_RPTR, 0); REG_WRITE(DMCUB_INBOX1_WPTR, 0); REG_WRITE(DMCUB_OUTBOX1_RPTR, 0); @@ -131,7 +136,10 @@ void dmub_dcn401_backdoor_load(struct dmub_srv *dmub, dmub_dcn401_get_fb_base_offset(dmub, &fb_base, &fb_offset); + /* reset and disable DMCUB and MMHUBBUB DMUIF */ REG_UPDATE(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 1); + REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1); + REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0); dmub_dcn401_translate_addr(&cw0->offset, fb_base, fb_offset, &offset); @@ -151,6 +159,7 @@ void dmub_dcn401_backdoor_load(struct dmub_srv *dmub, DMCUB_REGION3_CW1_TOP_ADDRESS, cw1->region.top, DMCUB_REGION3_CW1_ENABLE, 1); + /* release DMCUB reset only to prevent premature execution */ REG_UPDATE_2(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 0, DMCUB_MEM_UNIT_ID, 0x20); } @@ -161,7 +170,10 @@ void dmub_dcn401_backdoor_load_zfb_mode(struct dmub_srv *dmub, { union dmub_addr offset; + /* reset and disable DMCUB and MMHUBBUB DMUIF */ REG_UPDATE(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 1); + REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1); + REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0); offset = cw0->offset; @@ -181,6 +193,7 @@ void dmub_dcn401_backdoor_load_zfb_mode(struct dmub_srv *dmub, DMCUB_REGION3_CW1_TOP_ADDRESS, cw1->region.top, DMCUB_REGION3_CW1_ENABLE, 1); + /* release DMCUB reset only to prevent premature execution */ REG_UPDATE_2(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 0, DMCUB_MEM_UNIT_ID, 0x20); } @@ -402,72 +415,75 @@ uint32_t dmub_dcn401_get_current_time(struct dmub_srv *dmub) return REG_READ(DMCUB_TIMER_CURRENT); } -void dmub_dcn401_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data) +void dmub_dcn401_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; + struct dmub_timeout_info timeout = {0}; - if (!dmub || !diag_data) + if (!dmub) return; - memset(diag_data, 0, sizeof(*diag_data)); - - diag_data->dmcub_version = dmub->fw_version; - - diag_data->scratch[0] = REG_READ(DMCUB_SCRATCH0); - diag_data->scratch[1] = REG_READ(DMCUB_SCRATCH1); - diag_data->scratch[2] = REG_READ(DMCUB_SCRATCH2); - diag_data->scratch[3] = REG_READ(DMCUB_SCRATCH3); - diag_data->scratch[4] = REG_READ(DMCUB_SCRATCH4); - diag_data->scratch[5] = REG_READ(DMCUB_SCRATCH5); - diag_data->scratch[6] = REG_READ(DMCUB_SCRATCH6); - diag_data->scratch[7] = REG_READ(DMCUB_SCRATCH7); - diag_data->scratch[8] = REG_READ(DMCUB_SCRATCH8); - diag_data->scratch[9] = REG_READ(DMCUB_SCRATCH9); - diag_data->scratch[10] = REG_READ(DMCUB_SCRATCH10); - diag_data->scratch[11] = REG_READ(DMCUB_SCRATCH11); - diag_data->scratch[12] = REG_READ(DMCUB_SCRATCH12); - diag_data->scratch[13] = REG_READ(DMCUB_SCRATCH13); - diag_data->scratch[14] = REG_READ(DMCUB_SCRATCH14); - diag_data->scratch[15] = REG_READ(DMCUB_SCRATCH15); - diag_data->scratch[16] = REG_READ(DMCUB_SCRATCH16); - - diag_data->undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); - diag_data->inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); - diag_data->data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); - - diag_data->inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); - diag_data->inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); - diag_data->inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); - - diag_data->inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); - diag_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); - diag_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); - - diag_data->outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR); - diag_data->outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR); - diag_data->outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE); + /* timeout data filled externally, cache before resetting memory */ + timeout = dmub->debug.timeout_info; + memset(&dmub->debug, 0, sizeof(dmub->debug)); + dmub->debug.timeout_info = timeout; + + dmub->debug.dmcub_version = dmub->fw_version; + + dmub->debug.scratch[0] = REG_READ(DMCUB_SCRATCH0); + dmub->debug.scratch[1] = REG_READ(DMCUB_SCRATCH1); + dmub->debug.scratch[2] = REG_READ(DMCUB_SCRATCH2); + dmub->debug.scratch[3] = REG_READ(DMCUB_SCRATCH3); + dmub->debug.scratch[4] = REG_READ(DMCUB_SCRATCH4); + dmub->debug.scratch[5] = REG_READ(DMCUB_SCRATCH5); + dmub->debug.scratch[6] = REG_READ(DMCUB_SCRATCH6); + dmub->debug.scratch[7] = REG_READ(DMCUB_SCRATCH7); + dmub->debug.scratch[8] = REG_READ(DMCUB_SCRATCH8); + dmub->debug.scratch[9] = REG_READ(DMCUB_SCRATCH9); + dmub->debug.scratch[10] = REG_READ(DMCUB_SCRATCH10); + dmub->debug.scratch[11] = REG_READ(DMCUB_SCRATCH11); + dmub->debug.scratch[12] = REG_READ(DMCUB_SCRATCH12); + dmub->debug.scratch[13] = REG_READ(DMCUB_SCRATCH13); + dmub->debug.scratch[14] = REG_READ(DMCUB_SCRATCH14); + dmub->debug.scratch[15] = REG_READ(DMCUB_SCRATCH15); + dmub->debug.scratch[16] = REG_READ(DMCUB_SCRATCH16); + + dmub->debug.undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); + dmub->debug.inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); + dmub->debug.data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); + + dmub->debug.inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); + dmub->debug.inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); + dmub->debug.inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); + + dmub->debug.inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); + dmub->debug.inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); + dmub->debug.inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); + + dmub->debug.outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR); + dmub->debug.outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR); + dmub->debug.outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE); REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled); - diag_data->is_dmcub_enabled = is_dmub_enabled; + dmub->debug.is_dmcub_enabled = is_dmub_enabled; REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &is_soft_reset); - diag_data->is_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); - diag_data->is_dmcub_secure_reset = is_sec_reset; + dmub->debug.is_dmcub_secure_reset = is_sec_reset; REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled); - diag_data->is_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); - diag_data->is_cw0_enabled = 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); - diag_data->is_cw6_enabled = is_cw6_enabled; + dmub->debug.is_cw6_enabled = is_cw6_enabled; - diag_data->gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0); - diag_data->timeout_info = dmub->debug; + dmub->debug.gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0); } void dmub_dcn401_configure_dmub_in_system_memory(struct dmub_srv *dmub) { diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.h index 4c8843b79695..c35be52676f6 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.h @@ -169,7 +169,8 @@ struct dmub_srv; DMUB_SF(HOST_INTERRUPT_CSR, HOST_REG_INBOX0_RSP_INT_EN) \ DMUB_SF(HOST_INTERRUPT_CSR, HOST_REG_OUTBOX0_RDY_INT_ACK) \ DMUB_SF(HOST_INTERRUPT_CSR, HOST_REG_OUTBOX0_RDY_INT_STAT) \ - DMUB_SF(HOST_INTERRUPT_CSR, HOST_REG_OUTBOX0_RDY_INT_EN) + DMUB_SF(HOST_INTERRUPT_CSR, HOST_REG_OUTBOX0_RDY_INT_EN) \ + DMUB_SF(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS) struct dmub_srv_dcn401_reg_offset { #define DMUB_SR(reg) uint32_t reg; @@ -263,7 +264,7 @@ void dmub_dcn401_set_outbox0_rptr(struct dmub_srv *dmub, uint32_t rptr_offset); uint32_t dmub_dcn401_get_current_time(struct dmub_srv *dmub); -void dmub_dcn401_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data); +void dmub_dcn401_get_diagnostic_data(struct dmub_srv *dmub); void dmub_dcn401_configure_dmub_in_system_memory(struct dmub_srv *dmub); void dmub_dcn401_send_inbox0_cmd(struct dmub_srv *dmub, union dmub_inbox0_data_register data); diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c index 15ea216e903d..ae8133816b43 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c @@ -38,6 +38,7 @@ #include "dmub_dcn32.h" #include "dmub_dcn35.h" #include "dmub_dcn351.h" +#include "dmub_dcn36.h" #include "dmub_dcn401.h" #include "os_types.h" /* @@ -314,6 +315,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic) case DMUB_ASIC_DCN35: case DMUB_ASIC_DCN351: + case DMUB_ASIC_DCN36: dmub->regs_dcn35 = &dmub_srv_dcn35_regs; funcs->configure_dmub_in_system_memory = dmub_dcn35_configure_dmub_in_system_memory; funcs->send_inbox0_cmd = dmub_dcn35_send_inbox0_cmd; @@ -351,7 +353,9 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic) funcs->init_reg_offsets = dmub_srv_dcn35_regs_init; if (asic == DMUB_ASIC_DCN351) - funcs->init_reg_offsets = dmub_srv_dcn351_regs_init; + funcs->init_reg_offsets = dmub_srv_dcn351_regs_init; + if (asic == DMUB_ASIC_DCN36) + funcs->init_reg_offsets = dmub_srv_dcn36_regs_init; funcs->is_hw_powered_up = dmub_dcn35_is_hw_powered_up; funcs->should_detect = dmub_dcn35_should_detect; @@ -704,7 +708,7 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, cw6.region.base = DMUB_CW6_BASE; cw6.region.top = cw6.region.base + fw_state_fb->size; - dmub->fw_state = fw_state_fb->cpu_addr; + dmub->fw_state = (void *)((uintptr_t)(fw_state_fb->cpu_addr) + DMUB_DEBUG_FW_STATE_OFFSET); region6.offset.quad_part = shared_state_fb->gpu_addr; region6.region.base = DMUB_CW6_BASE; @@ -846,7 +850,7 @@ enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub) flush_rb.rptr = dmub->inbox1_last_wptr; dmub_rb_flush_pending(&flush_rb); - dmub->hw_funcs.set_inbox1_wptr(dmub, dmub->inbox1_rb.wrpt); + dmub->hw_funcs.set_inbox1_wptr(dmub, dmub->inbox1_rb.wrpt); dmub->inbox1_last_wptr = dmub->inbox1_rb.wrpt; @@ -915,7 +919,7 @@ enum dmub_status dmub_srv_wait_for_idle(struct dmub_srv *dmub, return DMUB_STATUS_INVALID; for (i = 0; i <= timeout_us; ++i) { - rptr = dmub->hw_funcs.get_inbox1_rptr(dmub); + rptr = dmub->hw_funcs.get_inbox1_rptr(dmub); if (rptr > dmub->inbox1_rb.capacity) return DMUB_STATUS_HW_FAILURE; @@ -1095,11 +1099,11 @@ bool dmub_srv_get_outbox0_msg(struct dmub_srv *dmub, struct dmcub_trace_buf_entr return dmub_rb_out_trace_buffer_front(&dmub->outbox0_rb, (void *)entry); } -bool dmub_srv_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data) +bool dmub_srv_get_diagnostic_data(struct dmub_srv *dmub) { - if (!dmub || !dmub->hw_funcs.get_diagnostic_data || !diag_data) + if (!dmub || !dmub->hw_funcs.get_diagnostic_data) return false; - dmub->hw_funcs.get_diagnostic_data(dmub, diag_data); + dmub->hw_funcs.get_diagnostic_data(dmub); return true; } @@ -1156,6 +1160,7 @@ void dmub_srv_subvp_save_surf_addr(struct dmub_srv *dmub, const struct dc_plane_ } } + enum dmub_status dmub_srv_send_reg_inbox0_cmd( struct dmub_srv *dmub, union dmub_rb_cmd *cmd, |