}
 #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
 #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)
                        &context->res_ctx, pipes);
 
        if (!pipe_cnt) {
-               BW_VAL_TRACE_SKIP(pass);
                out = true;
                goto validate_out;
        }
        }
 #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);
 
                                                        != 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)
                                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: