From: Wenjing Liu <[email protected]>

[why]
Add support for retrieving Quality of Service (QoS) metrics from dc
to enable performance analysis and bottleneck identification. This provides
benchmark tools with real-time bandwidth and latency measurements from hardware
performance counters, helping diagnose display system performance issues.

[how]
- Add dc_get_qos_info() function to DC layer for unified QoS data retrieval
- Implement hardware sequencer interface with function pointers for QoS
measurements
- Integrate QoS metrics: peak/average bandwidth (Mbps) and max/average
latency (ns)

Reviewed-by: Aric Cyr <[email protected]>
Signed-off-by: Wenjing Liu <[email protected]>
Signed-off-by: Roman Li <[email protected]>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      | 24 ++++++++++++
 drivers/gpu/drm/amd/display/dc/dc.h           | 36 ++++++++++++++++++
 .../drm/amd/display/dc/hwss/hw_sequencer.h    | 37 +++++++++++++++++++
 3 files changed, 97 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 8be9cbd43e18..1e7c61b975e3 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -7091,3 +7091,27 @@ void dc_log_preos_dmcub_info(const struct dc *dc)
 {
        dc_dmub_srv_log_preos_dmcub_info(dc->ctx->dmub_srv);
 }
+
+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;
+
+       memset(info, 0, sizeof(*info));
+
+       // Check if all measurement functions are available
+       if (!dc->hwss.measure_peak_bw_mbps ||
+           !dc->hwss.measure_avg_bw_mbps ||
+           !dc->hwss.measure_max_latency_ns ||
+           !dc->hwss.measure_avg_latency_ns) {
+               return false;
+       }
+
+       // Call measurement functions to get actual values
+       info->actual_peak_bw_in_mbps = dc->hwss.measure_peak_bw_mbps(dc);
+       info->actual_avg_bw_in_mbps = dc->hwss.measure_avg_bw_mbps(dc);
+       info->actual_max_latency_in_ns = dc->hwss.measure_max_latency_ns(dc);
+       info->actual_avg_latency_in_ns = dc->hwss.measure_avg_latency_ns(dc);
+       info->dcn_bandwidth_ub_in_mbps = (uint32_t)(clk->fclk_khz / 1000 * 64);
+
+       return true;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 458883adfc28..827e0008c31d 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -951,6 +951,18 @@ struct dc_bounding_box_overrides {
        int min_dcfclk_mhz;
 };
 
+struct dc_qos_info {
+       uint32_t actual_peak_bw_in_mbps;
+       uint32_t qos_bandwidth_lb_in_mbps;
+       uint32_t actual_avg_bw_in_mbps;
+       uint32_t calculated_avg_bw_in_mbps;
+       uint32_t actual_max_latency_in_ns;
+       uint32_t qos_max_latency_ub_in_ns;
+       uint32_t actual_avg_latency_in_ns;
+       uint32_t qos_avg_latency_ub_in_ns;
+       uint32_t dcn_bandwidth_ub_in_mbps;
+};
+
 struct dc_state;
 struct resource_pool;
 struct dce_hwseq;
@@ -3322,4 +3334,28 @@ struct dc_register_software_state {
  */
 bool dc_capture_register_software_state(struct dc *dc, struct 
dc_register_software_state *state);
 
+/**
+ * dc_get_qos_info() - Retrieve Quality of Service (QoS) information from 
display core
+ * @dc: DC context containing current display configuration
+ * @info: Pointer to dc_qos_info structure to populate with QoS metrics
+ *
+ * This function retrieves QoS metrics from the display core that can be used 
by
+ * benchmark tools to analyze display system performance. The function may take
+ * several milliseconds to execute due to hardware measurement requirements.
+ *
+ * QoS information includes:
+ * - Bandwidth bounds (lower limits in Mbps)
+ * - Latency bounds (upper limits in nanoseconds)
+ * - Hardware-measured bandwidth metrics (peak/average in Mbps)
+ * - Hardware-measured latency metrics (maximum/average in nanoseconds)
+ *
+ * The function will populate the provided dc_qos_info structure with current
+ * QoS measurements. If hardware measurement functions are not available for
+ * the current DCN version, the function returns false with zero'd info 
structure.
+ *
+ * Return: true if QoS information was successfully retrieved, false if 
measurement
+ *         functions are unavailable or hardware measurements cannot be 
performed
+ */
+bool dc_get_qos_info(struct dc *dc, struct dc_qos_info *info);
+
 #endif /* DC_INTERFACE_H_ */
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 8ed9eea40c56..490a6fccebff 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
@@ -1287,6 +1287,43 @@ struct hw_sequencer_funcs {
        void (*get_underflow_debug_data)(const struct dc *dc,
                        struct timing_generator *tg,
                        struct dc_underflow_debug_data *out_data);
+
+       /**
+        * measure_peak_bw_mbps - Measure actual peak bandwidth in Mbps
+        * @dc: DC structure
+        *
+        * Returns the measured peak bandwidth value in Mbps from hardware
+        * performance counters or registers.
+        */
+       uint32_t (*measure_peak_bw_mbps)(struct dc *dc);
+
+       /**
+        * measure_avg_bw_mbps - Measure actual average bandwidth in Mbps
+        * @dc: DC structure
+        *
+        * Returns the measured average bandwidth value in Mbps from hardware
+        * performance counters or registers.
+        */
+       uint32_t (*measure_avg_bw_mbps)(struct dc *dc);
+
+       /**
+        * measure_max_latency_ns - Measure actual maximum latency in 
nanoseconds
+        * @dc: DC structure
+        *
+        * Returns the measured maximum latency value in nanoseconds from 
hardware
+        * performance counters or registers.
+        */
+       uint32_t (*measure_max_latency_ns)(struct dc *dc);
+
+       /**
+        * measure_avg_latency_ns - Measure actual average latency in 
nanoseconds
+        * @dc: DC structure
+        *
+        * Returns the measured average latency value in nanoseconds from 
hardware
+        * performance counters or registers.
+        */
+       uint32_t (*measure_avg_latency_ns)(struct dc *dc);
+
 };
 
 void color_space_to_black_color(
-- 
2.34.1

Reply via email to