[PATCH 01/34] drm/amd/display: Add support for overriding UTM client QC profile

Tom Chung <[email protected]> Wed, 5 Aug 2026 14:36:13 +0800
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
From: Dillon Varone <[email protected]>

[WHY&HOW]
Support overriding UTM client QC profiles for testing.

Reviewed-by: Alvin Lee <[email protected]>
Signed-off-by: Dillon Varone <[email protected]>
Signed-off-by: Tom Chung <[email protected]>
---
 drivers/gpu/drm/amd/display/dc/dc.h           |  2 ++
 .../display/dc/hubbub/dcn10/dcn10_hubbub.h    |  7 ++++++-
 .../display/dc/hubbub/dcn60/dcn60_hubbub.c    | 21 +++++++++++++++++++
 .../display/dc/hubbub/dcn60/dcn60_hubbub.h    |  6 +++++-
 .../amd/display/dc/hwss/dcn60/dcn60_hwseq.c   |  6 ++++++
 .../gpu/drm/amd/display/dc/inc/hw/dchubbub.h  |  1 +
 .../dc/resource/dcn60/dcn60_resource.h        |  3 ++-
 7 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 705c500ad711..6e45a484a9ad 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1321,6 +1321,8 @@ struct dc_debug_options {
 	bool disable_dynamic_expansion_for_test_pattern;
 	uint32_t dml21_custom_derate_num_dpms;
 	uint32_t dml21_custom_derate_at_dpm[DML2_MAX_NUM_DPM_LVL];
+	bool override_utm_client_qc_profile;
+	uint8_t utm_client_qc_profiles[4];
 };
 
 
diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h b/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h
index accb79c6dde5..5f065b4045ee 100644
--- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h
@@ -215,6 +215,7 @@ struct dcn_hubbub_registers {
 	uint32_t DC_PERFMON5_PERFMON_HI;
 	uint32_t DC_PERFMON5_PERFMON_LOW;
 	uint32_t FMON_CTRL;
+	uint32_t UTM_CLIENT_TO_SYSTEM_PROFILE_MAPPING_0;
 };
 
 #define HUBBUB_REG_FIELD_LIST_DCN32(type) \
