From: Dillon Varone <[email protected]> [WHY&HOW] Improves the optimization heuristic for "ideal" disallow time to clamp to a number more likely to pass the mandatory pstate checks.
Fixes core calculations to account for reserved time when considering the allow time for mandatory pstate checks. Reviewed-by: Austin Zheng <[email protected]> Signed-off-by: Dillon Varone <[email protected]> Signed-off-by: Ivan Lipski <[email protected]> --- .../dml2_core/dml2_core_dcn6_calcs_dchub.c | 5 +- .../dml2_pmo/dml2_pmo_dcn6_stage_optimizers.c | 97 +++++++++++-------- .../src/inc/dml2_internal_shared_types.h | 2 +- 3 files changed, 62 insertions(+), 42 deletions(-) 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 ce6eb94230c1..485ad96f64b1 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 @@ -1753,8 +1753,9 @@ void dcn6_calculate_pstate_schedule_windows( det_fill_delay_otg_vlines = (int)(math_ceil(det_fill_delay_us[k] / otg_vline_time_us[k])); reserved_vblank_otg_vlines = (int)(math_ceil(reserved_vblank_us[k] / otg_vline_time_us[k])); - allow_start_otg_vlines = v_blank_end[k] + det_fill_delay_otg_vlines; - allow_end_otg_vlines = v_blank_start[k] - (blackout_otg_vlines - reserved_vblank_otg_vlines); + /* for vactive only, make relative to vblank end */ + allow_start_otg_vlines = det_fill_delay_otg_vlines; + allow_end_otg_vlines = v_blank_start[k] - v_blank_end[k] - (blackout_otg_vlines - reserved_vblank_otg_vlines); /* Convert them back to time since the start of a frame */ allow_start_us[k] = allow_start_otg_vlines * otg_vline_time_us[k]; diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn6_stage_optimizers.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn6_stage_optimizers.c index 6d6611a6b5a6..40dcaa6588ff 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn6_stage_optimizers.c +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn6_stage_optimizers.c @@ -407,14 +407,20 @@ static bool dcn6_update_worksheet_for_pstate_admissibility(struct dml2_optimizat enum dml2_pstate_type pstate_type) { const double vblank_ratio = 0.8; - unsigned int plane_index, stream_index; - double ideal_relative_disallow, ideal_disallow_time_us, disallow_time_us; + const double min_vblank_unreserved_ratio = 0.15; + const double min_vblank_unreserved_time_us = 50.0; + // min reserved for prefetch + 1 line lost for max vstartup + const unsigned int min_vblank_unreserved_otg_vlines = 4 + 1; + + unsigned int plane_index, stream_index, stream_index1; + double ideal_disallow_time_us, disallow_time_us; double extra_time_required_us; double vblank_time_us; double min_unreserved_vblank_time_us; double min_det_fill_delay_us; double delta_max_det_fill_delay_us; double delta_reserved_vblank_time_us; + double smallest_allow_us; int max_vactive_det_fill_delay_us; long reserved_vblank_time_ns; @@ -428,54 +434,67 @@ static bool dcn6_update_worksheet_for_pstate_admissibility(struct dml2_optimizat * configs failing pstate admissibility tend to have a large vblank to vactive ratio. */ - ideal_relative_disallow = 1.0; - if (display_config->num_streams > 1) { - /* The disallow region should be less than (0.5) ^ (number of displays - 1) * total frame time - * Calculation assumes identical displays / timings when performing the scheduling check - * Make the relative disallow 5% smaller than the ideal case to add extra margin - */ - ideal_relative_disallow = (double)math_pow(0.5, (float)(display_config->num_streams - 1)) * 0.95; - } - for (stream_index = 0; stream_index < display_config->num_streams; stream_index++) { disallow_time_us = per_stream_pstate_meta[stream_index].method_vactive.common.disallow_time_us; - ideal_disallow_time_us = per_stream_pstate_meta[stream_index].method_vactive.common.period_us * ideal_relative_disallow; + ideal_disallow_time_us = disallow_time_us; + + /* find the smallest active to build the heurisitic for ideal disallow */ + smallest_allow_us = 0.0; + for (stream_index1 = 0; stream_index1 < display_config->num_streams; stream_index1++) { + if (stream_index != stream_index1 && + (smallest_allow_us == 0.0 || + per_stream_pstate_meta[stream_index1].method_vactive.common.allow_time_us < smallest_allow_us)) { + smallest_allow_us = per_stream_pstate_meta[stream_index1].method_vactive.common.allow_time_us; + } + } - extra_time_required_us = 0.0; delta_max_det_fill_delay_us = 0.0; delta_reserved_vblank_time_us = 0.0; - if (disallow_time_us > ideal_disallow_time_us) { - /* minimum unreserved 15% of blank, or 50us left over for prefetch */ - vblank_time_us = display_config->stream_descriptors[stream_index].timing.vblank_nom * + if (worksheet->fclk_ppt_temp_read_pstate.index > 0) { + if (smallest_allow_us > 0.0 && display_config->num_streams > 1) { + ideal_disallow_time_us = smallest_allow_us / math_pow(2.0, (float)display_config->num_streams - 2) * + (1.0 / (2.0 - math_pow(2.0, (float)(2 - display_config->num_streams)))); + } + + extra_time_required_us = 0.0; + delta_max_det_fill_delay_us = 0.0; + delta_reserved_vblank_time_us = 0.0; + if (disallow_time_us > ideal_disallow_time_us) { + /* minimum unreserved 15% of blank, or 50us left over for prefetch */ + vblank_time_us = display_config->stream_descriptors[stream_index].timing.vblank_nom * per_stream_pstate_meta[stream_index].otg_vline_time_us; - min_unreserved_vblank_time_us = math_min2(vblank_time_us * 0.15, 50); + min_unreserved_vblank_time_us = math_max2( + per_stream_pstate_meta[stream_index].otg_vline_time_us * min_vblank_unreserved_otg_vlines, + math_min2(vblank_time_us * min_vblank_unreserved_ratio, + min_vblank_unreserved_time_us)); - /* minmum of blackout time (~2x VActive bandwidth) */ - min_det_fill_delay_us = per_stream_pstate_meta[stream_index].blackout_otg_vlines * + /* minmum of blackout time (~2x VActive bandwidth) */ + min_det_fill_delay_us = per_stream_pstate_meta[stream_index].blackout_otg_vlines * per_stream_pstate_meta[stream_index].otg_vline_time_us; - extra_time_required_us = disallow_time_us - ideal_disallow_time_us; + extra_time_required_us = disallow_time_us - ideal_disallow_time_us; - /* try compressing VActive fill first */ - delta_max_det_fill_delay_us = math_min2(extra_time_required_us * (1.0 - vblank_ratio), + /* try compressing VActive fill first */ + delta_max_det_fill_delay_us = math_min2(extra_time_required_us * (1.0 - vblank_ratio), math_max2(0.0, - per_stream_pstate_meta[stream_index].method_vactive.max_vactive_det_fill_delay_us - min_det_fill_delay_us)); - delta_max_det_fill_delay_us = math_floor2(delta_max_det_fill_delay_us, per_stream_pstate_meta[stream_index].otg_vline_time_us); - extra_time_required_us -= delta_max_det_fill_delay_us; + per_stream_pstate_meta[stream_index].method_vactive.max_vactive_det_fill_delay_us - min_det_fill_delay_us)); + delta_max_det_fill_delay_us = math_floor2(delta_max_det_fill_delay_us, per_stream_pstate_meta[stream_index].otg_vline_time_us); + extra_time_required_us -= delta_max_det_fill_delay_us; - /* try reserving VBlank */ - delta_reserved_vblank_time_us = math_min2(extra_time_required_us, + /* try reserving VBlank */ + delta_reserved_vblank_time_us = math_min2(extra_time_required_us, math_max2(0.0, - vblank_time_us - per_stream_pstate_meta[stream_index].method_vactive.reserved_vblank_required_us - min_unreserved_vblank_time_us)); - delta_reserved_vblank_time_us = math_floor2(delta_reserved_vblank_time_us, per_stream_pstate_meta[stream_index].otg_vline_time_us); - extra_time_required_us -= delta_reserved_vblank_time_us; + vblank_time_us - per_stream_pstate_meta[stream_index].method_vactive.reserved_vblank_required_us - min_unreserved_vblank_time_us)); + delta_reserved_vblank_time_us = math_floor2(delta_reserved_vblank_time_us, per_stream_pstate_meta[stream_index].otg_vline_time_us); + extra_time_required_us -= delta_reserved_vblank_time_us; - if (extra_time_required_us > 0.0 && + if (extra_time_required_us > 0.0 && per_stream_pstate_meta[stream_index].method_vactive.max_vactive_det_fill_delay_us > math_ceil2(delta_max_det_fill_delay_us + extra_time_required_us, per_stream_pstate_meta[stream_index].otg_vline_time_us)) { - /* final attempt to compress fill time */ - delta_max_det_fill_delay_us = delta_max_det_fill_delay_us + extra_time_required_us; - delta_max_det_fill_delay_us = math_ceil2(delta_max_det_fill_delay_us, per_stream_pstate_meta[stream_index].otg_vline_time_us); - extra_time_required_us = 0.0; + /* final attempt to compress fill time */ + delta_max_det_fill_delay_us = delta_max_det_fill_delay_us + extra_time_required_us; + delta_max_det_fill_delay_us = math_ceil2(delta_max_det_fill_delay_us, per_stream_pstate_meta[stream_index].otg_vline_time_us); + extra_time_required_us = 0.0; + } } } @@ -1688,7 +1707,7 @@ static void dml2_pmo_dcn6_stage_optimizer_fclk_ppt_temp_read_pstate_init( struct dml2_pmo_stage_optimizer *stage, struct dml2_optimization_worksheet *worksheet) { DML_LOG_COMP_IF_ENTER(); - worksheet->fclk_ppt_temp_read_pstate.is_attempted = false; + worksheet->fclk_ppt_temp_read_pstate.index = 0; memset(&stage->func_locals->fclk_ppt_temp_read_pstate_optimize, 0, sizeof(struct dml2_stage_optimizer_fclk_ppt_temp_read_pstate_optimize_locals)); DML_LOG_COMP_IF_EXIT(); @@ -1712,13 +1731,11 @@ static bool dml2_pmo_dcn6_stage_optimizer_fclk_ppt_temp_read_pstate_optimize_nex DML_LOG_COMP_IF_ENTER(); - if (worksheet->fclk_ppt_temp_read_pstate.is_attempted) { + if (worksheet->fclk_ppt_temp_read_pstate.index >= 2) { DML_LOG_COMP_IF_EXIT(); return false; } - worksheet->fclk_ppt_temp_read_pstate.is_attempted = true; - if (display_config->overrides.all_streams_blanked) goto exit; @@ -1761,6 +1778,8 @@ static bool dml2_pmo_dcn6_stage_optimizer_fclk_ppt_temp_read_pstate_optimize_nex } } + worksheet->fclk_ppt_temp_read_pstate.index++; + exit: DML_LOG_DEBUG("%s exit with should_continue = %s\n", __func__, modified ? "true" : "false"); DML_LOG_COMP_IF_EXIT(); 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 dc9d4be9d7f7..6f527760071c 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 @@ -643,7 +643,7 @@ struct dml2_optimization_worksheet { } dcfclk_vmin; struct { - bool is_attempted; + unsigned int index; } fclk_ppt_temp_read_pstate; /* -- 2.43.0
