From: Dillon Varone <[email protected]> [WHY&HOW] Adds diagnostic logs for recent DMU traces.
Reviewed-by: Nicholas Kazlauskas <[email protected]> Reviewed-by: Aric Cyr <[email protected]> Signed-off-by: Dillon Varone <[email protected]> Signed-off-by: George Zhang <[email protected]> --- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 125 ++++++++++++------ drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 58 +++++++- .../gpu/drm/amd/display/dmub/src/dmub_dcn20.c | 84 ++++++------ .../gpu/drm/amd/display/dmub/src/dmub_dcn20.h | 2 +- .../gpu/drm/amd/display/dmub/src/dmub_dcn31.c | 94 +++++++------ .../gpu/drm/amd/display/dmub/src/dmub_dcn31.h | 2 +- .../gpu/drm/amd/display/dmub/src/dmub_dcn32.c | 94 +++++++------ .../gpu/drm/amd/display/dmub/src/dmub_dcn32.h | 2 +- .../gpu/drm/amd/display/dmub/src/dmub_dcn35.c | 94 +++++++------ .../gpu/drm/amd/display/dmub/src/dmub_dcn35.h | 2 +- .../drm/amd/display/dmub/src/dmub_dcn401.c | 98 +++++++------- .../drm/amd/display/dmub/src/dmub_dcn401.h | 2 +- .../gpu/drm/amd/display/dmub/src/dmub_dcn42.c | 98 +++++++------- .../gpu/drm/amd/display/dmub/src/dmub_dcn42.h | 2 +- .../gpu/drm/amd/display/dmub/src/dmub_dcn60.c | 98 +++++++------- .../gpu/drm/amd/display/dmub/src/dmub_dcn60.h | 2 +- .../gpu/drm/amd/display/dmub/src/dmub_srv.c | 54 +++++++- 17 files changed, 511 insertions(+), 400 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index 1e7071f8d53f..37248ecc3c08 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -273,6 +273,49 @@ bool dc_dmub_srv_cmd_list_queue_execute(struct dc_dmub_srv *dc_dmub_srv, return dc_dmub_srv_cmd_list_queue_execute_timeout(dc_dmub_srv, count, cmd_list, DMUB_CMD_DEFAULT_MAX_WAIT_US); } +static void dc_dmub_srv_log_timeout(const struct dc_dmub_srv *dc_dmub_srv, + struct dmub_timeout_info *timeout_info, + union dmub_rb_cmd *cmd) +{ + struct dmub_srv *dmub; + + if (!dc_dmub_srv || !dc_dmub_srv->dmub) + return; + + dmub = dc_dmub_srv->dmub; + + // timeout already ocurred, do not overwrite + if (timeout_info->timeout_occured) + return; + + timeout_info->timeout_occured = true; + if (cmd) + timeout_info->timeout_cmd = *cmd; + timeout_info->timestamp = dm_get_timestamp(dc_dmub_srv->ctx); + + // capture last trace entries from the DMCUB trace buffer + dmub_srv_get_trace_snapshot(dmub, + &timeout_info->trace_snapshot); +} + +static void dc_dmub_srv_log_timeouts(struct dc_dmub_srv *dc_dmub_srv, + union dmub_rb_cmd *cmd) +{ + struct dmub_srv *dmub; + + if (!dc_dmub_srv || !dc_dmub_srv->dmub) + return; + + dmub = dc_dmub_srv->dmub; + + // log if this is the first timeout + dc_dmub_srv_log_timeout(dc_dmub_srv, &dmub->debug.first_timeout_info, cmd); + + // clear valid flag and log latest timeout + dmub->debug.latest_timeout_info.timeout_occured = false; + dc_dmub_srv_log_timeout(dc_dmub_srv, &dmub->debug.latest_timeout_info, cmd); +} + bool dc_dmub_srv_wait_for_idle(struct dc_dmub_srv *dc_dmub_srv, enum dm_dmub_wait_type wait_type, union dmub_rb_cmd *cmd_list, @@ -294,12 +337,8 @@ bool dc_dmub_srv_wait_for_idle(struct dc_dmub_srv *dc_dmub_srv, if (status != DMUB_STATUS_OK) { DC_LOG_DEBUG("No reply for DMUB command: status=%d\n", status); - if (!dmub->debug.timeout_info.timeout_occured) { - dmub->debug.timeout_info.timeout_occured = true; - if (cmd_list) - dmub->debug.timeout_info.timeout_cmd = *cmd_list; - dmub->debug.timeout_info.timestamp = dm_get_timestamp(dc_dmub_srv->ctx); - } + + dc_dmub_srv_log_timeouts(dc_dmub_srv, cmd_list); dc_dmub_srv_handle_failure(dc_dmub_srv); return false; } @@ -985,44 +1024,44 @@ void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv) } DC_LOG_DEBUG("DMCUB STATE:"); - DC_LOG_DEBUG(" dmcub_version : %08x", dc_dmub_srv->dmub->debug.dmcub_version); - DC_LOG_DEBUG(" scratch [0] : %08x", dc_dmub_srv->dmub->debug.scratch[0]); - DC_LOG_DEBUG(" scratch [1] : %08x", dc_dmub_srv->dmub->debug.scratch[1]); - DC_LOG_DEBUG(" scratch [2] : %08x", dc_dmub_srv->dmub->debug.scratch[2]); - DC_LOG_DEBUG(" scratch [3] : %08x", dc_dmub_srv->dmub->debug.scratch[3]); - DC_LOG_DEBUG(" scratch [4] : %08x", dc_dmub_srv->dmub->debug.scratch[4]); - DC_LOG_DEBUG(" scratch [5] : %08x", dc_dmub_srv->dmub->debug.scratch[5]); - DC_LOG_DEBUG(" scratch [6] : %08x", dc_dmub_srv->dmub->debug.scratch[6]); - DC_LOG_DEBUG(" scratch [7] : %08x", dc_dmub_srv->dmub->debug.scratch[7]); - DC_LOG_DEBUG(" scratch [8] : %08x", dc_dmub_srv->dmub->debug.scratch[8]); - DC_LOG_DEBUG(" scratch [9] : %08x", dc_dmub_srv->dmub->debug.scratch[9]); - DC_LOG_DEBUG(" scratch [10] : %08x", dc_dmub_srv->dmub->debug.scratch[10]); - DC_LOG_DEBUG(" scratch [11] : %08x", dc_dmub_srv->dmub->debug.scratch[11]); - DC_LOG_DEBUG(" scratch [12] : %08x", dc_dmub_srv->dmub->debug.scratch[12]); - DC_LOG_DEBUG(" scratch [13] : %08x", dc_dmub_srv->dmub->debug.scratch[13]); - DC_LOG_DEBUG(" scratch [14] : %08x", dc_dmub_srv->dmub->debug.scratch[14]); - DC_LOG_DEBUG(" scratch [15] : %08x", dc_dmub_srv->dmub->debug.scratch[15]); + DC_LOG_DEBUG(" dmcub_version : %08x", dc_dmub_srv->dmub->debug.hw.dmcub_version); + DC_LOG_DEBUG(" scratch [0] : %08x", dc_dmub_srv->dmub->debug.hw.scratch[0]); + DC_LOG_DEBUG(" scratch [1] : %08x", dc_dmub_srv->dmub->debug.hw.scratch[1]); + DC_LOG_DEBUG(" scratch [2] : %08x", dc_dmub_srv->dmub->debug.hw.scratch[2]); + DC_LOG_DEBUG(" scratch [3] : %08x", dc_dmub_srv->dmub->debug.hw.scratch[3]); + DC_LOG_DEBUG(" scratch [4] : %08x", dc_dmub_srv->dmub->debug.hw.scratch[4]); + DC_LOG_DEBUG(" scratch [5] : %08x", dc_dmub_srv->dmub->debug.hw.scratch[5]); + DC_LOG_DEBUG(" scratch [6] : %08x", dc_dmub_srv->dmub->debug.hw.scratch[6]); + DC_LOG_DEBUG(" scratch [7] : %08x", dc_dmub_srv->dmub->debug.hw.scratch[7]); + DC_LOG_DEBUG(" scratch [8] : %08x", dc_dmub_srv->dmub->debug.hw.scratch[8]); + DC_LOG_DEBUG(" scratch [9] : %08x", dc_dmub_srv->dmub->debug.hw.scratch[9]); + DC_LOG_DEBUG(" scratch [10] : %08x", dc_dmub_srv->dmub->debug.hw.scratch[10]); + DC_LOG_DEBUG(" scratch [11] : %08x", dc_dmub_srv->dmub->debug.hw.scratch[11]); + DC_LOG_DEBUG(" scratch [12] : %08x", dc_dmub_srv->dmub->debug.hw.scratch[12]); + DC_LOG_DEBUG(" scratch [13] : %08x", dc_dmub_srv->dmub->debug.hw.scratch[13]); + DC_LOG_DEBUG(" scratch [14] : %08x", dc_dmub_srv->dmub->debug.hw.scratch[14]); + DC_LOG_DEBUG(" scratch [15] : %08x", dc_dmub_srv->dmub->debug.hw.scratch[15]); for (i = 0; i < DMUB_PC_SNAPSHOT_COUNT; i++) - DC_LOG_DEBUG(" pc[%d] : %08x", i, dc_dmub_srv->dmub->debug.pc[i]); - DC_LOG_DEBUG(" unk_fault_addr : %08x", dc_dmub_srv->dmub->debug.undefined_address_fault_addr); - DC_LOG_DEBUG(" inst_fault_addr : %08x", dc_dmub_srv->dmub->debug.inst_fetch_fault_addr); - DC_LOG_DEBUG(" data_fault_addr : %08x", dc_dmub_srv->dmub->debug.data_write_fault_addr); - DC_LOG_DEBUG(" inbox1_rptr : %08x", dc_dmub_srv->dmub->debug.inbox1_rptr); - DC_LOG_DEBUG(" inbox1_wptr : %08x", dc_dmub_srv->dmub->debug.inbox1_wptr); - DC_LOG_DEBUG(" inbox1_size : %08x", dc_dmub_srv->dmub->debug.inbox1_size); - DC_LOG_DEBUG(" inbox0_rptr : %08x", dc_dmub_srv->dmub->debug.inbox0_rptr); - DC_LOG_DEBUG(" inbox0_wptr : %08x", dc_dmub_srv->dmub->debug.inbox0_wptr); - DC_LOG_DEBUG(" inbox0_size : %08x", dc_dmub_srv->dmub->debug.inbox0_size); - DC_LOG_DEBUG(" outbox1_rptr : %08x", dc_dmub_srv->dmub->debug.outbox1_rptr); - DC_LOG_DEBUG(" outbox1_wptr : %08x", dc_dmub_srv->dmub->debug.outbox1_wptr); - DC_LOG_DEBUG(" outbox1_size : %08x", dc_dmub_srv->dmub->debug.outbox1_size); - DC_LOG_DEBUG(" is_enabled : %d", dc_dmub_srv->dmub->debug.is_dmcub_enabled); - DC_LOG_DEBUG(" is_soft_reset : %d", dc_dmub_srv->dmub->debug.is_dmcub_soft_reset); - DC_LOG_DEBUG(" is_secure_reset : %d", dc_dmub_srv->dmub->debug.is_dmcub_secure_reset); - DC_LOG_DEBUG(" is_traceport_en : %d", dc_dmub_srv->dmub->debug.is_traceport_en); - DC_LOG_DEBUG(" is_cw0_en : %d", dc_dmub_srv->dmub->debug.is_cw0_enabled); - DC_LOG_DEBUG(" is_cw6_en : %d", dc_dmub_srv->dmub->debug.is_cw6_enabled); - DC_LOG_DEBUG(" is_pwait : %d", dc_dmub_srv->dmub->debug.is_pwait); + DC_LOG_DEBUG(" pc[%d] : %08x", i, dc_dmub_srv->dmub->debug.hw.pc[i]); + DC_LOG_DEBUG(" unk_fault_addr : %08x", dc_dmub_srv->dmub->debug.hw.undefined_address_fault_addr); + DC_LOG_DEBUG(" inst_fault_addr : %08x", dc_dmub_srv->dmub->debug.hw.inst_fetch_fault_addr); + DC_LOG_DEBUG(" data_fault_addr : %08x", dc_dmub_srv->dmub->debug.hw.data_write_fault_addr); + DC_LOG_DEBUG(" inbox1_rptr : %08x", dc_dmub_srv->dmub->debug.hw.inbox1_rptr); + DC_LOG_DEBUG(" inbox1_wptr : %08x", dc_dmub_srv->dmub->debug.hw.inbox1_wptr); + DC_LOG_DEBUG(" inbox1_size : %08x", dc_dmub_srv->dmub->debug.hw.inbox1_size); + DC_LOG_DEBUG(" inbox0_rptr : %08x", dc_dmub_srv->dmub->debug.hw.inbox0_rptr); + DC_LOG_DEBUG(" inbox0_wptr : %08x", dc_dmub_srv->dmub->debug.hw.inbox0_wptr); + DC_LOG_DEBUG(" inbox0_size : %08x", dc_dmub_srv->dmub->debug.hw.inbox0_size); + DC_LOG_DEBUG(" outbox1_rptr : %08x", dc_dmub_srv->dmub->debug.hw.outbox1_rptr); + DC_LOG_DEBUG(" outbox1_wptr : %08x", dc_dmub_srv->dmub->debug.hw.outbox1_wptr); + DC_LOG_DEBUG(" outbox1_size : %08x", dc_dmub_srv->dmub->debug.hw.outbox1_size); + DC_LOG_DEBUG(" is_enabled : %d", dc_dmub_srv->dmub->debug.hw.is_dmcub_enabled); + DC_LOG_DEBUG(" is_soft_reset : %d", dc_dmub_srv->dmub->debug.hw.is_dmcub_soft_reset); + DC_LOG_DEBUG(" is_secure_reset : %d", dc_dmub_srv->dmub->debug.hw.is_dmcub_secure_reset); + DC_LOG_DEBUG(" is_traceport_en : %d", dc_dmub_srv->dmub->debug.hw.is_traceport_en); + DC_LOG_DEBUG(" is_cw0_en : %d", dc_dmub_srv->dmub->debug.hw.is_cw0_enabled); + DC_LOG_DEBUG(" is_cw6_en : %d", dc_dmub_srv->dmub->debug.hw.is_cw6_enabled); + DC_LOG_DEBUG(" is_pwait : %d", dc_dmub_srv->dmub->debug.hw.is_pwait); } bool dc_dmub_should_update_cursor_data(struct pipe_ctx *pipe_ctx) diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h index a5222ffc8ab6..17579ff2e1bf 100644 --- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h @@ -69,6 +69,7 @@ #include "dc/dc_types.h" #define DMUB_PC_SNAPSHOT_COUNT 10 +#define DMUB_TRACE_SNAPSHOT_COUNT 8 /* Default tracebuffer size if meta is absent. */ #define DMUB_TRACE_BUFFER_SIZE (64 * 1024) @@ -81,6 +82,7 @@ struct dmub_srv; struct dmub_srv_common_regs; struct dmub_srv_dcn31_regs; +struct dmcub_trace_buf; struct dmcub_trace_buf_entry; /* enum dmub_window_memory_type - memory location type specification for windows */ @@ -358,6 +360,26 @@ struct dmub_srv_hw_params { bool disable_dpia_bw_allocation; }; +#define DMUB_TIMEOUT_TRACE_COUNT 8 + +/** + * struct dmub_trace_buf_header - Header for the DMUB trace buffer + * @entry_count: Number of valid entries in the trace buffer + * @reserved: Reserved for future use + */ +struct dmub_trace_buf_header { + uint32_t entry_count; + uint32_t reserved[3]; +}; + +/** + * struct dmub_trace_snapshot - Snapshot of the DMUB trace buffer + * @traces: Array of trace buffer entries + */ +struct dmub_trace_snapshot { + struct dmcub_trace_buf_entry traces[DMUB_TRACE_SNAPSHOT_COUNT]; +}; + /** * struct dmub_srv_debug - Debug info for dmub_srv * @timeout_occured: Indicates a timeout occured on any message from driver to dmub @@ -367,13 +389,13 @@ struct dmub_timeout_info { bool timeout_occured; union dmub_rb_cmd timeout_cmd; unsigned long long timestamp; + struct dmub_trace_snapshot trace_snapshot; }; /** - * struct dmub_diagnostic_data - Diagnostic data retrieved from DMCUB for - * debugging purposes, including logging, crash analysis, etc. + * struct dmub_hw_diagnostic_data - Hardware diagnostic data for the DMUB */ -struct dmub_diagnostic_data { +struct dmub_hw_diagnostic_data { uint32_t dmcub_version; uint32_t scratch[17]; uint32_t pc[DMUB_PC_SNAPSHOT_COUNT]; @@ -390,7 +412,6 @@ struct dmub_diagnostic_data { uint32_t outbox1_wptr; uint32_t outbox1_size; uint32_t gpint_datain0; - struct dmub_timeout_info timeout_info; uint8_t is_dmcub_enabled : 1; uint8_t is_dmcub_soft_reset : 1; uint8_t is_dmcub_secure_reset : 1; @@ -400,6 +421,17 @@ struct dmub_diagnostic_data { uint8_t is_pwait : 1; }; +/** + * struct dmub_diagnostic_data - Diagnostic data retrieved from DMCUB for + * debugging purposes, including logging, crash analysis, etc. + */ +struct dmub_diagnostic_data { + struct dmub_hw_diagnostic_data hw; + struct dmub_timeout_info first_timeout_info; + struct dmub_timeout_info latest_timeout_info; + struct dmub_trace_snapshot trace_snapshot; +}; + /** * struct dmub_preos_info - preos fw info before loading post os fw. */ @@ -537,7 +569,7 @@ struct dmub_srv_hw_funcs { void (*send_inbox0_cmd)(struct dmub_srv *dmub, union dmub_inbox0_data_register data); uint32_t (*get_current_time)(struct dmub_srv *dmub); - void (*get_diagnostic_data)(struct dmub_srv *dmub); + void (*get_diagnostic_data)(struct dmub_srv *dmub, struct dmub_hw_diagnostic_data *hw_data); bool (*get_preos_fw_info)(struct dmub_srv *dmub); bool (*should_detect)(struct dmub_srv *dmub); @@ -992,6 +1024,14 @@ enum dmub_status dmub_srv_set_skip_panel_power_sequence(struct dmub_srv *dmub, bool dmub_srv_get_outbox0_msg(struct dmub_srv *dmub, struct dmcub_trace_buf_entry *entry); +/** + * dmub_srv_get_diagnostic_data() - Get diagnostic data from the DMUB. + * @dmub: the dmub service + * + * Returns: + * true - if the diagnostic data was successfully retrieved + * false - otherwise + */ bool dmub_srv_get_diagnostic_data(struct dmub_srv *dmub); bool dmub_srv_should_detect(struct dmub_srv *dmub); @@ -1151,4 +1191,12 @@ bool dmub_srv_get_preos_info(struct dmub_srv *dmub); enum dmub_status dmub_srv_get_fw_meta_info_from_raw_fw(struct dmub_srv_fw_meta_info_params *params, struct dmub_fw_meta_info *fw_info_out); +/** + * dmub_srv_get_trace_snapshot() - Fetch the latest trace entries from the DMCUB trace buffer + * @dmub: the dmub service + * @trace_snapshot: output buffer for trace entries + * + */ +void dmub_srv_get_trace_snapshot(struct dmub_srv *dmub, struct dmub_trace_snapshot *trace_snapshot); + #endif /* _DMUB_SRV_H_ */ 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 0b152926f75b..08c23ca47094 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c @@ -416,72 +416,68 @@ 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) +void dmub_dcn20_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_hw_diagnostic_data *hw_data) { 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) + if (!dmub || !hw_data) return; - /* 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); + memset(hw_data, 0, sizeof(*hw_data)); + + hw_data->dmcub_version = dmub->fw_version; + + hw_data->scratch[0] = REG_READ(DMCUB_SCRATCH0); + hw_data->scratch[1] = REG_READ(DMCUB_SCRATCH1); + hw_data->scratch[2] = REG_READ(DMCUB_SCRATCH2); + hw_data->scratch[3] = REG_READ(DMCUB_SCRATCH3); + hw_data->scratch[4] = REG_READ(DMCUB_SCRATCH4); + hw_data->scratch[5] = REG_READ(DMCUB_SCRATCH5); + hw_data->scratch[6] = REG_READ(DMCUB_SCRATCH6); + hw_data->scratch[7] = REG_READ(DMCUB_SCRATCH7); + hw_data->scratch[8] = REG_READ(DMCUB_SCRATCH8); + hw_data->scratch[9] = REG_READ(DMCUB_SCRATCH9); + hw_data->scratch[10] = REG_READ(DMCUB_SCRATCH10); + hw_data->scratch[11] = REG_READ(DMCUB_SCRATCH11); + hw_data->scratch[12] = REG_READ(DMCUB_SCRATCH12); + hw_data->scratch[13] = REG_READ(DMCUB_SCRATCH13); + hw_data->scratch[14] = REG_READ(DMCUB_SCRATCH14); + hw_data->scratch[15] = REG_READ(DMCUB_SCRATCH15); + + hw_data->undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); + hw_data->inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); + hw_data->data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); + + hw_data->inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); + hw_data->inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); + hw_data->inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); + + hw_data->inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); + hw_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); + hw_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled); ASSERT(is_dmub_enabled <= 0xFF); - dmub->debug.is_dmcub_enabled = (uint8_t)is_dmub_enabled; + hw_data->is_dmcub_enabled = (uint8_t)is_dmub_enabled; REG_GET(DMCUB_CNTL, DMCUB_SOFT_RESET, &is_soft_reset); ASSERT(is_soft_reset <= 0xFF); - dmub->debug.is_dmcub_soft_reset = (uint8_t)is_soft_reset; + hw_data->is_dmcub_soft_reset = (uint8_t)is_soft_reset; REG_GET(DMCUB_SEC_CNTL, DMCUB_SEC_RESET_STATUS, &is_sec_reset); ASSERT(is_sec_reset <= 0xFF); - dmub->debug.is_dmcub_secure_reset = (uint8_t)is_sec_reset; + hw_data->is_dmcub_secure_reset = (uint8_t)is_sec_reset; REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled); ASSERT(is_traceport_enabled <= 0xFF); - dmub->debug.is_traceport_en = (uint8_t)is_traceport_enabled; + hw_data->is_traceport_en = (uint8_t)is_traceport_enabled; REG_GET(DMCUB_REGION3_CW0_TOP_ADDRESS, DMCUB_REGION3_CW0_ENABLE, &is_cw0_enabled); ASSERT(is_cw0_enabled <= 0xFF); - dmub->debug.is_cw0_enabled = (uint8_t)is_cw0_enabled; + hw_data->is_cw0_enabled = (uint8_t)is_cw0_enabled; REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled); ASSERT(is_cw6_enabled <= 0xFF); - dmub->debug.is_cw6_enabled = (uint8_t)is_cw6_enabled; + hw_data->is_cw6_enabled = (uint8_t)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 42c1fb4bc73f..fd89d341573b 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); +void dmub_dcn20_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_hw_diagnostic_data *hw_data); #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 478d79a6e246..cd0ba8d41357 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c @@ -418,82 +418,78 @@ 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) +void dmub_dcn31_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_hw_diagnostic_data *hw_data) { uint32_t is_dmub_enabled, is_soft_reset, is_sec_reset, is_pwait; uint32_t is_traceport_enabled, is_cw0_enabled, is_cw6_enabled; - struct dmub_timeout_info timeout = {0}; - if (!dmub) + if (!dmub || !hw_data) return; - /* 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); + memset(hw_data, 0, sizeof(*hw_data)); + + hw_data->dmcub_version = dmub->fw_version; + + hw_data->scratch[0] = REG_READ(DMCUB_SCRATCH0); + hw_data->scratch[1] = REG_READ(DMCUB_SCRATCH1); + hw_data->scratch[2] = REG_READ(DMCUB_SCRATCH2); + hw_data->scratch[3] = REG_READ(DMCUB_SCRATCH3); + hw_data->scratch[4] = REG_READ(DMCUB_SCRATCH4); + hw_data->scratch[5] = REG_READ(DMCUB_SCRATCH5); + hw_data->scratch[6] = REG_READ(DMCUB_SCRATCH6); + hw_data->scratch[7] = REG_READ(DMCUB_SCRATCH7); + hw_data->scratch[8] = REG_READ(DMCUB_SCRATCH8); + hw_data->scratch[9] = REG_READ(DMCUB_SCRATCH9); + hw_data->scratch[10] = REG_READ(DMCUB_SCRATCH10); + hw_data->scratch[11] = REG_READ(DMCUB_SCRATCH11); + hw_data->scratch[12] = REG_READ(DMCUB_SCRATCH12); + hw_data->scratch[13] = REG_READ(DMCUB_SCRATCH13); + hw_data->scratch[14] = REG_READ(DMCUB_SCRATCH14); + hw_data->scratch[15] = REG_READ(DMCUB_SCRATCH15); + + hw_data->undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); + hw_data->inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); + hw_data->data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); + + hw_data->inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); + hw_data->inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); + hw_data->inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); + + hw_data->inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); + hw_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); + hw_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); + + hw_data->outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR); + hw_data->outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR); + hw_data->outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE); REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled); ASSERT(is_dmub_enabled <= 0xFF); - dmub->debug.is_dmcub_enabled = (uint8_t)is_dmub_enabled; + hw_data->is_dmcub_enabled = (uint8_t)is_dmub_enabled; REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &is_pwait); ASSERT(is_pwait <= 0xFF); - dmub->debug.is_pwait = (uint8_t)is_pwait; + hw_data->is_pwait = (uint8_t)is_pwait; REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &is_soft_reset); ASSERT(is_soft_reset <= 0xFF); - dmub->debug.is_dmcub_soft_reset = (uint8_t)is_soft_reset; + hw_data->is_dmcub_soft_reset = (uint8_t)is_soft_reset; REG_GET(DMCUB_SEC_CNTL, DMCUB_SEC_RESET_STATUS, &is_sec_reset); ASSERT(is_sec_reset <= 0xFF); - dmub->debug.is_dmcub_secure_reset = (uint8_t)is_sec_reset; + hw_data->is_dmcub_secure_reset = (uint8_t)is_sec_reset; REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled); ASSERT(is_traceport_enabled <= 0xFF); - dmub->debug.is_traceport_en = (uint8_t)is_traceport_enabled; + hw_data->is_traceport_en = (uint8_t)is_traceport_enabled; REG_GET(DMCUB_REGION3_CW0_TOP_ADDRESS, DMCUB_REGION3_CW0_ENABLE, &is_cw0_enabled); ASSERT(is_cw0_enabled <= 0xFF); - dmub->debug.is_cw0_enabled = (uint8_t)is_cw0_enabled; + hw_data->is_cw0_enabled = (uint8_t)is_cw0_enabled; REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled); ASSERT(is_cw6_enabled <= 0xFF); - dmub->debug.is_cw6_enabled = (uint8_t)is_cw6_enabled; + hw_data->is_cw6_enabled = (uint8_t)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 1c43ef2bca66..ec878c58d09b 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); +void dmub_dcn31_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_hw_diagnostic_data *hw_data); 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 3f9fb9e05b79..0d585dc63364 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c @@ -437,77 +437,73 @@ 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) +void dmub_dcn32_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_hw_diagnostic_data *hw_data) { 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) + if (!dmub || !hw_data) return; - /* 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); + memset(hw_data, 0, sizeof(*hw_data)); + + hw_data->dmcub_version = dmub->fw_version; + + hw_data->scratch[0] = REG_READ(DMCUB_SCRATCH0); + hw_data->scratch[1] = REG_READ(DMCUB_SCRATCH1); + hw_data->scratch[2] = REG_READ(DMCUB_SCRATCH2); + hw_data->scratch[3] = REG_READ(DMCUB_SCRATCH3); + hw_data->scratch[4] = REG_READ(DMCUB_SCRATCH4); + hw_data->scratch[5] = REG_READ(DMCUB_SCRATCH5); + hw_data->scratch[6] = REG_READ(DMCUB_SCRATCH6); + hw_data->scratch[7] = REG_READ(DMCUB_SCRATCH7); + hw_data->scratch[8] = REG_READ(DMCUB_SCRATCH8); + hw_data->scratch[9] = REG_READ(DMCUB_SCRATCH9); + hw_data->scratch[10] = REG_READ(DMCUB_SCRATCH10); + hw_data->scratch[11] = REG_READ(DMCUB_SCRATCH11); + hw_data->scratch[12] = REG_READ(DMCUB_SCRATCH12); + hw_data->scratch[13] = REG_READ(DMCUB_SCRATCH13); + hw_data->scratch[14] = REG_READ(DMCUB_SCRATCH14); + hw_data->scratch[15] = REG_READ(DMCUB_SCRATCH15); + hw_data->scratch[16] = REG_READ(DMCUB_SCRATCH16); + + hw_data->undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); + hw_data->inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); + hw_data->data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); + + hw_data->inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); + hw_data->inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); + hw_data->inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); + + hw_data->inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); + hw_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); + hw_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); + + hw_data->outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR); + hw_data->outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR); + hw_data->outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE); REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled); ASSERT(is_dmub_enabled <= 0xFF); - dmub->debug.is_dmcub_enabled = (uint8_t)is_dmub_enabled; + hw_data->is_dmcub_enabled = (uint8_t)is_dmub_enabled; REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &is_pwait); ASSERT(is_pwait <= 0xFF); - dmub->debug.is_pwait = (uint8_t)is_pwait; + hw_data->is_pwait = (uint8_t)is_pwait; REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &is_soft_reset); ASSERT(is_soft_reset <= 0xFF); - dmub->debug.is_dmcub_soft_reset = (uint8_t)is_soft_reset; + hw_data->is_dmcub_soft_reset = (uint8_t)is_soft_reset; REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled); ASSERT(is_traceport_enabled <= 0xFF); - dmub->debug.is_traceport_en = (uint8_t)is_traceport_enabled; + hw_data->is_traceport_en = (uint8_t)is_traceport_enabled; REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled); ASSERT(is_cw6_enabled <= 0xFF); - dmub->debug.is_cw6_enabled = (uint8_t)is_cw6_enabled; + hw_data->is_cw6_enabled = (uint8_t)is_cw6_enabled; - dmub->debug.gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0); + hw_data->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 daf81027d663..ccf849e07b38 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h @@ -260,7 +260,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); +void dmub_dcn32_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_hw_diagnostic_data *hw_data); 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 69fb6084232e..bd7637276aa6 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c @@ -458,77 +458,73 @@ 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) +void dmub_dcn35_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_hw_diagnostic_data *hw_data) { 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) + if (!dmub || !hw_data) return; - /* 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); + memset(hw_data, 0, sizeof(*hw_data)); + + hw_data->dmcub_version = dmub->fw_version; + + hw_data->scratch[0] = REG_READ(DMCUB_SCRATCH0); + hw_data->scratch[1] = REG_READ(DMCUB_SCRATCH1); + hw_data->scratch[2] = REG_READ(DMCUB_SCRATCH2); + hw_data->scratch[3] = REG_READ(DMCUB_SCRATCH3); + hw_data->scratch[4] = REG_READ(DMCUB_SCRATCH4); + hw_data->scratch[5] = REG_READ(DMCUB_SCRATCH5); + hw_data->scratch[6] = REG_READ(DMCUB_SCRATCH6); + hw_data->scratch[7] = REG_READ(DMCUB_SCRATCH7); + hw_data->scratch[8] = REG_READ(DMCUB_SCRATCH8); + hw_data->scratch[9] = REG_READ(DMCUB_SCRATCH9); + hw_data->scratch[10] = REG_READ(DMCUB_SCRATCH10); + hw_data->scratch[11] = REG_READ(DMCUB_SCRATCH11); + hw_data->scratch[12] = REG_READ(DMCUB_SCRATCH12); + hw_data->scratch[13] = REG_READ(DMCUB_SCRATCH13); + hw_data->scratch[14] = REG_READ(DMCUB_SCRATCH14); + hw_data->scratch[15] = REG_READ(DMCUB_SCRATCH15); + hw_data->scratch[16] = REG_READ(DMCUB_SCRATCH16); + + hw_data->undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); + hw_data->inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); + hw_data->data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); + + hw_data->inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); + hw_data->inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); + hw_data->inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); + + hw_data->inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); + hw_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); + hw_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); + + hw_data->outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR); + hw_data->outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR); + hw_data->outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE); REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled); ASSERT(is_dmub_enabled <= 0xFF); - dmub->debug.is_dmcub_enabled = (uint8_t)is_dmub_enabled; + hw_data->is_dmcub_enabled = (uint8_t)is_dmub_enabled; REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &is_pwait); ASSERT(is_pwait <= 0xFF); - dmub->debug.is_pwait = (uint8_t)is_pwait; + hw_data->is_pwait = (uint8_t)is_pwait; REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &is_soft_reset); ASSERT(is_soft_reset <= 0xFF); - dmub->debug.is_dmcub_soft_reset = (uint8_t)is_soft_reset; + hw_data->is_dmcub_soft_reset = (uint8_t)is_soft_reset; REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled); ASSERT(is_traceport_enabled <= 0xFF); - dmub->debug.is_traceport_en = (uint8_t)is_traceport_enabled; + hw_data->is_traceport_en = (uint8_t)is_traceport_enabled; REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled); ASSERT(is_cw6_enabled <= 0xFF); - dmub->debug.is_cw6_enabled = (uint8_t)is_cw6_enabled; + hw_data->is_cw6_enabled = (uint8_t)is_cw6_enabled; - dmub->debug.gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0); + hw_data->gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0); } bool dmub_dcn35_get_preos_fw_info(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 92e6695a2c9b..869095284993 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); +void dmub_dcn35_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_hw_diagnostic_data *hw_data); void dmub_dcn35_configure_dmub_in_system_memory(struct dmub_srv *dmub); 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 3444eb7d7d81..02ab26516584 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c @@ -423,85 +423,81 @@ 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) +void dmub_dcn401_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_hw_diagnostic_data *hw_data) { uint32_t is_dmub_enabled, is_soft_reset, is_sec_reset, is_pwait; uint32_t is_traceport_enabled, is_cw0_enabled, is_cw6_enabled; - struct dmub_timeout_info timeout = {0}; - if (!dmub) + if (!dmub || !hw_data) return; - /* 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); + memset(hw_data, 0, sizeof(*hw_data)); + + hw_data->dmcub_version = dmub->fw_version; + + hw_data->scratch[0] = REG_READ(DMCUB_SCRATCH0); + hw_data->scratch[1] = REG_READ(DMCUB_SCRATCH1); + hw_data->scratch[2] = REG_READ(DMCUB_SCRATCH2); + hw_data->scratch[3] = REG_READ(DMCUB_SCRATCH3); + hw_data->scratch[4] = REG_READ(DMCUB_SCRATCH4); + hw_data->scratch[5] = REG_READ(DMCUB_SCRATCH5); + hw_data->scratch[6] = REG_READ(DMCUB_SCRATCH6); + hw_data->scratch[7] = REG_READ(DMCUB_SCRATCH7); + hw_data->scratch[8] = REG_READ(DMCUB_SCRATCH8); + hw_data->scratch[9] = REG_READ(DMCUB_SCRATCH9); + hw_data->scratch[10] = REG_READ(DMCUB_SCRATCH10); + hw_data->scratch[11] = REG_READ(DMCUB_SCRATCH11); + hw_data->scratch[12] = REG_READ(DMCUB_SCRATCH12); + hw_data->scratch[13] = REG_READ(DMCUB_SCRATCH13); + hw_data->scratch[14] = REG_READ(DMCUB_SCRATCH14); + hw_data->scratch[15] = REG_READ(DMCUB_SCRATCH15); + hw_data->scratch[16] = REG_READ(DMCUB_SCRATCH16); + + hw_data->undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); + hw_data->inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); + hw_data->data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); + + hw_data->inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); + hw_data->inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); + hw_data->inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); + + hw_data->inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); + hw_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); + hw_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); + + hw_data->outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR); + hw_data->outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR); + hw_data->outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE); REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled); ASSERT(is_dmub_enabled <= 0xFF); - dmub->debug.is_dmcub_enabled = (uint8_t)is_dmub_enabled; + hw_data->is_dmcub_enabled = (uint8_t)is_dmub_enabled; REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &is_pwait); ASSERT(is_pwait <= 0xFF); - dmub->debug.is_pwait = (uint8_t)is_pwait; + hw_data->is_pwait = (uint8_t)is_pwait; REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &is_soft_reset); ASSERT(is_soft_reset <= 0xFF); - dmub->debug.is_dmcub_soft_reset = (uint8_t)is_soft_reset; + hw_data->is_dmcub_soft_reset = (uint8_t)is_soft_reset; REG_GET(DMCUB_SEC_CNTL, DMCUB_SEC_RESET_STATUS, &is_sec_reset); ASSERT(is_sec_reset <= 0xFF); - dmub->debug.is_dmcub_secure_reset = (uint8_t)is_sec_reset; + hw_data->is_dmcub_secure_reset = (uint8_t)is_sec_reset; REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled); ASSERT(is_traceport_enabled <= 0xFF); - dmub->debug.is_traceport_en = (uint8_t)is_traceport_enabled; + hw_data->is_traceport_en = (uint8_t)is_traceport_enabled; REG_GET(DMCUB_REGION3_CW0_TOP_ADDRESS, DMCUB_REGION3_CW0_ENABLE, &is_cw0_enabled); ASSERT(is_cw0_enabled <= 0xFF); - dmub->debug.is_cw0_enabled = (uint8_t)is_cw0_enabled; + hw_data->is_cw0_enabled = (uint8_t)is_cw0_enabled; REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled); ASSERT(is_cw6_enabled <= 0xFF); - dmub->debug.is_cw6_enabled = (uint8_t)is_cw6_enabled; + hw_data->is_cw6_enabled = (uint8_t)is_cw6_enabled; - dmub->debug.gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0); + hw_data->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 88c3a44d67d9..de7840d93592 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.h @@ -264,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); +void dmub_dcn401_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_hw_diagnostic_data *hw_data); 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_dcn42.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn42.c index e86fcfc74985..53e70c682a77 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn42.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn42.c @@ -626,85 +626,81 @@ uint32_t dmub_dcn42_get_current_time(struct dmub_srv *dmub) return REG_READ(DMCUB_TIMER_CURRENT); } -void dmub_dcn42_get_diagnostic_data(struct dmub_srv *dmub) +void dmub_dcn42_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_hw_diagnostic_data *hw_data) { uint32_t is_dmub_enabled, is_soft_reset, is_sec_reset, is_pwait; uint32_t is_traceport_enabled, is_cw0_enabled, is_cw6_enabled; - struct dmub_timeout_info timeout = {0}; - if (!dmub) + if (!dmub || !hw_data) return; - /* 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); + memset(hw_data, 0, sizeof(*hw_data)); + + hw_data->dmcub_version = dmub->fw_version; + + hw_data->scratch[0] = REG_READ(DMCUB_SCRATCH0); + hw_data->scratch[1] = REG_READ(DMCUB_SCRATCH1); + hw_data->scratch[2] = REG_READ(DMCUB_SCRATCH2); + hw_data->scratch[3] = REG_READ(DMCUB_SCRATCH3); + hw_data->scratch[4] = REG_READ(DMCUB_SCRATCH4); + hw_data->scratch[5] = REG_READ(DMCUB_SCRATCH5); + hw_data->scratch[6] = REG_READ(DMCUB_SCRATCH6); + hw_data->scratch[7] = REG_READ(DMCUB_SCRATCH7); + hw_data->scratch[8] = REG_READ(DMCUB_SCRATCH8); + hw_data->scratch[9] = REG_READ(DMCUB_SCRATCH9); + hw_data->scratch[10] = REG_READ(DMCUB_SCRATCH10); + hw_data->scratch[11] = REG_READ(DMCUB_SCRATCH11); + hw_data->scratch[12] = REG_READ(DMCUB_SCRATCH12); + hw_data->scratch[13] = REG_READ(DMCUB_SCRATCH13); + hw_data->scratch[14] = REG_READ(DMCUB_SCRATCH14); + hw_data->scratch[15] = REG_READ(DMCUB_SCRATCH15); + hw_data->scratch[16] = REG_READ(DMCUB_SCRATCH16); + + hw_data->undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); + hw_data->inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); + hw_data->data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); + + hw_data->inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); + hw_data->inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); + hw_data->inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); + + hw_data->inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); + hw_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); + hw_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); + + hw_data->outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR); + hw_data->outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR); + hw_data->outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE); REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled); ASSERT(is_dmub_enabled <= 0xFF); - dmub->debug.is_dmcub_enabled = (uint8_t)is_dmub_enabled; + hw_data->is_dmcub_enabled = (uint8_t)is_dmub_enabled; REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &is_pwait); ASSERT(is_pwait <= 0xFF); - dmub->debug.is_pwait = (uint8_t)is_pwait; + hw_data->is_pwait = (uint8_t)is_pwait; REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &is_soft_reset); ASSERT(is_soft_reset <= 0xFF); - dmub->debug.is_dmcub_soft_reset = (uint8_t)is_soft_reset; + hw_data->is_dmcub_soft_reset = (uint8_t)is_soft_reset; REG_GET(DMCUB_SEC_CNTL, DMCUB_SEC_RESET_STATUS, &is_sec_reset); ASSERT(is_sec_reset <= 0xFF); - dmub->debug.is_dmcub_secure_reset = (uint8_t)is_sec_reset; + hw_data->is_dmcub_secure_reset = (uint8_t)is_sec_reset; REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled); ASSERT(is_traceport_enabled <= 0xFF); - dmub->debug.is_traceport_en = (uint8_t)is_traceport_enabled; + hw_data->is_traceport_en = (uint8_t)is_traceport_enabled; REG_GET(DMCUB_REGION3_CW0_TOP_ADDRESS, DMCUB_REGION3_CW0_ENABLE, &is_cw0_enabled); ASSERT(is_cw0_enabled <= 0xFF); - dmub->debug.is_cw0_enabled = (uint8_t)is_cw0_enabled; + hw_data->is_cw0_enabled = (uint8_t)is_cw0_enabled; REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled); ASSERT(is_cw6_enabled <= 0xFF); - dmub->debug.is_cw6_enabled = (uint8_t)is_cw6_enabled; + hw_data->is_cw6_enabled = (uint8_t)is_cw6_enabled; - dmub->debug.gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0); + hw_data->gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0); } bool dmub_dcn42_get_preos_fw_info(struct dmub_srv *dmub) diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn42.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn42.h index c53f7691d1a8..c879e94272d7 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn42.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn42.h @@ -297,7 +297,7 @@ union dmub_fw_boot_options dmub_dcn42_get_fw_boot_option(struct dmub_srv *dmub); /* Timing and diagnostics */ uint32_t dmub_dcn42_get_current_time(struct dmub_srv *dmub); -void dmub_dcn42_get_diagnostic_data(struct dmub_srv *dmub); +void dmub_dcn42_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_hw_diagnostic_data *hw_data); bool dmub_dcn42_get_preos_fw_info(struct dmub_srv *dmub); #endif /* _DMUB_DCN42_H_ */ diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn60.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn60.c index 5c524f8d3fdf..8c3cc51c07a3 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn60.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn60.c @@ -469,85 +469,81 @@ uint32_t dmub_dcn60_get_current_time(struct dmub_srv *dmub) return REG_READ(DMCUB_TIMER_CURRENT); } -void dmub_dcn60_get_diagnostic_data(struct dmub_srv *dmub) +void dmub_dcn60_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_hw_diagnostic_data *hw_data) { uint32_t is_dmub_enabled, is_soft_reset, is_sec_reset, is_pwait; uint32_t is_traceport_enabled, is_cw0_enabled, is_cw6_enabled; - struct dmub_timeout_info timeout = {0}; - if (!dmub) + if (!dmub || !hw_data) return; - /* 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); + memset(hw_data, 0, sizeof(*hw_data)); + + hw_data->dmcub_version = dmub->fw_version; + + hw_data->scratch[0] = REG_READ(DMCUB_SCRATCH0); + hw_data->scratch[1] = REG_READ(DMCUB_SCRATCH1); + hw_data->scratch[2] = REG_READ(DMCUB_SCRATCH2); + hw_data->scratch[3] = REG_READ(DMCUB_SCRATCH3); + hw_data->scratch[4] = REG_READ(DMCUB_SCRATCH4); + hw_data->scratch[5] = REG_READ(DMCUB_SCRATCH5); + hw_data->scratch[6] = REG_READ(DMCUB_SCRATCH6); + hw_data->scratch[7] = REG_READ(DMCUB_SCRATCH7); + hw_data->scratch[8] = REG_READ(DMCUB_SCRATCH8); + hw_data->scratch[9] = REG_READ(DMCUB_SCRATCH9); + hw_data->scratch[10] = REG_READ(DMCUB_SCRATCH10); + hw_data->scratch[11] = REG_READ(DMCUB_SCRATCH11); + hw_data->scratch[12] = REG_READ(DMCUB_SCRATCH12); + hw_data->scratch[13] = REG_READ(DMCUB_SCRATCH13); + hw_data->scratch[14] = REG_READ(DMCUB_SCRATCH14); + hw_data->scratch[15] = REG_READ(DMCUB_SCRATCH15); + hw_data->scratch[16] = REG_READ(DMCUB_SCRATCH16); + + hw_data->undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); + hw_data->inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); + hw_data->data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); + + hw_data->inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); + hw_data->inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); + hw_data->inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); + + hw_data->inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); + hw_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); + hw_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); + + hw_data->outbox1_rptr = REG_READ(DMCUB_OUTBOX1_RPTR); + hw_data->outbox1_wptr = REG_READ(DMCUB_OUTBOX1_WPTR); + hw_data->outbox1_size = REG_READ(DMCUB_OUTBOX1_SIZE); REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled); ASSERT(is_dmub_enabled <= 0xFF); - dmub->debug.is_dmcub_enabled = (uint8_t)is_dmub_enabled; + hw_data->is_dmcub_enabled = (uint8_t)is_dmub_enabled; REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &is_pwait); ASSERT(is_pwait <= 0xFF); - dmub->debug.is_pwait = (uint8_t)is_pwait; + hw_data->is_pwait = (uint8_t)is_pwait; REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &is_soft_reset); ASSERT(is_soft_reset <= 0xFF); - dmub->debug.is_dmcub_soft_reset = (uint8_t)is_soft_reset; + hw_data->is_dmcub_soft_reset = (uint8_t)is_soft_reset; REG_GET(DMCUB_SEC_CNTL, DMCUB_SEC_RESET_STATUS, &is_sec_reset); ASSERT(is_sec_reset <= 0xFF); - dmub->debug.is_dmcub_secure_reset = (uint8_t)is_sec_reset; + hw_data->is_dmcub_secure_reset = (uint8_t)is_sec_reset; REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled); ASSERT(is_traceport_enabled <= 0xFF); - dmub->debug.is_traceport_en = (uint8_t)is_traceport_enabled; + hw_data->is_traceport_en = (uint8_t)is_traceport_enabled; REG_GET(DMCUB_REGION3_CW0_TOP_ADDRESS, DMCUB_REGION3_CW0_ENABLE, &is_cw0_enabled); ASSERT(is_cw0_enabled <= 0xFF); - dmub->debug.is_cw0_enabled = (uint8_t)is_cw0_enabled; + hw_data->is_cw0_enabled = (uint8_t)is_cw0_enabled; REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled); ASSERT(is_cw6_enabled <= 0xFF); - dmub->debug.is_cw6_enabled = (uint8_t)is_cw6_enabled; + hw_data->is_cw6_enabled = (uint8_t)is_cw6_enabled; - dmub->debug.gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0); + hw_data->gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0); } void dmub_dcn60_configure_dmub_in_system_memory(struct dmub_srv *dmub) { diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn60.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn60.h index 5007ed1c19d7..238cba46d366 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn60.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn60.h @@ -277,7 +277,7 @@ void dmub_dcn60_set_outbox0_rptr(struct dmub_srv *dmub, uint32_t rptr_offset); uint32_t dmub_dcn60_get_current_time(struct dmub_srv *dmub); -void dmub_dcn60_get_diagnostic_data(struct dmub_srv *dmub); +void dmub_dcn60_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_hw_diagnostic_data *hw_data); void dmub_dcn60_configure_dmub_in_system_memory(struct dmub_srv *dmub); void dmub_dcn60_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 dd868e38e0b0..41b14b137643 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c @@ -1315,11 +1315,63 @@ 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); } +void dmub_srv_get_trace_snapshot(struct dmub_srv *dmub, struct dmub_trace_snapshot *trace_snapshot) +{ + const unsigned int snapshot_max_entry_count = + sizeof(trace_snapshot->traces) / sizeof(struct dmcub_trace_buf_entry); + + struct dmub_trace_buf_header *trace_buf_header; + struct dmcub_trace_buf_entry *trace_buf; + unsigned int trace_buf_max_entry_count; + unsigned int entry_count, start_idx, first_chunk_entry_count; + + if (!dmub || !dmub->fb_info || !trace_snapshot) + return; + + // capture last trace entries from the DMCUB trace buffer + trace_buf_header = (struct dmub_trace_buf_header *)dmub->fb_info->fb[DMUB_WINDOW_5_TRACEBUFF].cpu_addr; + trace_buf_max_entry_count = dmub->fb_info->fb[DMUB_WINDOW_5_TRACEBUFF].size == 0 ? 0 : + (dmub->fb_info->fb[DMUB_WINDOW_5_TRACEBUFF].size - + sizeof(struct dmub_trace_buf_header)) / + sizeof(struct dmcub_trace_buf_entry); + trace_buf_max_entry_count = trace_buf_max_entry_count > DMUB_TRACE_BUFFER_SIZE ? + DMUB_TRACE_BUFFER_SIZE : trace_buf_max_entry_count; + + if (trace_buf_header && trace_buf_max_entry_count > 0) { + entry_count = trace_buf_header->entry_count; + start_idx = 0; + if (entry_count >= snapshot_max_entry_count) { + start_idx = (entry_count - snapshot_max_entry_count) % trace_buf_max_entry_count; + } + + trace_buf = (struct dmcub_trace_buf_entry *)(trace_buf_header + 1); + + if (start_idx + snapshot_max_entry_count <= trace_buf_max_entry_count) { + // contiguous + memcpy(trace_snapshot->traces, + &trace_buf[start_idx], + sizeof(struct dmcub_trace_buf_entry) * snapshot_max_entry_count); + } else { + // wraparound case + first_chunk_entry_count = trace_buf_max_entry_count - start_idx; + + memcpy(trace_snapshot->traces, + &trace_buf[start_idx], + sizeof(struct dmcub_trace_buf_entry) * first_chunk_entry_count); + memcpy(&trace_snapshot->traces[first_chunk_entry_count], + &trace_buf[0], + sizeof(struct dmcub_trace_buf_entry) * (snapshot_max_entry_count - first_chunk_entry_count)); + } + } +} + bool dmub_srv_get_diagnostic_data(struct dmub_srv *dmub) { if (!dmub || !dmub->hw_funcs.get_diagnostic_data) return false; - dmub->hw_funcs.get_diagnostic_data(dmub); + + dmub->hw_funcs.get_diagnostic_data(dmub, &dmub->debug.hw); + dmub_srv_get_trace_snapshot(dmub, &dmub->debug.trace_snapshot); return true; } -- 2.55.0