@@ -545,7 +546,11 @@ struct dcn_hubbub_registers {
 
 #define HUBBUB_REG_FIELD_LIST_DCN60(type) \
 		type DCHUBBUB_ARB_BUFFER_FULLNESS_WATERMARK_A;\
-		type DCHUBBUB_ARB_BUFFER_FULLNESS_WATERMARK_B
+		type DCHUBBUB_ARB_BUFFER_FULLNESS_WATERMARK_B;\
+		type SYSTEM_PROFILE_QC0;\
+		type SYSTEM_PROFILE_QC1;\
+		type SYSTEM_PROFILE_QC2;\
+		type SYSTEM_PROFILE_QC3
 
 struct dcn_hubbub_shift {
 	DCN_HUBBUB_REG_FIELD_LIST(uint8_t);
diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.c
index 3994e73a2992..e2a457ab13bb 100644
--- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.c
@@ -1730,6 +1730,26 @@ static void hubbub60_reset_display_qos_profile(struct hubbub *hubbub)
 	REG_UPDATE(DCHUBBUB_ARB_QOS_FORCE, DCHUBBUB_ARB_UTM_FORCE_URGENT, 0);
 }
 
+static void hubbub60_override_utm_client_qc_profile(struct hubbub *hubbub, uint8_t qc_profile, int index)
+{
+	struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
+
+	switch (index) {
+	case 0:
+		REG_UPDATE(UTM_CLIENT_TO_SYSTEM_PROFILE_MAPPING_0, SYSTEM_PROFILE_QC0, qc_profile);
+		break;
+	case 1:
+		REG_UPDATE(UTM_CLIENT_TO_SYSTEM_PROFILE_MAPPING_0, SYSTEM_PROFILE_QC1, qc_profile);
+		break;
+	case 2:
+		REG_UPDATE(UTM_CLIENT_TO_SYSTEM_PROFILE_MAPPING_0, SYSTEM_PROFILE_QC2, qc_profile);
+		break;
+	default:
+		BREAK_TO_DEBUGGER();
+		break;
+	}
+}
+
 static const struct hubbub_funcs hubbub60_funcs = {
 	.update_dchub = hubbub2_update_dchub,
 	.init_dchub_sys_ctx = hubbub3_init_dchub_sys_ctx,
@@ -1755,6 +1775,7 @@ static const struct hubbub_funcs hubbub60_funcs = {
 	.program_compbuf_segments = dcn60_program_compbuf_segments,
 	.wait_for_det_update = dcn60_wait_for_det_update,
 	.program_arbiter = dcn401_program_arbiter,
+	.override_utm_client_qc_profile = hubbub60_override_utm_client_qc_profile,
 	.hubbub_read_reg_state = hubbub3_read_reg_state,
 	.perfmon = {
 		.reset = hubbub60_perfmon_reset,
diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.h b/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.h
index 204f422c3383..03b5182d233c 100644
--- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.h
@@ -193,7 +193,11 @@
 	HUBBUB_SF(DCHUBBUB_ARB_QOS_FORCE, DCHUBBUB_ARB_UTM_FORCE_URGENT, mask_sh), \
 	HUBBUB_SF(DCHUBBUB_ARB_QOS_FORCE, DCHUBBUB_ARB_UTM_FORCE_BANDWIDTH_OVERHEAD, mask_sh), \
 	HUBBUB_SF(DCHUBBUB_ARB_QOS_FORCE, DCHUBBUB_ARB_UTM_FORCE_ENABLE, mask_sh), \
-	HUBBUB_SF(DCHUBBUB_ARB_QOS_FORCE, DCHUBBUB_ARB_DO_NOT_FORCE_URGENCY_DURING_PSTATE_CHANGE_REQUEST, mask_sh)
+	HUBBUB_SF(DCHUBBUB_ARB_QOS_FORCE, DCHUBBUB_ARB_DO_NOT_FORCE_URGENCY_DURING_PSTATE_CHANGE_REQUEST, mask_sh), \
+	HUBBUB_SF(UTM_CLIENT_TO_SYSTEM_PROFILE_MAPPING_0, SYSTEM_PROFILE_QC0, mask_sh), \
+	HUBBUB_SF(UTM_CLIENT_TO_SYSTEM_PROFILE_MAPPING_0, SYSTEM_PROFILE_QC1, mask_sh), \
+	HUBBUB_SF(UTM_CLIENT_TO_SYSTEM_PROFILE_MAPPING_0, SYSTEM_PROFILE_QC2, mask_sh), \
+	HUBBUB_SF(UTM_CLIENT_TO_SYSTEM_PROFILE_MAPPING_0, SYSTEM_PROFILE_QC3, mask_sh)
 
 void hubbub60_construct(struct dcn20_hubbub *hubbub2,
 	struct dc_context *ctx,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_hwseq.c
index 72c2d3ca52f6..14adf1a3a1e0 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn60/dcn60_hwseq.c
@@ -753,6 +753,12 @@ void dcn60_init_hw(struct dc *dc)
 	if (dc->res_pool->hubbub->funcs->set_request_limit && dc->config.sdpif_request_limit_words_per_umc > 0)
 		dc->res_pool->hubbub->funcs->set_request_limit(dc->res_pool->hubbub, dc->ctx->dc_bios->vram_info.num_chans, dc->config.sdpif_request_limit_words_per_umc);
 
+	if (dc->res_pool->hubbub->funcs->override_utm_client_qc_profile && dc->debug.override_utm_client_qc_profile) {
+		dc->res_pool->hubbub->funcs->override_utm_client_qc_profile(dc->res_pool->hubbub, dc->debug.utm_client_qc_profiles[0], 0);
+		dc->res_pool->hubbub->funcs->override_utm_client_qc_profile(dc->res_pool->hubbub, dc->debug.utm_client_qc_profiles[1], 1);
+		dc->res_pool->hubbub->funcs->override_utm_client_qc_profile(dc->res_pool->hubbub, dc->debug.utm_client_qc_profiles[2], 2);
+	}
+
 	// Get DMCUB capabilities
 	if (dc->ctx->dmub_srv) {
 		dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
index 02bc0010e565..22a0e3dcb25c 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
@@ -253,6 +253,7 @@ struct hubbub_funcs {
 	void (*wait_for_det_update)(struct hubbub *hubbub, int hubp_inst);
 	bool (*program_arbiter)(struct hubbub *hubbub, struct dml2_display_arb_regs *arb_regs, bool safe_to_lower);
 	void (*dchvm_init)(struct hubbub *hubbub);
+	void (*override_utm_client_qc_profile)(struct hubbub *hubbub, uint8_t qc_profile, int index);
 
 	/* Performance monitoring related functions */
 	struct hubbub_perfmon_funcs {
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.h b/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.h
index c4b6df4838c6..913f049deeb3 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.h
@@ -140,7 +140,8 @@ bool dcn50_program_mcache_pipe_config(struct dc_state *context,
 	SR(DC_PERFMON5_PERFMON_HI),                                              \
 	SR(DC_PERFMON5_PERFMON_LOW),                                             \
 	SR(FMON_CTRL),                                                           \
-	SR(DCHUBBUB_ARB_QOS_FORCE)
+	SR(DCHUBBUB_ARB_QOS_FORCE),                                              \
+	SR(UTM_CLIENT_TO_SYSTEM_PROFILE_MAPPING_0)
 
 /* HUBP */
 #define HUBP_REG_LIST_DCN60_RI(id)                                               \
-- 
2.43.0