From: Wenjing Liu Date: Thu, 23 Apr 2026 20:59:01 +0000 (-0400) Subject: drm/amd/display: add max bandwidth budget to QoS interface X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=706364231119bddb0aaa2c8e0fa662311ff9302e;p=thirdparty%2Fkernel%2Flinux.git drm/amd/display: add max bandwidth budget to QoS interface [Why] The QoS reporting interface lacked a field to expose the maximum active memory bandwidth budget. Adding this field allows callers to observe the effective bandwidth ceiling. [How] Rename struct memory_qos to dc_measured_memory_qos and introduce a new struct dc_requested_memory_qos holding bandwidth lower bound, calculated average bandwidth, latency upper bounds, and max bandwidth budget. Add a get_requested_memory_qos function pointer to clk_mgr_funcs. Update dc_get_qos_info to call through the new function pointer and populate all requested QoS fields including qos_max_bw_budget_in_mbps in dc_qos_info. Reviewed-by: Dillon Varone Signed-off-by: Wenjing Liu Signed-off-by: James Lin Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 2cb1d1bf0376..92190ea451e8 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -7601,7 +7601,8 @@ void dc_log_preos_dmcub_info(const struct dc *dc) bool dc_get_qos_info(struct dc *dc, struct dc_qos_info *info) { const struct dc_clocks *clk = &dc->current_state->bw_ctx.bw.dcn.clk; - struct memory_qos qos; + struct dc_measured_memory_qos measured = {}; + struct dc_requested_memory_qos requested = {}; memset(info, 0, sizeof(*info)); @@ -7610,16 +7611,23 @@ bool dc_get_qos_info(struct dc *dc, struct dc_qos_info *info) return false; } - // Call unified measurement function - dc->hwss.measure_memory_qos(dc, &qos); + dc->hwss.measure_memory_qos(dc, &measured); - // Populate info from measured qos - info->actual_peak_bw_in_mbps = qos.peak_bw_mbps; - info->actual_avg_bw_in_mbps = qos.avg_bw_mbps; - info->actual_min_latency_in_ns = qos.min_latency_ns; - info->actual_max_latency_in_ns = qos.max_latency_ns; - info->actual_avg_latency_in_ns = qos.avg_latency_ns; - info->dcn_bandwidth_ub_in_mbps = (uint32_t)(clk->fclk_khz / 1000 * 64); + info->actual_peak_bw_in_mbps = measured.peak_bw_mbps; + info->actual_avg_bw_in_mbps = measured.avg_bw_mbps; + info->actual_min_latency_in_ns = measured.min_latency_ns; + info->actual_max_latency_in_ns = measured.max_latency_ns; + info->actual_avg_latency_in_ns = measured.avg_latency_ns; + info->dcn_bandwidth_ub_in_mbps = (uint32_t)(clk->fclk_khz / 1000 * 64); + + if (dc->clk_mgr && dc->clk_mgr->funcs->get_requested_memory_qos) { + dc->clk_mgr->funcs->get_requested_memory_qos(dc->clk_mgr, &requested); + info->qos_bandwidth_lb_in_mbps = requested.bandwidth_lb_in_mbps; + info->calculated_avg_bw_in_mbps = requested.calculated_avg_bw_in_mbps; + info->qos_max_latency_ub_in_ns = requested.max_latency_ub_in_ns; + info->qos_avg_latency_ub_in_ns = requested.avg_latency_ub_in_ns; + info->qos_max_bw_budget_in_mbps = requested.max_bw_budget_in_mbps; + } return true; } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 73901ac94b7d..757ec9aff0b2 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -971,6 +971,7 @@ struct dc_qos_info { uint32_t actual_avg_latency_in_ns; uint32_t qos_avg_latency_ub_in_ns; uint32_t dcn_bandwidth_ub_in_mbps; + uint32_t qos_max_bw_budget_in_mbps; }; struct dc_state; diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h index 7f0743de1b14..4b9fcb87e60d 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h @@ -53,7 +53,7 @@ struct drr_params; struct dc_underflow_debug_data; struct dsc_optc_config; struct vm_system_aperture_param; -struct memory_qos; +struct dc_measured_memory_qos; struct stream_encoder; struct hpo_dp_stream_encoder; struct hpo_frl_stream_encoder; @@ -1516,12 +1516,12 @@ struct hw_sequencer_funcs { /** * measure_memory_qos - Measure memory QoS metrics * @dc: DC structure - * @qos: Pointer to memory_qos struct to populate with measured values + * @qos: Pointer to dc_measured_memory_qos struct to populate with measured values * - * Populates the provided memory_qos struct with peak bandwidth, average bandwidth, + * Populates the provided dc_measured_memory_qos struct with peak bandwidth, average bandwidth, * max latency, min latency, and average latency from hardware performance counters. */ - void (*measure_memory_qos)(struct dc *dc, struct memory_qos *qos); + void (*measure_memory_qos)(struct dc *dc, struct dc_measured_memory_qos *qos); }; diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index e960ca9062ad..a99e1937f8ce 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -707,7 +707,7 @@ struct dc_bounding_box_max_clk { int max_phyclk_mhz; }; -struct memory_qos { +struct dc_measured_memory_qos { uint32_t peak_bw_mbps; uint32_t avg_bw_mbps; uint32_t max_latency_ns; @@ -715,4 +715,12 @@ struct memory_qos { uint32_t avg_latency_ns; }; +struct dc_requested_memory_qos { + uint32_t bandwidth_lb_in_mbps; + uint32_t calculated_avg_bw_in_mbps; + uint32_t max_latency_ub_in_ns; + uint32_t avg_latency_ub_in_ns; + uint32_t max_bw_budget_in_mbps; +}; + #endif /* _CORE_TYPES_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h index eab25efea76b..dcce81e3d97c 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h @@ -28,6 +28,7 @@ #define __DAL_CLK_MGR_H__ #include "dc.h" +#include "core_types.h" #include "dm_pp_smu.h" /* Constants */ @@ -374,6 +375,15 @@ struct clk_mgr_funcs { unsigned int (*override_memory_bandwidth_request)( struct clk_mgr *clk_mgr, unsigned int bw_kbps); + /** + * get_requested_memory_qos - Retrieve current QoS request from the clock manager's + * current clock state, reflecting any active bandwidth overrides. + * @clk_mgr: clock manager instance + * @qos: pointer to dc_requested_memory_qos structure to populate + */ + void (*get_requested_memory_qos)( + struct clk_mgr *clk_mgr, + struct dc_requested_memory_qos *qos); }; struct clk_mgr {