From: Meenakshikumar Somasundaram <[email protected]>

[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 <[email protected]>
Signed-off-by: Meenakshikumar Somasundaram <[email protected]>
Signed-off-by: Wayne Lin <[email protected]>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  5 +++
 drivers/gpu/drm/amd/display/dc/dc.h           |  2 +
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  | 21 ++++++++++
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h  |  7 ++++
 drivers/gpu/drm/amd/display/dmub/dmub_srv.h   | 25 ++++++++++++
 .../gpu/drm/amd/display/dmub/src/dmub_dcn35.c | 39 +++++++++++++++++++
 .../gpu/drm/amd/display/dmub/src/dmub_dcn35.h |  2 +
 .../gpu/drm/amd/display/dmub/src/dmub_srv.c   |  9 +++++
 8 files changed, 110 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 2eb02345dadd..6ef9dd9ab7a3 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -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);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index b80bcbf7ae13..82ce1fbec7d8 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -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"
 
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 4b20c01bf646..fffbf1983143 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -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);
+       }
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h 
b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
index 9bb00d48fd5e..72e0a41f39f0 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
@@ -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_ */
diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h 
b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
index f25c2fc2f98f..9d0168986fe7 100644
--- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dmub/dmub_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_ */
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 b40482dbd6ad..e13557ed97be 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c
@@ -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:
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 39fcb7275da5..92e6695a2c9b 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.h
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.h
@@ -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_ */
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 0244c9b44ecc..a657efda89ce 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
@@ -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);
+}
-- 
2.43.0

Reply via email to