mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 08:02:27 +02:00
drm/amd/display: Add dc interface to log pre os firmware information
[Why] Pre os firmware information is useful to debug pre os to post os fw transition issues. [How] Add dc interface dc_log_preos_dmcub_info() to log pre os firmware information. Reviewed-by: Cruise Hung <cruise.hung@amd.com> Signed-off-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com> Signed-off-by: Wayne Lin <wayne.lin@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
14bb17cc37
commit
fb3896c18b
|
|
@ -6401,3 +6401,8 @@ void dc_get_underflow_debug_data_for_otg(struct dc *dc, int primary_otg_inst,
|
|||
if (dc->hwss.get_underflow_debug_data)
|
||||
dc->hwss.get_underflow_debug_data(dc, tg, out_data);
|
||||
}
|
||||
|
||||
void dc_log_preos_dmcub_info(const struct dc *dc)
|
||||
{
|
||||
dc_dmub_srv_log_preos_dmcub_info(dc->ctx->dmub_srv);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2727,6 +2727,8 @@ unsigned int dc_get_det_buffer_size_from_state(const struct dc_state *context);
|
|||
|
||||
bool dc_get_host_router_index(const struct dc_link *link, unsigned int *host_router_index);
|
||||
|
||||
void dc_log_preos_dmcub_info(const struct dc *dc);
|
||||
|
||||
/* DSC Interfaces */
|
||||
#include "dc_dsc.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -2344,3 +2344,24 @@ void dc_dmub_srv_release_hw(const struct dc *dc)
|
|||
|
||||
dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
|
||||
}
|
||||
|
||||
void dc_dmub_srv_log_preos_dmcub_info(struct dc_dmub_srv *dc_dmub_srv)
|
||||
{
|
||||
struct dmub_srv *dmub;
|
||||
|
||||
if (!dc_dmub_srv || !dc_dmub_srv->dmub)
|
||||
return;
|
||||
|
||||
dmub = dc_dmub_srv->dmub;
|
||||
|
||||
if (dmub_srv_get_preos_info(dmub)) {
|
||||
DC_LOG_DEBUG("%s: PreOS DMCUB Info", __func__);
|
||||
DC_LOG_DEBUG("fw_version : 0x%08x", dmub->preos_info.fw_version);
|
||||
DC_LOG_DEBUG("boot_options : 0x%08x", dmub->preos_info.boot_options);
|
||||
DC_LOG_DEBUG("boot_status : 0x%08x", dmub->preos_info.boot_status);
|
||||
DC_LOG_DEBUG("trace_buffer_phy_addr : 0x%016llx", dmub->preos_info.trace_buffer_phy_addr);
|
||||
DC_LOG_DEBUG("trace_buffer_size_bytes : 0x%08x", dmub->preos_info.trace_buffer_size);
|
||||
DC_LOG_DEBUG("fb_base : 0x%016llx", dmub->preos_info.fb_base);
|
||||
DC_LOG_DEBUG("fb_offset : 0x%016llx", dmub->preos_info.fb_offset);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -367,4 +367,11 @@ bool dc_dmub_srv_is_cursor_offload_enabled(const struct dc *dc);
|
|||
* @dc - pointer to DC object
|
||||
*/
|
||||
void dc_dmub_srv_release_hw(const struct dc *dc);
|
||||
|
||||
/**
|
||||
* dc_dmub_srv_log_preos_dmcub_info() - Logs preos dmcub fw info.
|
||||
*
|
||||
* @dc - pointer to DC object
|
||||
*/
|
||||
void dc_dmub_srv_log_preos_dmcub_info(struct dc_dmub_srv *dc_dmub_srv);
|
||||
#endif /* _DMUB_DC_SRV_H_ */
|
||||
|
|
|
|||
|
|
@ -363,6 +363,19 @@ struct dmub_diagnostic_data {
|
|||
uint8_t is_pwait : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dmub_preos_info - preos fw info before loading post os fw.
|
||||
*/
|
||||
struct dmub_preos_info {
|
||||
uint64_t fb_base;
|
||||
uint64_t fb_offset;
|
||||
uint64_t trace_buffer_phy_addr;
|
||||
uint32_t trace_buffer_size;
|
||||
uint32_t fw_version;
|
||||
uint32_t boot_status;
|
||||
uint32_t boot_options;
|
||||
};
|
||||
|
||||
struct dmub_srv_inbox {
|
||||
/* generic status */
|
||||
uint64_t num_submitted;
|
||||
|
|
@ -488,6 +501,7 @@ struct dmub_srv_hw_funcs {
|
|||
uint32_t (*get_current_time)(struct dmub_srv *dmub);
|
||||
|
||||
void (*get_diagnostic_data)(struct dmub_srv *dmub);
|
||||
bool (*get_preos_fw_info)(struct dmub_srv *dmub);
|
||||
|
||||
bool (*should_detect)(struct dmub_srv *dmub);
|
||||
void (*init_reg_offsets)(struct dmub_srv *dmub, struct dc_context *ctx);
|
||||
|
|
@ -588,6 +602,7 @@ struct dmub_srv {
|
|||
enum dmub_srv_power_state_type power_state;
|
||||
struct dmub_diagnostic_data debug;
|
||||
struct dmub_fb lsdma_rb_fb;
|
||||
struct dmub_preos_info preos_info;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1073,4 +1088,14 @@ enum dmub_status dmub_srv_wait_for_inbox_free(struct dmub_srv *dmub,
|
|||
*/
|
||||
enum dmub_status dmub_srv_update_inbox_status(struct dmub_srv *dmub);
|
||||
|
||||
/**
|
||||
* dmub_srv_get_preos_info() - retrieves preos fw info
|
||||
* @dmub: the dmub service
|
||||
*
|
||||
* Return:
|
||||
* true - preos fw info retrieved successfully
|
||||
* false - preos fw info not retrieved successfully
|
||||
*/
|
||||
bool dmub_srv_get_preos_info(struct dmub_srv *dmub);
|
||||
|
||||
#endif /* _DMUB_SRV_H_ */
|
||||
|
|
|
|||
|
|
@ -521,6 +521,45 @@ void dmub_dcn35_get_diagnostic_data(struct dmub_srv *dmub)
|
|||
|
||||
dmub->debug.gpint_datain0 = REG_READ(DMCUB_GPINT_DATAIN0);
|
||||
}
|
||||
|
||||
bool dmub_dcn35_get_preos_fw_info(struct dmub_srv *dmub)
|
||||
{
|
||||
uint64_t region3_cw5_offset;
|
||||
uint32_t top_addr, top_addr_enable, offset_low;
|
||||
uint32_t offset_high, base_addr, fw_version;
|
||||
bool is_vbios_fw = false;
|
||||
|
||||
memset(&dmub->preos_info, 0, sizeof(dmub->preos_info));
|
||||
|
||||
fw_version = REG_READ(DMCUB_SCRATCH1);
|
||||
is_vbios_fw = ((fw_version >> 6) & 0x01) ? true : false;
|
||||
if (!is_vbios_fw)
|
||||
return false;
|
||||
|
||||
dmub->preos_info.boot_status = REG_READ(DMCUB_SCRATCH0);
|
||||
dmub->preos_info.fw_version = REG_READ(DMCUB_SCRATCH1);
|
||||
dmub->preos_info.boot_options = REG_READ(DMCUB_SCRATCH14);
|
||||
REG_GET(DMCUB_REGION3_CW5_TOP_ADDRESS,
|
||||
DMCUB_REGION3_CW5_ENABLE, &top_addr_enable);
|
||||
if (top_addr_enable) {
|
||||
dmub_dcn35_get_fb_base_offset(dmub,
|
||||
&dmub->preos_info.fb_base, &dmub->preos_info.fb_offset);
|
||||
offset_low = REG_READ(DMCUB_REGION3_CW5_OFFSET);
|
||||
offset_high = REG_READ(DMCUB_REGION3_CW5_OFFSET_HIGH);
|
||||
region3_cw5_offset = ((uint64_t)offset_high << 32) | offset_low;
|
||||
dmub->preos_info.trace_buffer_phy_addr = region3_cw5_offset
|
||||
- dmub->preos_info.fb_base + dmub->preos_info.fb_offset;
|
||||
|
||||
REG_GET(DMCUB_REGION3_CW5_TOP_ADDRESS,
|
||||
DMCUB_REGION3_CW5_TOP_ADDRESS, &top_addr);
|
||||
base_addr = REG_READ(DMCUB_REGION3_CW5_BASE_ADDRESS) & 0x1FFFFFFF;
|
||||
dmub->preos_info.trace_buffer_size =
|
||||
(top_addr > base_addr) ? (top_addr - base_addr + 1) : 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dmub_dcn35_configure_dmub_in_system_memory(struct dmub_srv *dmub)
|
||||
{
|
||||
/* DMCUB_REGION3_TMR_AXI_SPACE values:
|
||||
|
|
|
|||
|
|
@ -285,4 +285,6 @@ bool dmub_dcn35_is_hw_powered_up(struct dmub_srv *dmub);
|
|||
|
||||
void dmub_srv_dcn35_regs_init(struct dmub_srv *dmub, struct dc_context *ctx);
|
||||
|
||||
bool dmub_dcn35_get_preos_fw_info(struct dmub_srv *dmub);
|
||||
|
||||
#endif /* _DMUB_DCN35_H_ */
|
||||
|
|
|
|||
|
|
@ -359,6 +359,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
|
|||
|
||||
funcs->get_current_time = dmub_dcn35_get_current_time;
|
||||
funcs->get_diagnostic_data = dmub_dcn35_get_diagnostic_data;
|
||||
funcs->get_preos_fw_info = dmub_dcn35_get_preos_fw_info;
|
||||
|
||||
funcs->init_reg_offsets = dmub_srv_dcn35_regs_init;
|
||||
if (asic == DMUB_ASIC_DCN351)
|
||||
|
|
@ -1372,3 +1373,11 @@ enum dmub_status dmub_srv_update_inbox_status(struct dmub_srv *dmub)
|
|||
|
||||
return DMUB_STATUS_OK;
|
||||
}
|
||||
|
||||
bool dmub_srv_get_preos_info(struct dmub_srv *dmub)
|
||||
{
|
||||
if (!dmub || !dmub->hw_funcs.get_preos_fw_info)
|
||||
return false;
|
||||
|
||||
return dmub->hw_funcs.get_preos_fw_info(dmub);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user