]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/amd/display: Remove stutter only configurations
authorNasir Osman <nasir.osman@amd.com>
Wed, 1 Feb 2023 19:16:12 +0000 (14:16 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 11 May 2023 14:10:53 +0000 (23:10 +0900)
[ Upstream commit 71c4ca2d3b079d0ba4d9b3033641fea906cebfb6 ]

[why]
Newer ASICs such as DCN314 needs to allow for both self refresh and mem
clk switching rather than just self refresh only. Otherwise, we can see
some p-state hangs on ASICs that do support mem clk switching.

[how]
Added an allow_self_refresh_only flag for dcn30_internal_validate_bw
and created a validate_bw method for DCN314 with the allow_self_refresh_only
flag set to false (to support mem clk switching).

Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: Nasir Osman <nasir.osman@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Stable-dep-of: 1e994cc0956b ("drm/amd/display: limit timing for single dimm memory")
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.h
drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c

index c18c52a60100e5af2edae2879a1d0a2b1519e32e..c4e206aedf73135ac9a9f2c349e123308fdf1f0d 100644 (file)
@@ -1648,7 +1648,8 @@ noinline bool dcn30_internal_validate_bw(
                display_e2e_pipe_params_st *pipes,
                int *pipe_cnt_out,
                int *vlevel_out,
-               bool fast_validate)
+               bool fast_validate,
+               bool allow_self_refresh_only)
 {
        bool out = false;
        bool repopulate_pipes = false;
@@ -1675,7 +1676,7 @@ noinline bool dcn30_internal_validate_bw(
 
        dml_log_pipe_params(&context->bw_ctx.dml, pipes, pipe_cnt);
 
-       if (!fast_validate) {
+       if (!fast_validate || !allow_self_refresh_only) {
                /*
                 * DML favors voltage over p-state, but we're more interested in
                 * supporting p-state over voltage. We can't support p-state in
@@ -1688,11 +1689,12 @@ noinline bool dcn30_internal_validate_bw(
                if (vlevel < context->bw_ctx.dml.soc.num_states)
                        vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge);
        }
-       if (fast_validate || vlevel == context->bw_ctx.dml.soc.num_states ||
-                       vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported) {
+       if (allow_self_refresh_only &&
+           (fast_validate || vlevel == context->bw_ctx.dml.soc.num_states ||
+                       vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported)) {
                /*
-                * If mode is unsupported or there's still no p-state support then
-                * fall back to favoring voltage.
+                * If mode is unsupported or there's still no p-state support
+                * then fall back to favoring voltage.
                 *
                 * We don't actually support prefetch mode 2, so require that we
                 * at least support prefetch mode 1.
@@ -2063,7 +2065,7 @@ bool dcn30_validate_bandwidth(struct dc *dc,
        BW_VAL_TRACE_COUNT();
 
        DC_FP_START();
-       out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);
+       out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate, true);
        DC_FP_END();
 
        if (pipe_cnt == 0)
index 7d063c7d6a4bfdb3194683e3e3cdfb1ed32f9884..8e6b8b7368fdb32072b7c92818395963696cd88d 100644 (file)
@@ -64,7 +64,8 @@ bool dcn30_internal_validate_bw(
                display_e2e_pipe_params_st *pipes,
                int *pipe_cnt_out,
                int *vlevel_out,
-               bool fast_validate);
+               bool fast_validate,
+               bool allow_self_refresh_only);
 void dcn30_calculate_wm_and_dlg(
                struct dc *dc, struct dc_state *context,
                display_e2e_pipe_params_st *pipes,
index 3ca517dcc82dc5fedd6e683cea9e20858fd84cf6..d3918a10773a3e3060ac8acc487cfcdc494945e9 100644 (file)
@@ -1795,7 +1795,7 @@ bool dcn31_validate_bandwidth(struct dc *dc,
        BW_VAL_TRACE_COUNT();
 
        DC_FP_START();
-       out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);
+       out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate, true);
        DC_FP_END();
 
        // Disable fast_validate to set min dcfclk in alculate_wm_and_dlg
index 73f519dbdb531144f7535e7e143d07d42cb0a386..54ed3de869d3b001d98d8f8c0ab972fe7d819065 100644 (file)
@@ -1697,6 +1697,61 @@ static void dcn314_get_panel_config_defaults(struct dc_panel_config *panel_confi
        *panel_config = panel_config_defaults;
 }
 
+bool dcn314_validate_bandwidth(struct dc *dc,
+               struct dc_state *context,
+               bool fast_validate)
+{
+       bool out = false;
+
+       BW_VAL_TRACE_SETUP();
+
+       int vlevel = 0;
+       int pipe_cnt = 0;
+       display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
+       DC_LOGGER_INIT(dc->ctx->logger);
+
+       BW_VAL_TRACE_COUNT();
+
+       DC_FP_START();
+       // do not support self refresh only
+       out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate, false);
+       DC_FP_END();
+
+       // Disable fast_validate to set min dcfclk in calculate_wm_and_dlg
+       if (pipe_cnt == 0)
+               fast_validate = false;
+
+       if (!out)
+               goto validate_fail;
+
+       BW_VAL_TRACE_END_VOLTAGE_LEVEL();
+
+       if (fast_validate) {
+               BW_VAL_TRACE_SKIP(fast);
+               goto validate_out;
+       }
+
+       dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel);
+
+       BW_VAL_TRACE_END_WATERMARKS();
+
+       goto validate_out;
+
+validate_fail:
+       DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n",
+               dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states]));
+
+       BW_VAL_TRACE_SKIP(fail);
+       out = false;
+
+validate_out:
+       kfree(pipes);
+
+       BW_VAL_TRACE_FINISH();
+
+       return out;
+}
+
 static struct resource_funcs dcn314_res_pool_funcs = {
        .destroy = dcn314_destroy_resource_pool,
        .link_enc_create = dcn31_link_encoder_create,
@@ -1704,7 +1759,7 @@ static struct resource_funcs dcn314_res_pool_funcs = {
        .link_encs_assign = link_enc_cfg_link_encs_assign,
        .link_enc_unassign = link_enc_cfg_link_enc_unassign,
        .panel_cntl_create = dcn31_panel_cntl_create,
-       .validate_bandwidth = dcn31_validate_bandwidth,
+       .validate_bandwidth = dcn314_validate_bandwidth,
        .calculate_wm_and_dlg = dcn31_calculate_wm_and_dlg,
        .update_soc_for_wm_a = dcn31_update_soc_for_wm_a,
        .populate_dml_pipes = dcn314_populate_dml_pipes_from_context,
index 0dd3153aa5c17aaca0bcdf8229a0e788acae102a..49ffe71018dfb9dc0e445d5cc5f891ed61f3fdbd 100644 (file)
@@ -39,6 +39,10 @@ struct dcn314_resource_pool {
        struct resource_pool base;
 };
 
+bool dcn314_validate_bandwidth(struct dc *dc,
+               struct dc_state *context,
+               bool fast_validate);
+
 struct resource_pool *dcn314_create_resource_pool(
                const struct dc_init_data *init_data,
                struct dc *dc);
index d4c0f9cdac8e2f60254ef28aae50fd146894ee6e..4fa63636479371cad6eae210f0213f08d69b52a2 100644 (file)
@@ -634,7 +634,7 @@ int dcn30_find_dummy_latency_index_for_fw_based_mclk_switch(struct dc *dc,
        while (dummy_latency_index < max_latency_table_entries) {
                context->bw_ctx.dml.soc.dram_clock_change_latency_us =
                                dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us;
-               dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false);
+               dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false, true);
 
                if (context->bw_ctx.dml.soc.allow_dram_self_refresh_or_dram_clock_change_in_vblank ==
                        dm_allow_self_refresh_and_mclk_switch)