From: "Leo (Hanghong) Ma" <hanghong...@amd.com>

[Why]
We want to log DMCUB trace buffer events as Linux kernel traces.

[How]
Register an IRQ handler for DMCUB outbox0 interrupt in amdgpu_dm,
and log the messages in the DMCUB tracebuffer to a new DMCUB
TRACE_EVENT as soon as we receive the outbox0 IRQ from DMCUB FW.

Signed-off-by: Leo (Hanghong) Ma <hanghong...@amd.com>
Reviewed-by: Harry Wentland <harry.wentl...@amd.com>
Acked-by: Solomon Chiu <solomon.c...@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 48 +++++++++++++++++++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  9 ++++
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 12 ++++-
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 20 ++++++++
 .../amd/display/amdgpu_dm/amdgpu_dm_trace.h   | 21 ++++++++
 .../display/dc/irq/dcn21/irq_service_dcn21.c  | 32 ++++++++++++-
 .../display/dc/irq/dcn30/irq_service_dcn30.c  | 32 ++++++++++++-
 7 files changed, 170 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 8b464debc1ef..36100eeefb3b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -908,6 +908,32 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
        return 0;
 }
 
+#define DMUB_TRACE_MAX_READ 64
+static void dm_dmub_trace_high_irq(void *interrupt_params)
+{
+       struct common_irq_params *irq_params = interrupt_params;
+       struct amdgpu_device *adev = irq_params->adev;
+       struct amdgpu_display_manager *dm = &adev->dm;
+       struct dmcub_trace_buf_entry entry = { 0 };
+       uint32_t count = 0;
+
+       do {
+               if (dc_dmub_srv_get_dmub_outbox0_msg(dm->dc, &entry)) {
+                       trace_amdgpu_dmub_trace_high_irq(entry.trace_code, 
entry.tick_count,
+                                                       entry.param0, 
entry.param1);
+
+                       DRM_DEBUG_DRIVER("trace_code:%u, tick_count:%u, 
param0:%u, param1:%u\n",
+                                entry.trace_code, entry.tick_count, 
entry.param0, entry.param1);
+               } else
+                       break;
+
+               count++;
+
+       } while (count <= DMUB_TRACE_MAX_READ);
+
+       ASSERT(count <= DMUB_TRACE_MAX_READ);
+}
+
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 static void mmhub_read_system_context(struct amdgpu_device *adev, struct 
dc_phy_addr_space_config *pa_config)
 {
@@ -3078,6 +3104,28 @@ static int dcn10_register_irq_handlers(struct 
amdgpu_device *adev)
 
        }
 
+       if (dc->ctx->dmub_srv) {
+               i = DCN_1_0__SRCID__DMCUB_OUTBOX_HIGH_PRIORITY_READY_INT;
+               r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_DCE, i, 
&adev->dmub_trace_irq);
+
+               if (r) {
+                       DRM_ERROR("Failed to add dmub trace irq id!\n");
+                       return r;
+               }
+
+               int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT;
+               int_params.irq_source =
+                       dc_interrupt_to_irq_source(dc, i, 0);
+
+               c_irq_params = &adev->dm.dmub_trace_params[0];
+
+               c_irq_params->adev = adev;
+               c_irq_params->irq_src = int_params.irq_source;
+
+               amdgpu_dm_irq_register_interrupt(adev, &int_params,
+                               dm_dmub_trace_high_irq, c_irq_params);
+       }
+
        /* HPD */
        r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_DCE, 
