summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlvin Lee <Alvin.Lee2@amd.com>2026-08-19 14:30:07 -0400
committerAlex Deucher <alexander.deucher@amd.com>2026-09-10 11:58:51 -0400
commitc993759b2a8500c1908f7db5c7f6fac9d3e2d022 (patch)
tree11a2c21f3e24e7a365629aa99826cdb2e33139d1
parent281eacf0c167303fe57877e0e7f3981ed6262d2d (diff)
downloadlinux-next-c993759b2a8500c1908f7db5c7f6fac9d3e2d022.tar.gz
linux-next-c993759b2a8500c1908f7db5c7f6fac9d3e2d022.zip
drm/amd/display: Ensure requested LSDMA BW is within the SOP bound
[Why & How] - When calculating the required LSDMA bandwidth, it must be capped to the global maximum LSDMA BW. - Also check the calculated bandwidth against what is available in the SOP - Rework code to only compute alt-ch params if alt-ch is in use - Also remove some unused fields - Fix whitespace errors Reviewed-by: Wenjing Liu <wenjing.liu@amd.com> Signed-off-by: Alvin Lee <Alvin.Lee2@amd.com> Signed-off-by: Ray Wu <ray.wu@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn6_soc_bb.h12
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_types.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_calcs_dchub.c33
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_support.c37
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_utm_soc_bb/dml2_utm_soc_bb_dcn6.c7
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h1
8 files changed, 77 insertions, 18 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn6_soc_bb.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn6_soc_bb.h
index 19d43e5b7cc2..04292e77698b 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn6_soc_bb.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn6_soc_bb.h
@@ -206,6 +206,18 @@ static inline void dcn6_test_initialize_v3_sop_latencies_all_levels(
df_response_time_ps);
}
+/**
+ * dcn6_test_override_lsdma_bandwidth_v3 - Debug / test interface that
+ * can be used to override the LSDMA bandwidth as needed for any LL and SOP.
+ * @dchub: DCN6 flat UTM QoS v3 table to modify
+ */
+static inline void dcn6_test_override_lsdma_bandwidth_v3(
+ struct utm_qos_model_dchub_v3 *dchub)
+{
+ /* Implement override as needed */
+ (void)dchub;
+}
+
static inline void dcn6_test_initialize_utm_qos_model_v3(
struct utm_qos_model *qos_model,
struct utm_qos_model_dchub_v3 *dchub)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h
index 422833548aa6..80d652bab5e3 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h
@@ -172,6 +172,7 @@ struct dml2_soc_bb {
double lower_bound_bandwidth_dchub;
double fraction_of_urgent_bandwidth_nominal_target;
double fraction_of_urgent_bandwidth_flip_target;
+ unsigned int max_lsdma_bandwidth_kbps;
unsigned int dprefclk_mhz;
unsigned int xtalclk_mhz;
unsigned int pcie_refclk_mhz;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_types.h
index c04a4af1f3ea..c241ecaf4d7a 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_types.h
@@ -402,6 +402,7 @@ struct dml2_memory_path_bandwidth {
struct {
double urgent_bandwidth_kbps; // kbytes per sec
double non_urgent_bandwidth_kbps; // kbytes per sec
+ double lsdma_bandwidth_kbps; // kbytes per sec
} dcn5;
};
};
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_calcs_dchub.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_calcs_dchub.c
index ba0082e216d5..125ad095c2bb 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_calcs_dchub.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_calcs_dchub.c
@@ -458,6 +458,37 @@ void dcn6_calculate_alternate_params(struct dml2_core_calcs_calculate_alternate_
unsigned int fw_delay;
struct swath_params swath_params;
+ /* the alternate channel outputs are only meaningful when the alternate channel is in use;
+ * otherwise zero all outputs and return early */
+ if (!p->alt_chan_in_use) {
+ *p->svp0_max_bytes = 0;
+ *p->svp1_max_bytes = 0;
+ *p->lsdma_bw_req_for_alt_kbps = 0;
+
+ for (i = 0; i < p->display_cfg->num_planes; i++) {
+ p->svp0_max_bytes_per_dpp[i] = 0;
+ p->svp0_max_bytes_per_dpp_c[i] = 0;
+ p->svp1_max_bytes_per_dpp[i] = 0;
+ p->svp1_max_bytes_per_dpp_c[i] = 0;
+ p->total_swaths[i] = 0;
+ p->total_swaths_c[i] = 0;
+ p->prefetch_swaths[i] = 0;
+ p->prefetch_swaths_c[i] = 0;
+ p->prefetch_hdl_delta[i] = 0;
+ p->recout_hdl_delta[i] = 0;
+ p->prefetch_hdl_delta_c[i] = 0;
+ p->recout_hdl_delta_c[i] = 0;
+ }
+
+ for (i = 0; i < p->display_cfg->num_streams; i++) {
+ p->nom_req_limit_alt[i] = 0;
+ p->min_lead_dst_lines[i] = 0;
+ p->max_prefetch_in_lines[i] = 0;
+ }
+
+ return;
+ }
+
*p->svp0_max_bytes = 0;
*p->svp1_max_bytes = 0;
svp_max_bytes[0] = 0;
@@ -518,7 +549,7 @@ void dcn6_calculate_alternate_params(struct dml2_core_calcs_calculate_alternate_
*p->svp0_max_bytes = svp_max_bytes[0];
*p->svp1_max_bytes = svp_max_bytes[1];
- *p->lsdma_bw_req_for_alt_kbps = p->dcn_non_urgent_bandwidth_kbps;
+ *p->lsdma_bw_req_for_alt_kbps = math_min2(p->dcn_non_urgent_bandwidth_kbps, p->max_lsdma_bandwidth_kbps);
copy_time_us = p->display_cfg->overrides.hw.force_alt_chan_copy_time.enable ? p->display_cfg->overrides.hw.force_alt_chan_copy_time.copy_time_us : calculate_alt_copy_time_us(p);
fw_delay = p->display_cfg->overrides.hw.force_alt_chan_fw_delay.enable ? p->display_cfg->overrides.hw.force_alt_chan_fw_delay.fw_delay_us : p->alt_chan_fw_delay_us;
for (i = 0; i < p->display_cfg->num_streams; i++) {
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_support.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_support.c
index 5de84d6c73c0..de81815f098a 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_support.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_support.c
@@ -2242,8 +2242,19 @@ static void dcn6_ms_calculate_alternate_params(const struct dml2_core_calculate_
const struct dml2_utm_soc_bb *soc_bb = ctx->soc_bb;
struct dml2_core_internal_mode_support *inputs = states;
struct dml2_core_internal_mode_support *outputs = states;
+ unsigned int i;
+ bool is_alternate_pstate_required = false;
DML_LOG_FUNC_ENTER();
+
+ for (i = 0; i < ctx->display_cfg->num_planes; i++) {
+ if (ctx->display_cfg->plane_descriptors[i].overrides.uclk_pstate_change_strategy ==
+ dml2_uclk_pstate_change_strategy_force_alternate) {
+ is_alternate_pstate_required = true;
+ break;
+ }
+ }
+
p->display_cfg = ctx->display_cfg;
p->dst_y_prefetch = inputs->dst_y_prefetch;
p->SwathHeightY = inputs->SwathHeightY;
@@ -2271,16 +2282,17 @@ static void dcn6_ms_calculate_alternate_params(const struct dml2_core_calculate_
p->NoOfDPP = inputs->NoOfDPP;
p->max_num_dpp = ctx->ip->max_num_dpp;
p->dram_blackout_us = soc_bb->power_management_parameters.dram_clk_change_blackout_us;
- p->VActiveLatencyHidingUs = inputs->VActiveLatencyHidingUs;
p->svp0_dst_lines = inputs->svp0_dst_lines;
p->svp1_dst_lines = inputs->svp1_dst_lines;
p->svp_req_limit = inputs->svp_req_limit;
- p->dcn_non_urgent_bandwidth_kbps = inputs->support.bandwidth_upper_bound.dcn5.non_urgent_bandwidth_kbps;
+ p->dcn_non_urgent_bandwidth_kbps = **inputs->support.non_urg_bandwidth_required_flip * 1000;
+ p->max_lsdma_bandwidth_kbps = soc_bb->max_lsdma_bandwidth_kbps;
p->alt_chan_fw_delay_us = ctx->ip->alt_chan_fw_delay_us;
p->dst_y_per_vm_vblank = inputs->LinesForVM;
p->dst_y_per_row_vblank = inputs->LinesForDPTERow;
p->DSTYAfterScaler = inputs->DSTYAfterScaler;
p->ODMMode = inputs->ODMMode;
+ p->alt_chan_in_use = is_alternate_pstate_required;
p->svp0_max_bytes = &outputs->svp0_max_bytes;
p->svp1_max_bytes = &outputs->svp1_max_bytes;
@@ -3217,8 +3229,11 @@ static void dcn6_ms_calculate_bandwidth_upper_bound(const struct dml2_core_calcu
math_max3(**inputs->support.urg_bandwidth_required_flip,
**inputs->support.non_urg_bandwidth_required / ctx->soc_bb->fraction_of_urgent_bandwidth_nominal_target,
**inputs->support.non_urg_bandwidth_required_flip / ctx->soc_bb->fraction_of_urgent_bandwidth_flip_target) * 1000;
+ outputs->support.bandwidth_upper_bound.dcn5.lsdma_bandwidth_kbps = inputs->lsdma_bw_req_for_alt_kbps;
+
DML_LOG_DEBUG_DOUBLE(outputs->support.bandwidth_upper_bound.dcn5.non_urgent_bandwidth_kbps);
DML_LOG_DEBUG_DOUBLE(outputs->support.bandwidth_upper_bound.dcn5.urgent_bandwidth_kbps);
+ DML_LOG_DEBUG_DOUBLE(outputs->support.bandwidth_upper_bound.dcn5.lsdma_bandwidth_kbps);
DML_LOG_FUNC_EXIT();
}
@@ -3650,8 +3665,6 @@ static void dcn6_ms_check_alternate_channel_size_support(
const struct dml2_core_calculate_ms_context *ctx,
struct dml2_core_internal_mode_support *states)
{
- unsigned int i;
- bool alt_chan_in_use = false;
const struct dml2_utm_soc_bb *soc_bb = ctx->soc_bb;
struct dml2_core_internal_mode_support *inputs = states;
struct dml2_core_internal_mode_support *outputs = states;
@@ -3661,16 +3674,8 @@ static void dcn6_ms_check_alternate_channel_size_support(
DML_LOG_FUNC_ENTER();
outputs->support.alternate_channel_size_support = true;
- //Alternate Channel Size Support Check - only fail if alternate channels are used AND exceed carveout limit
- for (i = 0; i < ctx->display_cfg->num_planes; i++) {
- if (ctx->display_cfg->plane_descriptors[i].overrides.uclk_pstate_change_strategy == dml2_uclk_pstate_change_strategy_force_alternate) {
- alt_chan_in_use = true;
- break;
- }
- }
-
- if (alt_chan_in_use && (inputs->svp0_max_bytes > alternate_carveout_size_bytes ||
- inputs->svp1_max_bytes > alternate_carveout_size_bytes)) {
+ if (inputs->svp0_max_bytes > alternate_carveout_size_bytes ||
+ inputs->svp1_max_bytes > alternate_carveout_size_bytes) {
outputs->support.alternate_channel_size_support = false;
}
@@ -4081,6 +4086,8 @@ static enum dml2_status dcn6_ms_validate_prefetch(
dcn6_ms_calculate_peak_bandwidth_required(ctx, states);
+ dcn6_ms_calculate_alternate_params(ctx, states);
+
dcn6_ms_calculate_bandwidth_upper_bound(ctx, states);
dcn6_ms_check_qos_bandwidth_support(ctx, states);
@@ -4095,8 +4102,6 @@ static enum dml2_status dcn6_ms_validate_prefetch(
dcn6_ms_calculate_vactive_det_fill_latency(ctx, states);
- dcn6_ms_calculate_alternate_params(ctx, states);
-
dcn6_ms_check_alternate_channel_size_support(ctx, states);
dcn6_ms_calculate_pstate_schedule_windows(ctx, states);
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h
index df552eac0006..289ed250f477 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h
@@ -2309,16 +2309,17 @@ struct dml2_core_calcs_calculate_alternate_params {
unsigned int *NoOfDPP;
unsigned int max_num_dpp;
double dram_blackout_us;
- double *VActiveLatencyHidingUs;
unsigned int *svp0_dst_lines;
unsigned int *svp1_dst_lines;
unsigned int *svp_req_limit;
double dcn_non_urgent_bandwidth_kbps;
+ double max_lsdma_bandwidth_kbps;
unsigned int alt_chan_fw_delay_us;
double *dst_y_per_vm_vblank;
double *dst_y_per_row_vblank;
unsigned int *DSTYAfterScaler;
enum dml2_odm_mode *ODMMode;
+ bool alt_chan_in_use;
/* output params */
unsigned int *svp0_max_bytes;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_utm_soc_bb/dml2_utm_soc_bb_dcn6.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_utm_soc_bb/dml2_utm_soc_bb_dcn6.c
index 9c6892edca8a..937205f1f086 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_utm_soc_bb/dml2_utm_soc_bb_dcn6.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_utm_soc_bb/dml2_utm_soc_bb_dcn6.c
@@ -181,6 +181,8 @@ static bool dcn6_v3_sop_table_is_bandwidth_supported_at_index(
&dchub->sops[UTM_QOS_MODEL_V3_LOAD_LEVEL_IDLE][index];
const struct utm_qos_model_dchub_v3_sop_entry *active_entry =
&dchub->sops[UTM_QOS_MODEL_V3_LOAD_LEVEL_ACTIVE_ALTERNATE_PSTATE][highest_sop_index];
+ const struct utm_qos_model_dchub_v3_sop_entry *pstate_entry =
+ &dchub->sops[UTM_QOS_MODEL_V3_LOAD_LEVEL_ACTIVE_ALTERNATE_PSTATE][index];
if (bw->dcn5.non_urgent_bandwidth_kbps > idle_entry->nominal_bandwidth_KBps
|| bw->dcn5.urgent_bandwidth_kbps > idle_entry->urgent_bandwidth_KBps)
@@ -190,6 +192,10 @@ static bool dcn6_v3_sop_table_is_bandwidth_supported_at_index(
|| bw->dcn5.urgent_bandwidth_kbps > active_entry->urgent_bandwidth_KBps)
return false;
+ /* check if the requested lsdma bandwidth fits within the current sop's alt-pstate lsdma budget */
+ if (bw->dcn5.lsdma_bandwidth_kbps > pstate_entry->lsdma_bandwidth_KBps)
+ return false;
+
return true;
}
@@ -321,6 +327,7 @@ static void dcn6_initialize_from_soc_bb(struct dml2_utm_soc_bb *utm_soc_bb,
utm_soc_bb->lower_bound_bandwidth_dchub = soc_bb->lower_bound_bandwidth_dchub;
utm_soc_bb->fraction_of_urgent_bandwidth_nominal_target = soc_bb->fraction_of_urgent_bandwidth_nominal_target;
utm_soc_bb->fraction_of_urgent_bandwidth_flip_target = soc_bb->fraction_of_urgent_bandwidth_flip_target;
+ utm_soc_bb->max_lsdma_bandwidth_kbps = soc_bb->max_lsdma_bandwidth_kbps;
}
static void dcn6_initialize_from_qos_model(struct dml2_utm_soc_bb *utm_soc_bb,
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h
index 8ddf58da2eed..4289f7f998ff 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h
@@ -117,6 +117,7 @@ struct dml2_utm_soc_bb {
double lower_bound_bandwidth_dchub;
double fraction_of_urgent_bandwidth_nominal_target;
double fraction_of_urgent_bandwidth_flip_target;
+ unsigned int max_lsdma_bandwidth_kbps;
unsigned int dchub_refclk_mhz;
unsigned int max_outstanding_reqs;
unsigned long return_bus_width_bytes;