Commit a08f16cf authored by Leo (Hanghong) Ma's avatar Leo (Hanghong) Ma Committed by Alex Deucher
Browse files

drm/amd/display: Log DMCUB trace buffer events



[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.

Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarLeo (Hanghong) Ma <hanghong.ma@amd.com>
Reviewed-by: default avatarHarry Wentland <Harry.Wentland@amd.com>
Acked-by: default avatarSolomon Chiu <solomon.chiu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 234cc26f
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -922,6 +922,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)
{
@@ -3104,6 +3130,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);
+9 −0
Original line number Diff line number Diff line
@@ -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;
+10 −2
Original line number Diff line number Diff line
@@ -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;
}
+20 −0
Original line number Diff line number Diff line
@@ -732,6 +732,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,
@@ -747,6 +759,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,
@@ -769,6 +786,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;

+21 −0
Original line number Diff line number Diff line
@@ -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
Loading