DCN_1_0__SRCID__DC_HPD1_INT,
                        &adev->hpd_irq);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index f7f0680c1fa1..9d12f304b2ee 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -339,6 +339,15 @@ struct amdgpu_display_manager {
        struct common_irq_params
        vupdate_params[DC_IRQ_SOURCE_VUPDATE6 - DC_IRQ_SOURCE_VUPDATE1 + 1];
 
+       /**
+        * @dmub_trace_params:
+        *
+        * DMUB trace event IRQ parameters, passed to registered handlers when
+        * triggered.
+        */
+       struct common_irq_params
+       dmub_trace_params[1];
+
        spinlock_t irq_handler_list_table_lock;
 
        struct backlight_device *backlight_dev;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 09bdffb3a09e..103e29905b57 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -700,6 +700,14 @@ void dm_helpers_free_gpu_mem(
 
 bool dm_helpers_dmub_outbox0_interrupt_control(struct dc_context *ctx, bool 
enable)
 {
-       // TODO
-       return true;
+       enum dc_irq_source irq_source;
+       bool ret;
+
+       irq_source = DC_IRQ_SOURCE_DMCUB_OUTBOX0;
+
+       ret = dc_interrupt_set(ctx->dc, irq_source, enable);
+
+       DRM_DEBUG_DRIVER("Dmub trace irq %sabling: r=%d\n",
+                        enable ? "en" : "dis", ret);
+       return ret;
 }
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
index d3c687d07ee6..ffd18cd90947 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
@@ -731,6 +731,18 @@ static int amdgpu_dm_set_vupdate_irq_state(struct 
amdgpu_device *adev,
                __func__);
 }
 
+static int amdgpu_dm_set_dmub_trace_irq_state(struct amdgpu_device *adev,
+                                          struct amdgpu_irq_src *source,
+                                          unsigned int type,
+                                          enum amdgpu_interrupt_state state)
+{
+       enum dc_irq_source irq_source = DC_IRQ_SOURCE_DMCUB_OUTBOX0;
+       bool st = (state == AMDGPU_IRQ_STATE_ENABLE);
+
+       dc_interrupt_set(adev->dm.dc, irq_source, st);
+       return 0;
+}
+
 static const struct amdgpu_irq_src_funcs dm_crtc_irq_funcs = {
        .set = amdgpu_dm_set_crtc_irq_state,
        .process = amdgpu_dm_irq_handler,
@@ -746,6 +758,11 @@ static const struct amdgpu_irq_src_funcs 
dm_vupdate_irq_funcs = {
        .process = amdgpu_dm_irq_handler,
 };
 
+static const struct amdgpu_irq_src_funcs dm_dmub_trace_irq_funcs = {
+       .set = amdgpu_dm_set_dmub_trace_irq_state,
+       .process = amdgpu_dm_irq_handler,
+};
+
 static const struct amdgpu_irq_src_funcs dm_pageflip_irq_funcs = {
        .set = amdgpu_dm_set_pflip_irq_state,
        .process = amdgpu_dm_irq_handler,
@@ -768,6 +785,9 @@ void amdgpu_dm_set_irq_funcs(struct amdgpu_device *adev)
        adev->vupdate_irq.num_types = adev->mode_info.num_crtc;
        adev->vupdate_irq.funcs = &dm_vupdate_irq_funcs;
 
+       adev->dmub_trace_irq.num_types = 1;
+       adev->dmub_trace_irq.funcs = &dm_dmub_trace_irq_funcs;
+
        adev->pageflip_irq.num_types = adev->mode_info.num_crtc;
        adev->pageflip_irq.funcs = &dm_pageflip_irq_funcs;
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
index 86960476823c..ac8bcd171b57 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
@@ -597,6 +597,27 @@ TRACE_EVENT(amdgpu_dm_dce_clocks_state,
            )
 );
 
+TRACE_EVENT(amdgpu_dmub_trace_high_irq,
+       TP_PROTO(uint32_t trace_code, uint32_t tick_count, uint32_t param0,
+                uint32_t param1),
+       TP_ARGS(trace_code, tick_count, param0, param1),
+       TP_STRUCT__entry(
+               __field(uint32_t, trace_code)
+               __field(uint32_t, tick_count)
+               __field(uint32_t, param0)
+               __field(uint32_t, param1)
+               ),
+       TP_fast_assign(
+               __entry->trace_code = trace_code;
+               __entry->tick_count = tick_count;
+               __entry->param0 = param0;
+               __entry->param1 = param1;
+       ),
+       TP_printk("trace_code=%u tick_count=%u param0=%u param1=%u",
+                 __entry->trace_code, __entry->tick_count,
+                 __entry->param0, __entry->param1)
+);
+
 #endif /* _AMDGPU_DM_TRACE_H_ */
 
 #undef TRACE_INCLUDE_PATH
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c 
b/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c
index 0e0f494fbb5e..e9db4f56a39f 100644
--- a/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c
+++ b/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c
@@ -58,6 +58,8 @@ enum dc_irq_source to_dal_irq_source_dcn21(
                return DC_IRQ_SOURCE_VBLANK5;
        case DCN_1_0__SRCID__DC_D6_OTG_VSTARTUP:
                return DC_IRQ_SOURCE_VBLANK6;
+       case DCN_1_0__SRCID__DMCUB_OUTBOX_HIGH_PRIORITY_READY_INT:
+               return DC_IRQ_SOURCE_DMCUB_OUTBOX0;
        case DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT:
                return DC_IRQ_SOURCE_PFLIP1;
        case DCN_1_0__SRCID__HUBP1_FLIP_INTERRUPT:
@@ -173,6 +175,11 @@ static const struct irq_source_info_funcs 
vupdate_no_lock_irq_info_funcs = {
        .ack = NULL
 };
 
+static const struct irq_source_info_funcs dmub_trace_irq_info_funcs = {
+       .set = NULL,
+       .ack = NULL
+};
+
 #undef BASE_INNER
 #define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg
 
@@ -185,6 +192,9 @@ static const struct irq_source_info_funcs 
vupdate_no_lock_irq_info_funcs = {
        BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
                        mm ## block ## id ## _ ## reg_name
 
+#define SRI_DMUB(reg_name)\
+       BASE(mm ## reg_name ## _BASE_IDX) + \
+                       mm ## reg_name
 
 #define IRQ_REG_ENTRY(block, reg_num, reg1, mask1, reg2, mask2)\
        .enable_reg = SRI(reg1, block, reg_num),\
@@ -200,7 +210,19 @@ static const struct irq_source_info_funcs 
vupdate_no_lock_irq_info_funcs = {
        .ack_value = \
                block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK \
 
-
+#define IRQ_REG_ENTRY_DMUB(reg1, mask1, reg2, mask2)\
+       .enable_reg = SRI_DMUB(reg1),\
+       .enable_mask = \
+               reg1 ## __ ## mask1 ## _MASK,\
+       .enable_value = {\
+               reg1 ## __ ## mask1 ## _MASK,\
+               ~reg1 ## __ ## mask1 ## _MASK \
+       },\
+       .ack_reg = SRI_DMUB(reg2),\
+       .ack_mask = \
+               reg2 ## __ ## mask2 ## _MASK,\
+       .ack_value = \
+               reg2 ## __ ## mask2 ## _MASK \
 
 #define hpd_int_entry(reg_num)\
        [DC_IRQ_SOURCE_HPD1 + reg_num] = {\
@@ -254,6 +276,13 @@ static const struct irq_source_info_funcs 
vupdate_no_lock_irq_info_funcs = {
                .funcs = &vblank_irq_info_funcs\
        }
 
+#define dmub_trace_int_entry()\
+       [DC_IRQ_SOURCE_DMCUB_OUTBOX0] = {\
+               IRQ_REG_ENTRY_DMUB(DMCUB_INTERRUPT_ENABLE, 
DMCUB_OUTBOX0_READY_INT_EN,\
+                       DMCUB_INTERRUPT_ACK, DMCUB_OUTBOX0_READY_INT_ACK),\
+               .funcs = &dmub_trace_irq_info_funcs\
+       }
+
 #define dummy_irq_entry() \
        {\
                .funcs = &dummy_irq_info_funcs\
@@ -366,6 +395,7 @@ irq_source_info_dcn21[DAL_IRQ_SOURCES_NUMBER] = {
        vblank_int_entry(3),
        vblank_int_entry(4),
        vblank_int_entry(5),
+       dmub_trace_int_entry(),
 };
 
 static const struct irq_service_funcs irq_service_funcs_dcn21 = {
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c 
b/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c
index a35b76772b9d..238f68cdd41b 100644
--- a/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c
+++ b/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c
@@ -65,6 +65,8 @@ enum dc_irq_source to_dal_irq_source_dcn30(
                return DC_IRQ_SOURCE_VBLANK5;
        case DCN_1_0__SRCID__DC_D6_OTG_VSTARTUP:
                return DC_IRQ_SOURCE_VBLANK6;
+       case DCN_1_0__SRCID__DMCUB_OUTBOX_HIGH_PRIORITY_READY_INT:
+               return DC_IRQ_SOURCE_DMCUB_OUTBOX0;
        case DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT:
                return DC_IRQ_SOURCE_PFLIP1;
        case DCN_1_0__SRCID__HUBP1_FLIP_INTERRUPT:
@@ -179,6 +181,11 @@ static const struct irq_source_info_funcs 
vblank_irq_info_funcs = {
        .ack = NULL
 };
 
+static const struct irq_source_info_funcs dmub_trace_irq_info_funcs = {
+       .set = NULL,
+       .ack = NULL
+};
+
 #undef BASE_INNER
 #define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg
 
@@ -191,6 +198,9 @@ static const struct irq_source_info_funcs 
vblank_irq_info_funcs = {
        BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
                        mm ## block ## id ## _ ## reg_name
 
+#define SRI_DMUB(reg_name)\
+       BASE(mm ## reg_name ## _BASE_IDX) + \
+                       mm ## reg_name
 
 #define IRQ_REG_ENTRY(block, reg_num, reg1, mask1, reg2, mask2)\
        .enable_reg = SRI(reg1, block, reg_num),\
@@ -206,7 +216,19 @@ static const struct irq_source_info_funcs 
vblank_irq_info_funcs = {
        .ack_value = \
                block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK \
 
-
+#define IRQ_REG_ENTRY_DMUB(reg1, mask1, reg2, mask2)\
+       .enable_reg = SRI_DMUB(reg1),\
+       .enable_mask = \
+               reg1 ## __ ## mask1 ## _MASK,\
+       .enable_value = {\
+               reg1 ## __ ## mask1 ## _MASK,\
+               ~reg1 ## __ ## mask1 ## _MASK \
+       },\
+       .ack_reg = SRI_DMUB(reg2),\
+       .ack_mask = \
+               reg2 ## __ ## mask2 ## _MASK,\
+       .ack_value = \
+               reg2 ## __ ## mask2 ## _MASK \
 
 #define hpd_int_entry(reg_num)\
        [DC_IRQ_SOURCE_HPD1 + reg_num] = {\
@@ -252,6 +274,13 @@ static const struct irq_source_info_funcs 
vblank_irq_info_funcs = {
                .funcs = &vblank_irq_info_funcs\
        }
 
+#define dmub_trace_int_entry()\
+       [DC_IRQ_SOURCE_DMCUB_OUTBOX0] = {\
+               IRQ_REG_ENTRY_DMUB(DMCUB_INTERRUPT_ENABLE, 
DMCUB_OUTBOX0_READY_INT_EN,\
+                       DMCUB_INTERRUPT_ACK, DMCUB_OUTBOX0_READY_INT_ACK),\
+               .funcs = &dmub_trace_irq_info_funcs\
+       }
+
 #define dummy_irq_entry() \
        {\
                .funcs = &dummy_irq_info_funcs\
@@ -360,6 +389,7 @@ irq_source_info_dcn30[DAL_IRQ_SOURCES_NUMBER] = {
        vblank_int_entry(3),
        vblank_int_entry(4),
        vblank_int_entry(5),
+       dmub_trace_int_entry(),
 };
 
 static const struct irq_service_funcs irq_service_funcs_dcn30 = {
-- 
2.29.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to