drm/amd/display: Introduce program_perfmon hwss hook and BLS perfmon sequence

[Why]
The hubbub perfmon peak-bandwidth path used a monolithic function
combining counter configuration and enable in one call, and wrote results
into a caller-supplied struct outside the dc_state model. A BLS-driven
approach builds the measurement from stateless primitives, gates it to OTG
frame boundaries, and stores results in dc_state.

[How]
- Rename the peak-BW vtable members from "unbounded_bandwidth" to
  "out_of_order_bandwidth" and split them into arm and start operations.
- Add the full set of perfmon BLS primitives - param structs, union
  members, enum entries, executors, and hwss_add_* builders - for reset,
  arm, every start_measuring_* and every get_* operation.
- Add dc_probe_status (valid, type, result union) plus probe_status[] to
  dc_state.
- Replace the measure_memory_qos hook with program_perfmon(dc, context),
  which writes results into probe_status[].
- dc_get_qos_info no longer calls the removed hook.

Reviewed-by: Dominik Kaszewski <dominik.kaszewski@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Wenjing Liu 2026-06-18 18:05:07 -04:00 committed by Alex Deucher
parent 598abe0aad
commit 85df288438
6 changed files with 562 additions and 23 deletions

View File

@ -8124,24 +8124,13 @@ 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 dc_measured_memory_qos measured = {};
struct dc_requested_memory_qos requested = {};
memset(info, 0, sizeof(*info));
// Check if measurement function is available
if (!dc->hwss.measure_memory_qos) {
return false;
}
dc->hwss.measure_memory_qos(dc, &measured);
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);
/* TODO: remove the actual_* fields from struct dc_qos_info once all callers
* read measured QoS from dc_state probe_status instead of this struct. */
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);

View File

