Commit c435bce6 authored by Alvin Lee's avatar Alvin Lee Committed by Alex Deucher

drm/amd/display: Add extra DMUB logging to track message timeout

[Description]
- Add logging for first DMUB inbox message that timed out to diagnostic
  data
- It is useful to track the first failed message for debug purposes
  because once DMUB becomes hung (typically on a message), it will
  remain hung and all subsequent messages. In these cases we're
  interested in knowing which is the first message that failed.
Reviewed-by: default avatarJosip Pavic <josip.pavic@amd.com>
Acked-by: default avatarRoman Li <roman.li@amd.com>
Signed-off-by: default avatarAlvin Lee <alvin.lee2@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent de2d1105
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
* *
*/ */
#include "dm_services.h"
#include "dc.h" #include "dc.h"
#include "dc_dmub_srv.h" #include "dc_dmub_srv.h"
#include "../dmub/dmub_srv.h" #include "../dmub/dmub_srv.h"
...@@ -198,6 +199,11 @@ bool dc_dmub_srv_wait_for_idle(struct dc_dmub_srv *dc_dmub_srv, ...@@ -198,6 +199,11 @@ bool dc_dmub_srv_wait_for_idle(struct dc_dmub_srv *dc_dmub_srv,
if (status != DMUB_STATUS_OK) { if (status != DMUB_STATUS_OK) {
DC_LOG_DEBUG("No reply for DMUB command: status=%d\n", status); DC_LOG_DEBUG("No reply for DMUB command: status=%d\n", status);
if (!dmub->debug.timeout_occured) {
dmub->debug.timeout_occured = true;
dmub->debug.timeout_cmd = *cmd_list;
dmub->debug.timestamp = dm_get_timestamp(dc_dmub_srv->ctx);
}
dc_dmub_srv_log_diagnostic_data(dc_dmub_srv); dc_dmub_srv_log_diagnostic_data(dc_dmub_srv);
return false; return false;
} }
...@@ -904,6 +910,7 @@ bool dc_dmub_srv_get_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv, struct dmu ...@@ -904,6 +910,7 @@ bool dc_dmub_srv_get_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv, struct dmu
void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv) void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv)
{ {
struct dmub_diagnostic_data diag_data = {0}; struct dmub_diagnostic_data diag_data = {0};
uint32_t i;
if (!dc_dmub_srv || !dc_dmub_srv->dmub) { if (!dc_dmub_srv || !dc_dmub_srv->dmub) {
DC_LOG_ERROR("%s: invalid parameters.", __func__); DC_LOG_ERROR("%s: invalid parameters.", __func__);
...@@ -935,7 +942,8 @@ void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv) ...@@ -935,7 +942,8 @@ void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv)
DC_LOG_DEBUG(" scratch [13] : %08x", diag_data.scratch[13]); DC_LOG_DEBUG(" scratch [13] : %08x", diag_data.scratch[13]);
DC_LOG_DEBUG(" scratch [14] : %08x", diag_data.scratch[14]); DC_LOG_DEBUG(" scratch [14] : %08x", diag_data.scratch[14]);
DC_LOG_DEBUG(" scratch [15] : %08x", diag_data.scratch[15]); DC_LOG_DEBUG(" scratch [15] : %08x", diag_data.scratch[15]);
DC_LOG_DEBUG(" pc : %08x", diag_data.pc); for (i = 0; i < DMUB_PC_SNAPSHOT_COUNT; i++)
DC_LOG_DEBUG(" pc[%d] : %08x", i, diag_data.pc[i]);
DC_LOG_DEBUG(" unk_fault_addr : %08x", diag_data.undefined_address_fault_addr); DC_LOG_DEBUG(" unk_fault_addr : %08x", diag_data.undefined_address_fault_addr);
DC_LOG_DEBUG(" inst_fault_addr : %08x", diag_data.inst_fetch_fault_addr); DC_LOG_DEBUG(" inst_fault_addr : %08x", diag_data.inst_fetch_fault_addr);
DC_LOG_DEBUG(" data_fault_addr : %08x", diag_data.data_write_fault_addr); DC_LOG_DEBUG(" data_fault_addr : %08x", diag_data.data_write_fault_addr);
......
...@@ -71,6 +71,8 @@ ...@@ -71,6 +71,8 @@
extern "C" { extern "C" {
#endif #endif
#define DMUB_PC_SNAPSHOT_COUNT 10
/* Forward declarations */ /* Forward declarations */
struct dmub_srv; struct dmub_srv;
struct dmub_srv_common_regs; struct dmub_srv_common_regs;
...@@ -299,6 +301,17 @@ struct dmub_srv_hw_params { ...@@ -299,6 +301,17 @@ struct dmub_srv_hw_params {
enum dmub_ips_disable_type disable_ips; enum dmub_ips_disable_type disable_ips;
}; };
/**
* struct dmub_srv_debug - Debug info for dmub_srv
* @timeout_occured: Indicates a timeout occured on any message from driver to dmub
* @timeout_cmd: first cmd sent from driver that timed out - subsequent timeouts are not stored
*/
struct dmub_srv_debug {
bool timeout_occured;
union dmub_rb_cmd timeout_cmd;
unsigned long long timestamp;
};
/** /**
* struct dmub_diagnostic_data - Diagnostic data retrieved from DMCUB for * struct dmub_diagnostic_data - Diagnostic data retrieved from DMCUB for
* debugging purposes, including logging, crash analysis, etc. * debugging purposes, including logging, crash analysis, etc.
...@@ -306,7 +319,7 @@ struct dmub_srv_hw_params { ...@@ -306,7 +319,7 @@ struct dmub_srv_hw_params {
struct dmub_diagnostic_data { struct dmub_diagnostic_data {
uint32_t dmcub_version; uint32_t dmcub_version;
uint32_t scratch[17]; uint32_t scratch[17];
uint32_t pc; uint32_t pc[DMUB_PC_SNAPSHOT_COUNT];
uint32_t undefined_address_fault_addr; uint32_t undefined_address_fault_addr;
uint32_t inst_fetch_fault_addr; uint32_t inst_fetch_fault_addr;
uint32_t data_write_fault_addr; uint32_t data_write_fault_addr;
...@@ -317,6 +330,7 @@ struct dmub_diagnostic_data { ...@@ -317,6 +330,7 @@ struct dmub_diagnostic_data {
uint32_t inbox0_wptr; uint32_t inbox0_wptr;
uint32_t inbox0_size; uint32_t inbox0_size;
uint32_t gpint_datain0; uint32_t gpint_datain0;
struct dmub_srv_debug timeout_info;
uint8_t is_dmcub_enabled : 1; uint8_t is_dmcub_enabled : 1;
uint8_t is_dmcub_soft_reset : 1; uint8_t is_dmcub_soft_reset : 1;
uint8_t is_dmcub_secure_reset : 1; uint8_t is_dmcub_secure_reset : 1;
...@@ -506,6 +520,7 @@ struct dmub_srv { ...@@ -506,6 +520,7 @@ struct dmub_srv {
struct dmub_visual_confirm_color visual_confirm_color; struct dmub_visual_confirm_color visual_confirm_color;
enum dmub_srv_power_state_type power_state; enum dmub_srv_power_state_type power_state;
struct dmub_srv_debug debug;
}; };
/** /**
......
...@@ -472,4 +472,5 @@ void dmub_dcn20_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnosti ...@@ -472,4 +472,5 @@ void dmub_dcn20_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnosti
REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_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->is_cw6_enabled = is_cw6_enabled;
diag_data->timeout_info = dmub->debug;
} }
...@@ -466,6 +466,7 @@ void dmub_dcn31_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnosti ...@@ -466,6 +466,7 @@ void dmub_dcn31_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnosti
REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_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->is_cw6_enabled = is_cw6_enabled;
diag_data->timeout_info = dmub->debug;
} }
bool dmub_dcn31_should_detect(struct dmub_srv *dmub) bool dmub_dcn31_should_detect(struct dmub_srv *dmub)
......
...@@ -478,6 +478,8 @@ void dmub_dcn32_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnosti ...@@ -478,6 +478,8 @@ void dmub_dcn32_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnosti
diag_data->is_cw6_enabled = is_cw6_enabled; diag_data->is_cw6_enabled = is_cw6_enabled;
diag_data->gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0); diag_data->gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0);
diag_data->timeout_info = dmub->debug;
} }
void dmub_dcn32_configure_dmub_in_system_memory(struct dmub_srv *dmub) void dmub_dcn32_configure_dmub_in_system_memory(struct dmub_srv *dmub)
{ {
......
...@@ -516,6 +516,7 @@ void dmub_dcn35_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnosti ...@@ -516,6 +516,7 @@ void dmub_dcn35_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnosti
diag_data->is_cw6_enabled = is_cw6_enabled; diag_data->is_cw6_enabled = is_cw6_enabled;
diag_data->gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0); diag_data->gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0);
diag_data->timeout_info = dmub->debug;
} }
void dmub_dcn35_configure_dmub_in_system_memory(struct dmub_srv *dmub) void dmub_dcn35_configure_dmub_in_system_memory(struct dmub_srv *dmub)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment