]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd/display: Add workaround to restrict max frac urgent for DPM0
authorSung-huai Wang <danny.wang@amd.com>
Thu, 13 Jun 2024 07:22:17 +0000 (15:22 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 27 Jun 2024 21:10:37 +0000 (17:10 -0400)
[WHY]
Underflow occurs on some platforms when urgent BW is close to
the maximum in DPM0.

[HOW]
It does not occur at DPM1, so as a workaround restrict the maximum
amount and increase the lowest state index for clock states until
we're out of DPM0.
Adds DML2 config options to specify this pe platform as required.

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Sung-huai Wang <danny.wang@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c
drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c

index f6310408dbbadf1d7f9f0d9841e26f9a8e36b4ac..f4038ac2e4765c4b78654013ab725712f523679a 100644 (file)
@@ -628,6 +628,21 @@ static bool dml2_validate_and_build_resource(const struct dc *in_dc, struct dc_s
 
        if (result) {
                unsigned int lowest_state_idx = s->mode_support_params.out_lowest_state_idx;
+               double min_fclk_mhz_for_urgent_workaround = (double)dml2->config.min_fclk_for_urgent_workaround_khz / 1000.0;
+               double max_frac_urgent = (double)dml2->config.max_frac_urgent_for_min_fclk_x1000 / 1000.0;
+
+               if (min_fclk_mhz_for_urgent_workaround > 0.0 && max_frac_urgent > 0.0 &&
+                   (dml2->v20.dml_core_ctx.mp.FractionOfUrgentBandwidth > max_frac_urgent ||
+                    dml2->v20.dml_core_ctx.mp.FractionOfUrgentBandwidthImmediateFlip > max_frac_urgent)) {
+                       unsigned int forced_lowest_state_idx = lowest_state_idx;
+
+                       while (forced_lowest_state_idx < dml2->v20.dml_core_ctx.states.num_states &&
+                              dml2->v20.dml_core_ctx.states.state_array[forced_lowest_state_idx].fabricclk_mhz <= min_fclk_mhz_for_urgent_workaround) {
+                               forced_lowest_state_idx += 1;
+                       }
+                       lowest_state_idx = forced_lowest_state_idx;
+               }
+
                out_clks.dispclk_khz = (unsigned int)dml2->v20.dml_core_ctx.mp.Dispclk_calculated * 1000;
                out_clks.p_state_supported = s->mode_support_info.DRAMClockChangeSupport[0] != dml_dram_clock_change_unsupported;
                if (in_dc->config.use_default_clock_table &&
index 20b3970c085719d531db4cb535105ecdbf9e4c93..79bf2d75780400b2b15f4d10e452c9dae82c211f 100644 (file)
@@ -237,6 +237,8 @@ struct dml2_configuration_options {
        bool use_clock_dc_limits;
        bool gpuvm_enable;
        struct dml2_soc_bb *bb_from_dmub;
+       int max_frac_urgent_for_min_fclk_x1000;
+       int min_fclk_for_urgent_workaround_khz;
 };
 
 /*
index 67ab8c1962ff45890d4681fab091fba5bc5c732b..1ce0f9ecff9cf0d777954abcb593f807a068dd83 100644 (file)
@@ -2152,8 +2152,9 @@ static bool dcn35_resource_construct(
        dc->dml2_options.callbacks.can_support_mclk_switch_using_fw_based_vblank_stretch = &dcn30_can_support_mclk_switch_using_fw_based_vblank_stretch;
 
        dc->dml2_options.max_segments_per_hubp = 24;
-
        dc->dml2_options.det_segment_size = DCN3_2_DET_SEG_SIZE;/*todo*/
+       dc->dml2_options.max_frac_urgent_for_min_fclk_x1000 = 900;
+       dc->dml2_options.min_fclk_for_urgent_workaround_khz = 400 * 1000;
 
        if (dc->config.sdpif_request_limit_words_per_umc == 0)
                dc->config.sdpif_request_limit_words_per_umc = 16;/*todo*/