drm/amd/display: Set min dcfclk if pipe count is 0
authorjsg <jsg@openbsd.org>
Wed, 13 Jul 2022 03:42:13 +0000 (03:42 +0000)
committerjsg <jsg@openbsd.org>
Wed, 13 Jul 2022 03:42:13 +0000 (03:42 +0000)
From Michael Strauss
f276634b12fa8f63988be9cf5492c7d60d5ad7b1 in linux 5.15.y/5.15.54
bc204778b4032b336cb3bde85bea852d79e7e389 in mainline linux

sys/dev/pci/drm/amd/display/dc/dcn30/dcn30_resource.c
sys/dev/pci/drm/amd/display/dc/dcn30/dcn30_resource.h
sys/dev/pci/drm/amd/display/dc/dcn31/dcn31_resource.c

index 0294d0c..735c92a 100644 (file)
@@ -1856,7 +1856,7 @@ static struct pipe_ctx *dcn30_find_split_pipe(
        return pipe;
 }
 
-static noinline bool dcn30_internal_validate_bw(
+noinline bool dcn30_internal_validate_bw(
                struct dc *dc,
                struct dc_state *context,
                display_e2e_pipe_params_st *pipes,
index b754b89..b92e4cc 100644 (file)
@@ -55,6 +55,13 @@ unsigned int dcn30_calc_max_scaled_time(
 
 bool dcn30_validate_bandwidth(struct dc *dc, struct dc_state *context,
                bool fast_validate);
+bool dcn30_internal_validate_bw(
+               struct dc *dc,
+               struct dc_state *context,
+               display_e2e_pipe_params_st *pipes,
+               int *pipe_cnt_out,
+               int *vlevel_out,
+               bool fast_validate);
 void dcn30_calculate_wm_and_dlg(
                struct dc *dc, struct dc_state *context,
                display_e2e_pipe_params_st *pipes,
index b60ab3c..7aadb35 100644 (file)
@@ -1664,6 +1664,15 @@ static void dcn31_calculate_wm_and_dlg_fp(
        if (context->bw_ctx.dml.soc.min_dcfclk > dcfclk)
                dcfclk = context->bw_ctx.dml.soc.min_dcfclk;
 
+       /* We don't recalculate clocks for 0 pipe configs, which can block
+        * S0i3 as high clocks will block low power states
+        * Override any clocks that can block S0i3 to min here
+        */
+       if (pipe_cnt == 0) {
+               context->bw_ctx.bw.dcn.clk.dcfclk_khz = dcfclk; // always should be vlevel 0
+               return;
+       }
+
        pipes[0].clks_cfg.voltage = vlevel;
        pipes[0].clks_cfg.dcfclk_mhz = dcfclk;
        pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
@@ -1789,6 +1798,58 @@ static void dcn31_calculate_wm_and_dlg(
        DC_FP_END();
 }
 
+bool dcn31_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();
+
+       out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);
+
+       // Disable fast_validate to set min dcfclk in alculate_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 alidation.\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 dc_cap_funcs cap_funcs = {
        .get_dcc_compression_cap = dcn20_get_dcc_compression_cap
 };
@@ -1871,7 +1932,7 @@ static struct resource_funcs dcn31_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 = dcn30_validate_bandwidth,
+       .validate_bandwidth = dcn31_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 = dcn31_populate_dml_pipes_from_context,