@ -1495,6 +1495,48 @@ void hwss_execute_sequence(struct dc *dc,
case HUBBUB_SOFT_RESET:
hwss_hubbub_soft_reset(params);
break;
case HUBBUB_PERFMON_RESET:
hwss_hubbub_perfmon_reset(params);
break;
case HUBBUB_PERFMON_ARM_OUT_OF_ORDER_BW:
hwss_hubbub_perfmon_arm_out_of_order_bw(params);
break;
case HUBBUB_PERFMON_START_OUT_OF_ORDER_BW:
hwss_hubbub_perfmon_start_out_of_order_bw(params);
break;
case HUBBUB_PERFMON_START_IN_ORDER_BW:
hwss_hubbub_perfmon_start_in_order_bw(params);
break;
case HUBBUB_PERFMON_START_MEMORY_LATENCIES:
hwss_hubbub_perfmon_start_memory_latencies(params);
break;
case HUBBUB_PERFMON_START_URGENT_ASSERTION_COUNT:
hwss_hubbub_perfmon_start_urgent_assertion_count(params);
break;
case HUBBUB_PERFMON_START_URGENT_RAMP_LATENCY:
hwss_hubbub_perfmon_start_urgent_ramp_latency(params);
break;
case HUBBUB_PERFMON_START_PREFETCH_DATA_SIZE:
hwss_hubbub_perfmon_start_prefetch_data_size(params);
break;
case HUBBUB_PERFMON_GET_OUT_OF_ORDER_BW:
hwss_hubbub_perfmon_get_out_of_order_bw(params);
break;
case HUBBUB_PERFMON_GET_IN_ORDER_BW:
hwss_hubbub_perfmon_get_in_order_bw(params);
break;
case HUBBUB_PERFMON_GET_MEMORY_LATENCIES:
hwss_hubbub_perfmon_get_memory_latencies(params);
break;
case HUBBUB_PERFMON_GET_URGENT_ASSERTION_COUNT:
hwss_hubbub_perfmon_get_urgent_assertion_count(params);
break;
case HUBBUB_PERFMON_GET_PREFETCH_DATA_SIZE:
hwss_hubbub_perfmon_get_prefetch_data_size(params);
break;
case HUBBUB_PERFMON_GET_URGENT_RAMP_LATENCY:
hwss_hubbub_perfmon_get_urgent_ramp_latency(params);
break;
case HUBP_CLK_CNTL:
hwss_hubp_clk_cntl(params);
break;
@ -3251,6 +3293,139 @@ void hwss_hubbub_soft_reset(union block_sequence_params *params)
params->hubbub_soft_reset_params.hubbub_soft_reset(hubbub, reset);
}
void hwss_hubbub_perfmon_reset(union block_sequence_params *params)
{
struct hubbub *hubbub = params->hubbub_perfmon_reset_params.hubbub;
if (hubbub && hubbub->funcs->perfmon.reset)
hubbub->funcs->perfmon.reset(hubbub);
}
void hwss_hubbub_perfmon_arm_out_of_order_bw(union block_sequence_params *params)
{
struct hubbub *hubbub = params->hubbub_perfmon_arm_out_of_order_bw_params.hubbub;
if (hubbub && hubbub->funcs->perfmon.arm_measuring_out_of_order_bandwidth)
hubbub->funcs->perfmon.arm_measuring_out_of_order_bandwidth(hubbub);
}
void hwss_hubbub_perfmon_start_out_of_order_bw(union block_sequence_params *params)
{
struct hubbub *hubbub = params->hubbub_perfmon_start_out_of_order_bw_params.hubbub;
if (hubbub && hubbub->funcs->perfmon.start_measuring_out_of_order_bandwidth)
hubbub->funcs->perfmon.start_measuring_out_of_order_bandwidth(hubbub);
}
void hwss_hubbub_perfmon_start_in_order_bw(union block_sequence_params *params)
{
struct hubbub *hubbub = params->hubbub_perfmon_start_in_order_bw_params.hubbub;
if (hubbub && hubbub->funcs->perfmon.start_measuring_in_order_bandwidth)
hubbub->funcs->perfmon.start_measuring_in_order_bandwidth(hubbub);
}
void hwss_hubbub_perfmon_start_memory_latencies(union block_sequence_params *params)
{
struct hubbub *hubbub = params->hubbub_perfmon_start_memory_latencies_params.hubbub;
if (hubbub && hubbub->funcs->perfmon.start_measuring_memory_latencies)
hubbub->funcs->perfmon.start_measuring_memory_latencies(hubbub);
}
void hwss_hubbub_perfmon_start_urgent_assertion_count(union block_sequence_params *params)
{
struct hubbub *hubbub = params->hubbub_perfmon_start_urgent_assertion_count_params.hubbub;
if (hubbub && hubbub->funcs->perfmon.start_measuring_urgent_assertion_count)
hubbub->funcs->perfmon.start_measuring_urgent_assertion_count(hubbub);
}
void hwss_hubbub_perfmon_start_urgent_ramp_latency(union block_sequence_params *params)
{
struct hubbub *hubbub = params->hubbub_perfmon_start_urgent_ramp_latency_params.hubbub;
if (hubbub && hubbub->funcs->perfmon.start_measuring_urgent_ramp_latency)
hubbub->funcs->perfmon.start_measuring_urgent_ramp_latency(
hubbub,
&params->hubbub_perfmon_start_urgent_ramp_latency_params.latency_params);
}
void hwss_hubbub_perfmon_start_prefetch_data_size(union block_sequence_params *params)
{
struct hubbub *hubbub = params->hubbub_perfmon_start_prefetch_data_size_params.hubbub;
if (hubbub && hubbub->funcs->perfmon.start_measuring_prefetch_data_size)
hubbub->funcs->perfmon.start_measuring_prefetch_data_size(hubbub);
}
void hwss_hubbub_perfmon_get_out_of_order_bw(union block_sequence_params *params)
{
struct hubbub *hubbub = params->hubbub_perfmon_get_out_of_order_bw_params.hubbub;
uint32_t refclk_mhz = params->hubbub_perfmon_get_out_of_order_bw_params.refclk_mhz;
uint32_t *mbps = params->hubbub_perfmon_get_out_of_order_bw_params.bandwidth_mbps;
uint32_t *duration = params->hubbub_perfmon_get_out_of_order_bw_params.duration_ns;
if (hubbub && hubbub->funcs->perfmon.get_out_of_order_bandwidth_mbps && mbps)
*mbps = hubbub->funcs->perfmon.get_out_of_order_bandwidth_mbps(
hubbub, refclk_mhz, duration);
}
void hwss_hubbub_perfmon_get_in_order_bw(union block_sequence_params *params)
{
struct hubbub *hubbub = params->hubbub_perfmon_get_in_order_bw_params.hubbub;
uint32_t refclk_mhz = params->hubbub_perfmon_get_in_order_bw_params.refclk_mhz;
uint32_t min_duration_ns = params->hubbub_perfmon_get_in_order_bw_params.min_duration_ns;
uint32_t *mbps = params->hubbub_perfmon_get_in_order_bw_params.bandwidth_mbps;
uint32_t *duration = params->hubbub_perfmon_get_in_order_bw_params.duration_ns;
if (hubbub && hubbub->funcs->perfmon.get_in_order_bandwidth_mbps && mbps)
*mbps = hubbub->funcs->perfmon.get_in_order_bandwidth_mbps(
hubbub, refclk_mhz, min_duration_ns, duration);
}
void hwss_hubbub_perfmon_get_memory_latencies(union block_sequence_params *params)
{
struct hubbub *hubbub = params->hubbub_perfmon_get_memory_latencies_params.hubbub;
uint32_t refclk_mhz = params->hubbub_perfmon_get_memory_latencies_params.refclk_mhz;
struct hubbub_system_latencies *result = params->hubbub_perfmon_get_memory_latencies_params.result;
if (hubbub && hubbub->funcs->perfmon.get_memory_latencies_ns && result)
hubbub->funcs->perfmon.get_memory_latencies_ns(
hubbub, refclk_mhz, &result->min_latency_ns, &result->max_latency_ns, &result->avg_latency_ns);
}
void hwss_hubbub_perfmon_get_urgent_assertion_count(union block_sequence_params *params)
{
struct hubbub *hubbub = params->hubbub_perfmon_get_urgent_assertion_count_params.hubbub;
uint32_t refclk_mhz = params->hubbub_perfmon_get_urgent_assertion_count_params.refclk_mhz;
uint32_t *count = params->hubbub_perfmon_get_urgent_assertion_count_params.assertion_count;
if (hubbub && hubbub->funcs->perfmon.get_urgent_assertion_count)
hubbub->funcs->perfmon.get_urgent_assertion_count(
hubbub, refclk_mhz, count, NULL, NULL);
}
void hwss_hubbub_perfmon_get_prefetch_data_size(union block_sequence_params *params)
{
struct hubbub *hubbub = params->hubbub_perfmon_get_prefetch_data_size_params.hubbub;
uint32_t *prefetch_size = params->hubbub_perfmon_get_prefetch_data_size_params.prefetch_data_size;
if (hubbub && hubbub->funcs->perfmon.get_prefetch_data_size && prefetch_size)
*prefetch_size = hubbub->funcs->perfmon.get_prefetch_data_size(hubbub);
}
void hwss_hubbub_perfmon_get_urgent_ramp_latency(union block_sequence_params *params)
{
struct hubbub *hubbub = params->hubbub_perfmon_get_urgent_ramp_latency_params.hubbub;
uint32_t refclk_mhz = params->hubbub_perfmon_get_urgent_ramp_latency_params.refclk_mhz;
uint32_t *latency_ns = params->hubbub_perfmon_get_urgent_ramp_latency_params.latency_ns;
if (hubbub && hubbub->funcs->perfmon.get_urgent_ramp_latency_ns && latency_ns)
*latency_ns = hubbub->funcs->perfmon.get_urgent_ramp_latency_ns(
hubbub, refclk_mhz);
}
void hwss_hubp_clk_cntl(union block_sequence_params *params)
{
struct hubp *hubp = params->hubp_clk_cntl_params.hubp;
@ -4422,6 +4597,168 @@ void hwss_add_hubbub_soft_reset(struct block_sequence_state *seq_state,
}
}
void hwss_add_hubbub_perfmon_reset(struct block_sequence_state *seq_state,
struct hubbub *hubbub)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = HUBBUB_PERFMON_RESET;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_reset_params.hubbub = hubbub;
(*seq_state->num_steps)++;
}
}
void hwss_add_hubbub_perfmon_arm_out_of_order_bw(struct block_sequence_state *seq_state,
struct hubbub *hubbub)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = HUBBUB_PERFMON_ARM_OUT_OF_ORDER_BW;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_arm_out_of_order_bw_params.hubbub = hubbub;
(*seq_state->num_steps)++;
}
}
void hwss_add_hubbub_perfmon_start_out_of_order_bw(struct block_sequence_state *seq_state,
struct hubbub *hubbub)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = HUBBUB_PERFMON_START_OUT_OF_ORDER_BW;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_start_out_of_order_bw_params.hubbub = hubbub;
(*seq_state->num_steps)++;
}
}
void hwss_add_hubbub_perfmon_start_in_order_bw(struct block_sequence_state *seq_state,
struct hubbub *hubbub)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = HUBBUB_PERFMON_START_IN_ORDER_BW;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_start_in_order_bw_params.hubbub = hubbub;
(*seq_state->num_steps)++;
}
}
void hwss_add_hubbub_perfmon_start_memory_latencies(struct block_sequence_state *seq_state,
struct hubbub *hubbub)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = HUBBUB_PERFMON_START_MEMORY_LATENCIES;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_start_memory_latencies_params.hubbub = hubbub;
(*seq_state->num_steps)++;
}
}
void hwss_add_hubbub_perfmon_start_urgent_assertion_count(struct block_sequence_state *seq_state,
struct hubbub *hubbub)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = HUBBUB_PERFMON_START_URGENT_ASSERTION_COUNT;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_start_urgent_assertion_count_params.hubbub = hubbub;
(*seq_state->num_steps)++;
}
}
void hwss_add_hubbub_perfmon_start_urgent_ramp_latency(struct block_sequence_state *seq_state,
struct hubbub *hubbub,
const struct hubbub_urgent_latency_params *latency_params)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = HUBBUB_PERFMON_START_URGENT_RAMP_LATENCY;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_start_urgent_ramp_latency_params.hubbub = hubbub;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_start_urgent_ramp_latency_params.latency_params =
*latency_params;
(*seq_state->num_steps)++;
}
}
void hwss_add_hubbub_perfmon_start_prefetch_data_size(struct block_sequence_state *seq_state,
struct hubbub *hubbub)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = HUBBUB_PERFMON_START_PREFETCH_DATA_SIZE;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_start_prefetch_data_size_params.hubbub = hubbub;
(*seq_state->num_steps)++;
}
}
void hwss_add_hubbub_perfmon_get_out_of_order_bw(struct block_sequence_state *seq_state,
struct hubbub *hubbub, uint32_t refclk_mhz,
uint32_t *bandwidth_mbps, uint32_t *duration_ns)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = HUBBUB_PERFMON_GET_OUT_OF_ORDER_BW;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_out_of_order_bw_params.hubbub = hubbub;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_out_of_order_bw_params.refclk_mhz = refclk_mhz;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_out_of_order_bw_params.bandwidth_mbps = bandwidth_mbps;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_out_of_order_bw_params.duration_ns = duration_ns;
(*seq_state->num_steps)++;
}
}
void hwss_add_hubbub_perfmon_get_in_order_bw(struct block_sequence_state *seq_state,
struct hubbub *hubbub, uint32_t refclk_mhz, uint32_t min_duration_ns,
uint32_t *bandwidth_mbps, uint32_t *duration_ns)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = HUBBUB_PERFMON_GET_IN_ORDER_BW;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_in_order_bw_params.hubbub = hubbub;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_in_order_bw_params.refclk_mhz = refclk_mhz;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_in_order_bw_params.min_duration_ns = min_duration_ns;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_in_order_bw_params.bandwidth_mbps = bandwidth_mbps;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_in_order_bw_params.duration_ns = duration_ns;
(*seq_state->num_steps)++;
}
}
void hwss_add_hubbub_perfmon_get_memory_latencies(struct block_sequence_state *seq_state,
struct hubbub *hubbub, uint32_t refclk_mhz,
struct hubbub_system_latencies *result)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = HUBBUB_PERFMON_GET_MEMORY_LATENCIES;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_memory_latencies_params.hubbub = hubbub;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_memory_latencies_params.refclk_mhz = refclk_mhz;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_memory_latencies_params.result = result;
(*seq_state->num_steps)++;
}
}
void hwss_add_hubbub_perfmon_get_urgent_assertion_count(struct block_sequence_state *seq_state,
struct hubbub *hubbub, uint32_t refclk_mhz,
uint32_t *assertion_count)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = HUBBUB_PERFMON_GET_URGENT_ASSERTION_COUNT;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_urgent_assertion_count_params.hubbub = hubbub;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_urgent_assertion_count_params.refclk_mhz = refclk_mhz;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_urgent_assertion_count_params.assertion_count = assertion_count;
(*seq_state->num_steps)++;
}
}
void hwss_add_hubbub_perfmon_get_prefetch_data_size(struct block_sequence_state *seq_state,
struct hubbub *hubbub, uint32_t *prefetch_data_size)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = HUBBUB_PERFMON_GET_PREFETCH_DATA_SIZE;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_prefetch_data_size_params.hubbub = hubbub;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_prefetch_data_size_params.prefetch_data_size = prefetch_data_size;
(*seq_state->num_steps)++;
}
}
void hwss_add_hubbub_perfmon_get_urgent_ramp_latency(struct block_sequence_state *seq_state,
struct hubbub *hubbub, uint32_t refclk_mhz,
uint32_t *latency_ns)
{
if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
seq_state->steps[*seq_state->num_steps].func = HUBBUB_PERFMON_GET_URGENT_RAMP_LATENCY;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_urgent_ramp_latency_params.hubbub = hubbub;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_urgent_ramp_latency_params.refclk_mhz = refclk_mhz;
seq_state->steps[*seq_state->num_steps].params.hubbub_perfmon_get_urgent_ramp_latency_params.latency_ns = latency_ns;
(*seq_state->num_steps)++;
}
}
void hwss_add_hubp_clk_cntl(struct block_sequence_state *seq_state,
struct hubp *hubp,
bool enable)

View File

@ -361,6 +361,7 @@ void dc_state_destruct(struct dc_state *state)
state->phantom_plane_count = 0;
memset(state->probes, 0, sizeof(state->probes));
memset(state->probe_status, 0, sizeof(state->probe_status));
state->probe_count = 0;
state->stream_mask = 0;

View File

@ -32,6 +32,7 @@
#include "inc/hw/link_encoder.h"
#include "inc/core_status.h"
#include "inc/hw/hw_shared.h"
#include "inc/hw/dchubbub.h"
#include "dsc/dsc.h"
#include "link_service_types.h"
@ -53,7 +54,6 @@ struct drr_params;
struct dc_underflow_debug_data;
struct dsc_optc_config;
struct vm_system_aperture_param;
struct dc_measured_memory_qos;
struct stream_encoder;
struct hpo_dp_stream_encoder;
struct hpo_frl_stream_encoder;
@ -580,6 +580,77 @@ struct hubbub_soft_reset_params {
bool reset;
};
struct hubbub_perfmon_reset_params {
struct hubbub *hubbub;
};
struct hubbub_perfmon_arm_out_of_order_bw_params {
struct hubbub *hubbub;
};
struct hubbub_perfmon_start_out_of_order_bw_params {
struct hubbub *hubbub;
};
struct hubbub_perfmon_start_in_order_bw_params {
struct hubbub *hubbub;
};
struct hubbub_perfmon_start_memory_latencies_params {
struct hubbub *hubbub;
};
struct hubbub_perfmon_start_urgent_assertion_count_params {
struct hubbub *hubbub;
};
struct hubbub_perfmon_start_urgent_ramp_latency_params {
struct hubbub *hubbub;
struct hubbub_urgent_latency_params latency_params;
};
struct hubbub_perfmon_start_prefetch_data_size_params {
struct hubbub *hubbub;
};
struct hubbub_perfmon_get_out_of_order_bw_params {
struct hubbub *hubbub;
uint32_t refclk_mhz;
uint32_t *bandwidth_mbps;
uint32_t *duration_ns;
};
struct hubbub_perfmon_get_in_order_bw_params {
struct hubbub *hubbub;
uint32_t refclk_mhz;
uint32_t min_duration_ns;
uint32_t *bandwidth_mbps;
uint32_t *duration_ns;
};
struct hubbub_perfmon_get_memory_latencies_params {
struct hubbub *hubbub;
uint32_t refclk_mhz;
struct hubbub_system_latencies *result;
};
struct hubbub_perfmon_get_urgent_assertion_count_params {
struct hubbub *hubbub;
uint32_t refclk_mhz;
uint32_t *assertion_count;
};
struct hubbub_perfmon_get_prefetch_data_size_params {
struct hubbub *hubbub;
uint32_t *prefetch_data_size;
};
struct hubbub_perfmon_get_urgent_ramp_latency_params {
struct hubbub *hubbub;
uint32_t refclk_mhz;
uint32_t *latency_ns;
};
struct hubp_clk_cntl_params {
struct hubp *hubp;
bool enable;
@ -1031,6 +1102,20 @@ union block_sequence_params {
struct hubp_set_blank_en_params hubp_set_blank_en_params;
struct hubp_disable_control_params hubp_disable_control_params;
struct hubbub_soft_reset_params hubbub_soft_reset_params;
struct hubbub_perfmon_reset_params hubbub_perfmon_reset_params;
struct hubbub_perfmon_arm_out_of_order_bw_params hubbub_perfmon_arm_out_of_order_bw_params;
struct hubbub_perfmon_start_out_of_order_bw_params hubbub_perfmon_start_out_of_order_bw_params;
struct hubbub_perfmon_start_in_order_bw_params hubbub_perfmon_start_in_order_bw_params;
struct hubbub_perfmon_start_memory_latencies_params hubbub_perfmon_start_memory_latencies_params;
struct hubbub_perfmon_start_urgent_assertion_count_params hubbub_perfmon_start_urgent_assertion_count_params;
struct hubbub_perfmon_start_urgent_ramp_latency_params hubbub_perfmon_start_urgent_ramp_latency_params;
struct hubbub_perfmon_start_prefetch_data_size_params hubbub_perfmon_start_prefetch_data_size_params;
struct hubbub_perfmon_get_out_of_order_bw_params hubbub_perfmon_get_out_of_order_bw_params;
struct hubbub_perfmon_get_in_order_bw_params hubbub_perfmon_get_in_order_bw_params;
struct hubbub_perfmon_get_memory_latencies_params hubbub_perfmon_get_memory_latencies_params;
struct hubbub_perfmon_get_urgent_assertion_count_params hubbub_perfmon_get_urgent_assertion_count_params;
struct hubbub_perfmon_get_prefetch_data_size_params hubbub_perfmon_get_prefetch_data_size_params;
struct hubbub_perfmon_get_urgent_ramp_latency_params hubbub_perfmon_get_urgent_ramp_latency_params;
struct hubp_clk_cntl_params hubp_clk_cntl_params;
struct hubp_init_params hubp_init_params;
struct hubp_set_vm_system_aperture_settings_params hubp_set_vm_system_aperture_settings_params;
@ -1258,6 +1343,20 @@ enum block_sequence_func {
HUBBUB_PROGRAM_WATERMARKS,
HUBBUB_PROGRAM_ARBITER,
HUBBUB_PROGRAM_COMPBUF_SEGMENTS,
HUBBUB_PERFMON_RESET,
HUBBUB_PERFMON_ARM_OUT_OF_ORDER_BW,
HUBBUB_PERFMON_START_OUT_OF_ORDER_BW,
HUBBUB_PERFMON_START_IN_ORDER_BW,
HUBBUB_PERFMON_START_MEMORY_LATENCIES,
HUBBUB_PERFMON_START_URGENT_ASSERTION_COUNT,
HUBBUB_PERFMON_START_URGENT_RAMP_LATENCY,
HUBBUB_PERFMON_START_PREFETCH_DATA_SIZE,
HUBBUB_PERFMON_GET_OUT_OF_ORDER_BW,
HUBBUB_PERFMON_GET_IN_ORDER_BW,
HUBBUB_PERFMON_GET_MEMORY_LATENCIES,
HUBBUB_PERFMON_GET_URGENT_ASSERTION_COUNT,
HUBBUB_PERFMON_GET_PREFETCH_DATA_SIZE,
HUBBUB_PERFMON_GET_URGENT_RAMP_LATENCY,
/* This must be the last value in this enum, add new ones above */
HWSS_BLOCK_SEQUENCE_FUNC_COUNT
};
@ -1591,14 +1690,16 @@ struct hw_sequencer_funcs {
struct dc_underflow_debug_data *out_data);
/**
* measure_memory_qos - Measure memory QoS metrics
* @dc: DC structure
* @qos: Pointer to dc_measured_memory_qos struct to populate with measured values
* program_perfmon - Program/transition perfmon probes for a commit.
* @dc: DC structure
* @context: target state; probes, probe_count, and probe_status are
* read from and written to this object
*
* Populates the provided dc_measured_memory_qos struct with peak bandwidth, average bandwidth,
* max latency, min latency, and average latency from hardware performance counters.
* Invoked during the execute phase of dc_update_state. The hook resolves
* each probe's transition by diffing @context against dc->current_state
* and latches MEASURED results into @context->probe_status.
*/
void (*measure_memory_qos)(struct dc *dc, struct dc_measured_memory_qos *qos);
void (*program_perfmon)(struct dc *dc, struct dc_state *context);
};
@ -1875,6 +1976,34 @@ void hwss_hubp_disable_control(union block_sequence_params *params);
void hwss_hubbub_soft_reset(union block_sequence_params *params);
void hwss_hubbub_perfmon_reset(union block_sequence_params *params);
void hwss_hubbub_perfmon_arm_out_of_order_bw(union block_sequence_params *params);
void hwss_hubbub_perfmon_start_out_of_order_bw(union block_sequence_params *params);
void hwss_hubbub_perfmon_start_in_order_bw(union block_sequence_params *params);
void hwss_hubbub_perfmon_start_memory_latencies(union block_sequence_params *params);
void hwss_hubbub_perfmon_start_urgent_assertion_count(union block_sequence_params *params);
void hwss_hubbub_perfmon_start_urgent_ramp_latency(union block_sequence_params *params);
void hwss_hubbub_perfmon_start_prefetch_data_size(union block_sequence_params *params);
void hwss_hubbub_perfmon_get_out_of_order_bw(union block_sequence_params *params);
void hwss_hubbub_perfmon_get_in_order_bw(union block_sequence_params *params);
void hwss_hubbub_perfmon_get_memory_latencies(union block_sequence_params *params);
void hwss_hubbub_perfmon_get_urgent_assertion_count(union block_sequence_params *params);
void hwss_hubbub_perfmon_get_prefetch_data_size(union block_sequence_params *params);
void hwss_hubbub_perfmon_get_urgent_ramp_latency(union block_sequence_params *params);
void hwss_hubp_clk_cntl(union block_sequence_params *params);
void hwss_hubp_init(union block_sequence_params *params);
@ -2213,6 +2342,54 @@ void hwss_add_hubbub_soft_reset(struct block_sequence_state *seq_state,
void (*hubbub_soft_reset)(struct hubbub *hubbub, bool reset),
bool reset);
void hwss_add_hubbub_perfmon_reset(struct block_sequence_state *seq_state,
struct hubbub *hubbub);
void hwss_add_hubbub_perfmon_arm_out_of_order_bw(struct block_sequence_state *seq_state,
struct hubbub *hubbub);
void hwss_add_hubbub_perfmon_start_out_of_order_bw(struct block_sequence_state *seq_state,
struct hubbub *hubbub);
void hwss_add_hubbub_perfmon_start_in_order_bw(struct block_sequence_state *seq_state,
struct hubbub *hubbub);
void hwss_add_hubbub_perfmon_start_memory_latencies(struct block_sequence_state *seq_state,
struct hubbub *hubbub);
void hwss_add_hubbub_perfmon_start_urgent_assertion_count(struct block_sequence_state *seq_state,
struct hubbub *hubbub);
void hwss_add_hubbub_perfmon_start_urgent_ramp_latency(struct block_sequence_state *seq_state,
struct hubbub *hubbub,
const struct hubbub_urgent_latency_params *latency_params);
void hwss_add_hubbub_perfmon_start_prefetch_data_size(struct block_sequence_state *seq_state,
struct hubbub *hubbub);
void hwss_add_hubbub_perfmon_get_out_of_order_bw(struct block_sequence_state *seq_state,
struct hubbub *hubbub, uint32_t refclk_mhz,
uint32_t *bandwidth_mbps, uint32_t *duration_ns);
void hwss_add_hubbub_perfmon_get_in_order_bw(struct block_sequence_state *seq_state,
struct hubbub *hubbub, uint32_t refclk_mhz, uint32_t min_duration_ns,
uint32_t *bandwidth_mbps, uint32_t *duration_ns);
void hwss_add_hubbub_perfmon_get_memory_latencies(struct block_sequence_state *seq_state,
struct hubbub *hubbub, uint32_t refclk_mhz,
struct hubbub_system_latencies *result);
void hwss_add_hubbub_perfmon_get_urgent_assertion_count(struct block_sequence_state *seq_state,
struct hubbub *hubbub, uint32_t refclk_mhz,
uint32_t *assertion_count);
void hwss_add_hubbub_perfmon_get_prefetch_data_size(struct block_sequence_state *seq_state,
struct hubbub *hubbub, uint32_t *prefetch_data_size);
void hwss_add_hubbub_perfmon_get_urgent_ramp_latency(struct block_sequence_state *seq_state,
struct hubbub *hubbub, uint32_t refclk_mhz,
uint32_t *latency_ns);
void hwss_add_hubp_clk_cntl(struct block_sequence_state *seq_state,
struct hubp *hubp,
bool enable);

View File

@ -33,6 +33,7 @@
#include "dc_bios_types.h"
#include "mem_input.h"
#include "hubp.h"
#include "hw/dchubbub.h"
#include "mpc.h"
#include "dwb.h"
#include "hw/dio.h"
@ -609,6 +610,27 @@ struct dc_dmub_cmd {
enum dm_dmub_wait_type wait_type;
};
/**
* struct dc_probe_status - DC-internal latched perfmon results for a probe.
* @valid: true if a measurement was latched this commit.
* @type: type of the probe that produced this result.
* @u.bandwidth_mbps: peak BW in Mbps (DC_PROBE_PEAK_MEM_BW).
* @u.latency: min/max/avg memory latency in ns (DC_PROBE_MEM_LATENCY),
* stored as struct hubbub_system_latencies.
* @u.urgent_assertion_count: number of urgent assertion events (DC_PROBE_URGENT_ASSERTION_COUNT).
* @u.prefetch_data_size: total prefetch data in bytes (DC_PROBE_PREFETCH_DATA_SIZE).
*/
struct dc_probe_status {
bool valid;
enum dc_probe_type type;
union {
uint32_t bandwidth_mbps;
struct hubbub_system_latencies latency;
uint32_t urgent_assertion_count;
uint32_t prefetch_data_size;
} u;
};
/**
* struct dc_state - The full description of a state requested by users
*/
@ -652,6 +674,11 @@ struct dc_state {
*/
struct dc_probe_state probes[MAX_PROBES];
/**
* @probe_status: Committed absolute set of probe results.
*/
struct dc_probe_status probe_status[MAX_PROBES];
/**
* @probe_count: Number of valid entries in @probes.
*/

View File

@ -158,6 +158,12 @@ struct hubbub_urgent_latency_params {
uint32_t bw_factor_x1000;
};
struct hubbub;
struct dchub_init_data;
struct dc_dcc_surface_param;
struct dc_surface_dcc_cap;
union dcn_watermark_set;
struct dml2_display_arb_regs;
struct hubbub_funcs {
void (*update_dchub)(
struct hubbub *hubbub,
@ -274,9 +280,11 @@ struct hubbub_funcs {
const struct hubbub_urgent_latency_params *params);
uint32_t (*get_urgent_ramp_latency_ns)(struct hubbub *hubbub,
uint32_t refclk_mhz);
void (*start_measuring_unbounded_bandwidth)(
void (*arm_measuring_out_of_order_bandwidth)(
struct hubbub *hubbub);
uint32_t (*get_unbounded_bandwidth_mbps)(struct hubbub *hubbub,
void (*start_measuring_out_of_order_bandwidth)(
struct hubbub *hubbub);
uint32_t (*get_out_of_order_bandwidth_mbps)(struct hubbub *hubbub,
uint32_t refclk_mhz, uint32_t *duration_ns);
void (*start_measuring_in_order_bandwidth)(
struct hubbub *hubbub);