diff options
| author | Alvin Lee <Alvin.Lee2@amd.com> | 2026-08-19 14:30:07 -0400 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2026-09-10 11:58:51 -0400 |
| commit | c993759b2a8500c1908f7db5c7f6fac9d3e2d022 (patch) | |
| tree | 11a2c21f3e24e7a365629aa99826cdb2e33139d1 | |
| parent | 281eacf0c167303fe57877e0e7f3981ed6262d2d (diff) | |
| download | linux-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>
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; |
