aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3015-drm-amd-display-move-bw-calc-code-into-helpers.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3015-drm-amd-display-move-bw-calc-code-into-helpers.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3015-drm-amd-display-move-bw-calc-code-into-helpers.patch396
1 files changed, 396 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3015-drm-amd-display-move-bw-calc-code-into-helpers.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3015-drm-amd-display-move-bw-calc-code-into-helpers.patch
new file mode 100644
index 00000000..21bf0756
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3015-drm-amd-display-move-bw-calc-code-into-helpers.patch
@@ -0,0 +1,396 @@
+From 4662aa48edacb59942d375fc920b296a26878bff Mon Sep 17 00:00:00 2001
+From: Eric Yang <Eric.Yang2@amd.com>
+Date: Wed, 22 May 2019 14:24:40 -0400
+Subject: [PATCH 3015/4256] drm/amd/display: move bw calc code into helpers
+
+[Why]
+For better readability and reusability
+
+[How]
+Move snippets of BW calculation code into helpers.
+
+Signed-off-by: Eric Yang <Eric.Yang2@amd.com>
+Reviewed-by: Fatemeh Darbehani <Fatemeh.Darbehani@amd.com>
+Acked-by: Leo Li <sunpeng.li@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 +
+ .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c | 2 -
+ .../drm/amd/display/dc/dcn20/dcn20_resource.c | 250 +++++++++++-------
+ .../drm/amd/display/dc/dcn20/dcn20_resource.h | 11 +
+ .../amd/display/dc/inc/hw/clk_mgr_internal.h | 2 +
+ 5 files changed, 167 insertions(+), 99 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index 429794becdcd..aa007e9958a0 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -128,6 +128,7 @@ static DEVICE_ATTR(pcie_replay_count, S_IRUGO,
+ amdgpu_device_get_pcie_replay_count, NULL);
+
+ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev);
++static void amdgpu_device_parse_faked_did(struct amdgpu_device *adev);
+
+ /**
+ * amdgpu_device_is_px - Is the device is a dGPU with HG/PX power control
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
+index 740f5db22bb5..614a941eb9f2 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
+@@ -26,8 +26,6 @@
+ #include "dccg.h"
+ #include "clk_mgr_internal.h"
+
+-
+-#include "dcn20/dcn20_clk_mgr.h"
+ #include "dce100/dce_clk_mgr.h"
+ #include "reg_helper.h"
+ #include "core_types.h"
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+index 20cf98f090b0..842f48403226 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+@@ -2016,15 +2016,16 @@ static bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx)
+ }
+ #endif
+
+-bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
+- bool fast_validate)
++bool dcn20_fast_validate_bw(
++ struct dc *dc,
++ struct dc_state *context,
++ display_e2e_pipe_params_st *pipes,
++ int *pipe_split_from,
++ int *vlevel_out)
+ {
+ bool out = false;
+
+- BW_VAL_TRACE_SETUP();
+-
+ int pipe_cnt, i, pipe_idx, vlevel, vlevel_unsplit;
+- int pipe_split_from[MAX_PIPES];
+ bool odm_capable = context->bw_ctx.dml.ip.odm_capable;
+ bool force_split = false;
+ #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+@@ -2032,10 +2033,7 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
+ #endif
+ int split_threshold = dc->res_pool->pipe_count / 2;
+ bool avoid_split = dc->debug.pipe_split_policy != MPC_SPLIT_DYNAMIC;
+- 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();
+
+ ASSERT(pipes);
+ if (!pipes)
+@@ -2075,7 +2073,6 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
+ &context->res_ctx, pipes);
+
+ if (!pipe_cnt) {
+- BW_VAL_TRACE_SKIP(pass);
+ out = true;
+ goto validate_out;
+ }
+@@ -2240,101 +2237,128 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
+ }
+ #endif
+
+- BW_VAL_TRACE_END_VOLTAGE_LEVEL();
++ *vlevel_out = vlevel;
+
+- if (fast_validate) {
+- BW_VAL_TRACE_SKIP(fast);
+- out = true;
+- goto validate_out;
+- }
++ out = true;
++ goto validate_out;
++
++validate_fail:
++ out = false;
++
++validate_out:
++ return out;
++}
++
++void dcn20_calculate_wm(
++ struct dc *dc, struct dc_state *context,
++ display_e2e_pipe_params_st *pipes,
++ int *out_pipe_cnt,
++ int *pipe_split_from,
++ int vlevel)
++{
++ int pipe_cnt, i, pipe_idx;
+
+ for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
+- if (!context->res_ctx.pipe_ctx[i].stream)
+- continue;
++ if (!context->res_ctx.pipe_ctx[i].stream)
++ continue;
+
+- pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
+- pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
++ pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
++ pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
+
+- if (pipe_split_from[i] < 0) {
+- pipes[pipe_cnt].clks_cfg.dppclk_mhz =
+- context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
+- if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
+- pipes[pipe_cnt].pipe.dest.odm_combine =
+- context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx];
+- else
+- pipes[pipe_cnt].pipe.dest.odm_combine = 0;
+- pipe_idx++;
+- } else {
+- pipes[pipe_cnt].clks_cfg.dppclk_mhz =
+- context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
+- if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
+- pipes[pipe_cnt].pipe.dest.odm_combine =
+- context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_split_from[i]];
++ if (pipe_split_from[i] < 0) {
++ pipes[pipe_cnt].clks_cfg.dppclk_mhz =
++ context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
++ if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
++ pipes[pipe_cnt].pipe.dest.odm_combine =
++ context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx];
++ else
++ pipes[pipe_cnt].pipe.dest.odm_combine = 0;
++ pipe_idx++;
++ } else {
++ pipes[pipe_cnt].clks_cfg.dppclk_mhz =
++ context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
++ if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
++ pipes[pipe_cnt].pipe.dest.odm_combine =
++ context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_split_from[i]];
++ else
++ pipes[pipe_cnt].pipe.dest.odm_combine = 0;
++ }
++
++ if (dc->config.forced_clocks) {
++ pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
++ pipes[pipe_cnt].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
++ }
++
++ pipe_cnt++;
++ }
++
++ if (pipe_cnt != pipe_idx) {
++ if (dc->res_pool->funcs->populate_dml_pipes)
++ pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
++ &context->res_ctx, pipes);
+ else
+- pipes[pipe_cnt].pipe.dest.odm_combine = 0;
++ pipe_cnt = dcn20_populate_dml_pipes_from_context(dc,
++ &context->res_ctx, pipes);
+ }
+- if (dc->config.forced_clocks) {
+- pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
+- pipes[pipe_cnt].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
++
++ *out_pipe_cnt = pipe_cnt;
++
++ pipes[0].clks_cfg.voltage = vlevel;
++ pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
++ pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
++
++ /* only pipe 0 is read for voltage and dcf/soc clocks */
++ if (vlevel < 1) {
++ pipes[0].clks_cfg.voltage = 1;
++ pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].dcfclk_mhz;
++ pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].socclk_mhz;
+ }
+- pipe_cnt++;
+- }
++ context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++ context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++ context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++ context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++ context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++
++ if (vlevel < 2) {
++ pipes[0].clks_cfg.voltage = 2;
++ pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
++ pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;
++ }
++ context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++ context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++ context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++ context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++ context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++
++ if (vlevel < 3) {
++ pipes[0].clks_cfg.voltage = 3;
++ pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
++ pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;
++ }
++ context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++ context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++ context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++ context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++ context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++
++ pipes[0].clks_cfg.voltage = vlevel;
++ pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
++ pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
++ context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++ context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++ context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++ context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++ context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
++}
++
++void dcn20_calculate_dlg_params(
++ struct dc *dc, struct dc_state *context,
++ display_e2e_pipe_params_st *pipes,
++ int pipe_cnt,
++ int vlevel)
++{
++ int i, pipe_idx;
+
+- if (pipe_cnt != pipe_idx) {
+- if (dc->res_pool->funcs->populate_dml_pipes)
+- pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
+- &context->res_ctx, pipes);
+- else
+- pipe_cnt = dcn20_populate_dml_pipes_from_context(dc,
+- &context->res_ctx, pipes);
+- }
+-
+- pipes[0].clks_cfg.voltage = vlevel;
+- pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
+- pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
+-
+- /* only pipe 0 is read for voltage and dcf/soc clocks */
+- if (vlevel < 1) {
+- pipes[0].clks_cfg.voltage = 1;
+- pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].dcfclk_mhz;
+- pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].socclk_mhz;
+- }
+- context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+- context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+- context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+- context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+- context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+-
+- if (vlevel < 2) {
+- pipes[0].clks_cfg.voltage = 2;
+- pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
+- pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;
+- }
+- context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+- context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+- context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+- context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+- context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+-
+- if (vlevel < 3) {
+- pipes[0].clks_cfg.voltage = 3;
+- pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
+- pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;
+- }
+- context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+- context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+- context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+- context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+- context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+-
+- pipes[0].clks_cfg.voltage = vlevel;
+- pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
+- pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
+- context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+- context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+- context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+- context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+- context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+ /* Writeback MCIF_WB arbitration parameters */
+ dc->res_pool->funcs->set_mcif_arb_params(dc, context, pipes, pipe_cnt);
+
+@@ -2349,7 +2373,7 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
+ != dm_dram_clock_change_unsupported;
+ context->bw_ctx.bw.dcn.clk.dppclk_khz = 0;
+
+- BW_VAL_TRACE_END_WATERMARKS();
++
+
+ for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
+ if (!context->res_ctx.pipe_ctx[i].stream)
+@@ -2391,8 +2415,40 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
+ pipes[pipe_idx].pipe);
+ pipe_idx++;
+ }
++}
++
++bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
++ bool fast_validate)
++{
++ bool out = false;
++
++ BW_VAL_TRACE_SETUP();
++
++ int vlevel = 0;
++ int pipe_split_from[MAX_PIPES];
++ 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 = dcn20_fast_validate_bw(dc, context, pipes, pipe_split_from, &vlevel);
++
++ if (!out)
++ goto validate_fail;
++
++ BW_VAL_TRACE_END_VOLTAGE_LEVEL();
++
++ if (fast_validate) {
++ BW_VAL_TRACE_SKIP(fast);
++ goto validate_out;
++ }
++
++ dcn20_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel);
++ dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
++
++ BW_VAL_TRACE_END_WATERMARKS();
+
+- out = true;
+ goto validate_out;
+
+ validate_fail:
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
+index b5a75289f444..2b3692e0c48d 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
+@@ -116,6 +116,17 @@ void dcn20_set_mcif_arb_params(
+ display_e2e_pipe_params_st *pipes,
+ int pipe_cnt);
+ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, bool fast_validate);
++bool dcn20_fast_validate_bw(
++ struct dc *dc,
++ struct dc_state *context,
++ display_e2e_pipe_params_st *pipes,
++ int *pipe_split_from,
++ int *vlevel_out);
++void dcn20_calculate_dlg_params(
++ struct dc *dc, struct dc_state *context,
++ display_e2e_pipe_params_st *pipes,
++ int pipe_cnt,
++ int vlevel);
+
+ enum dc_status dcn20_build_mapped_resource(const struct dc *dc, struct dc_state *context, struct dc_stream_state *stream);
+ enum dc_status dcn20_add_stream_to_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream);
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
+index 0835ac041acf..3c105124dcdd 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
+@@ -64,6 +64,8 @@ enum dentist_divider_range {
+ ***************************************************************************************
+ */
+
++/* Macros */
++
+ #define TO_CLK_MGR_INTERNAL(clk_mgr)\
+ container_of(clk_mgr, struct clk_mgr_internal, base)
+
+--
+2.17.1
+