return false;
 }
+
+void resource_init_common_dml2_callbacks(struct dc *dc, struct dml2_configuration_options *dml2_options)
+{
+       dml2_options->callbacks.dc = dc;
+       dml2_options->callbacks.build_scaling_params = &resource_build_scaling_params;
+       dml2_options->callbacks.acquire_secondary_pipe_for_mpc_odm = &dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy;
+       dml2_options->callbacks.update_pipes_for_stream_with_slice_count = &resource_update_pipes_for_stream_with_slice_count;
+       dml2_options->callbacks.update_pipes_for_plane_with_slice_count = &resource_update_pipes_for_plane_with_slice_count;
+       dml2_options->callbacks.get_mpc_slice_index = &resource_get_mpc_slice_index;
+       dml2_options->callbacks.get_odm_slice_index = &resource_get_odm_slice_index;
+       dml2_options->callbacks.get_opp_head = &resource_get_opp_head;
+       dml2_options->callbacks.get_otg_master_for_stream = &resource_get_otg_master_for_stream;
+       dml2_options->callbacks.get_opp_heads_for_otg_master = &resource_get_opp_heads_for_otg_master;
+       dml2_options->callbacks.get_dpp_pipes_for_plane = &resource_get_dpp_pipes_for_plane;
+       dml2_options->callbacks.get_stream_status = &dc_state_get_stream_status;
+       dml2_options->callbacks.get_stream_from_id = &dc_state_get_stream_from_id;
+
+       dml2_options->svp_pstate.callbacks.dc = dc;
+       dml2_options->svp_pstate.callbacks.add_phantom_plane = &dc_state_add_phantom_plane;
+       dml2_options->svp_pstate.callbacks.add_phantom_stream = &dc_state_add_phantom_stream;
+       dml2_options->svp_pstate.callbacks.build_scaling_params = &resource_build_scaling_params;
+       dml2_options->svp_pstate.callbacks.create_phantom_plane = &dc_state_create_phantom_plane;
+       dml2_options->svp_pstate.callbacks.remove_phantom_plane = &dc_state_remove_phantom_plane;
+       dml2_options->svp_pstate.callbacks.remove_phantom_stream = &dc_state_remove_phantom_stream;
+       dml2_options->svp_pstate.callbacks.create_phantom_stream = &dc_state_create_phantom_stream;
+       dml2_options->svp_pstate.callbacks.release_phantom_plane = &dc_state_release_phantom_plane;
+       dml2_options->svp_pstate.callbacks.release_phantom_stream = &dc_state_release_phantom_stream;
+       dml2_options->svp_pstate.callbacks.get_pipe_subvp_type = &dc_state_get_pipe_subvp_type;
+       dml2_options->svp_pstate.callbacks.get_stream_subvp_type = &dc_state_get_stream_subvp_type;
+       dml2_options->svp_pstate.callbacks.get_paired_subvp_stream = &dc_state_get_paired_subvp_stream;
+       dml2_options->svp_pstate.callbacks.remove_phantom_streams_and_planes = &dc_state_remove_phantom_streams_and_planes;
+       dml2_options->svp_pstate.callbacks.release_phantom_streams_and_planes = &dc_state_release_phantom_streams_and_planes;
+}
 
  */
 struct dc_stream_status *dc_state_get_stream_status(
                struct dc_state *state,
-               struct dc_stream_state *stream)
+               const struct dc_stream_state *stream)
 {
        uint8_t i;
 
        for (i = 0; i < state->phantom_plane_count; i++)
                dc_state_release_phantom_plane(dc, state, state->phantom_planes[i]);
 }
+
+struct dc_stream_state *dc_state_get_stream_from_id(const struct dc_state *state, unsigned int id)
+{
+       struct dc_stream_state *stream = NULL;
+       int i;
+
+       for (i = 0; i < state->stream_count; i++) {
+               if (state->streams[i] && state->streams[i]->stream_id == id) {
+                       stream = state->streams[i];
+                       break;
+               }
+       }
+
+       return stream;
+}
 
 
 struct dc_stream_status *dc_state_get_stream_status(
        struct dc_state *state,
-       struct dc_stream_state *stream);
+       const struct dc_stream_state *stream);
 #endif /* _DC_STATE_H_ */
 
 #include "dc_state.h"
 #include "dc_stream.h"
 
+struct dc_stream_state *dc_state_get_stream_from_id(const struct dc_state *state, unsigned int id);
+
 /* Get the type of the provided resource (none, phantom, main) based on the provided
  * context. If the context is unavailable, determine only if phantom or not.
  */
 
        return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA;
 }
 
-
-uint32_t dcn32_helper_mall_bytes_to_ways(
-               struct dc *dc,
-               uint32_t total_size_in_mall_bytes)
-{
-       uint32_t cache_lines_used, lines_per_way, total_cache_lines, num_ways;
-
-       /* add 2 lines for worst case alignment */
-       cache_lines_used = total_size_in_mall_bytes / dc->caps.cache_line_size + 2;
-
-       total_cache_lines = dc->caps.max_cab_allocation_bytes / dc->caps.cache_line_size;
-       lines_per_way = total_cache_lines / dc->caps.cache_num_ways;
-       num_ways = cache_lines_used / lines_per_way;
-       if (cache_lines_used % lines_per_way > 0)
-               num_ways++;
-
-       return num_ways;
-}
-
 uint32_t dcn32_helper_calculate_mall_bytes_for_cursor(
                struct dc *dc,
                struct pipe_ctx *pipe_ctx,
        if (context->bw_ctx.bw.dcn.mall_subvp_size_bytes > 0) {
                if (dc->debug.force_subvp_num_ways) {
                        return dc->debug.force_subvp_num_ways;
+               } else if (dc->res_pool->funcs->calculate_mall_ways_from_bytes) {
+                       return dc->res_pool->funcs->calculate_mall_ways_from_bytes(dc, context->bw_ctx.bw.dcn.mall_subvp_size_bytes);
                } else {
-                       return dcn32_helper_mall_bytes_to_ways(dc, context->bw_ctx.bw.dcn.mall_subvp_size_bytes);
+                       return 0;
                }
        } else {
                return 0;
 
        }
 }
 
-bool dml2_validate(const struct dc *in_dc, struct dc_state *context, bool fast_validate)
+bool dml2_validate(struct dc *in_dc, struct dc_state *context, bool fast_validate)
 {
        bool out = false;
 
 
        int (*get_odm_slice_index)(const struct pipe_ctx *opp_head);
        int (*get_mpc_slice_index)(const struct pipe_ctx *dpp_pipe);
        struct pipe_ctx *(*get_opp_head)(const struct pipe_ctx *pipe_ctx);
+       struct pipe_ctx *(*get_otg_master_for_stream)(
+               struct resource_context *res_ctx,
+               const struct dc_stream_state *stream);
+       int (*get_opp_heads_for_otg_master)(const struct pipe_ctx *otg_master,
+               struct resource_context *res_ctx,
+               struct pipe_ctx *opp_heads[MAX_PIPES]);
+       int (*get_dpp_pipes_for_plane)(const struct dc_plane_state *plane,
+                       struct resource_context *res_ctx,
+                       struct pipe_ctx *dpp_pipes[MAX_PIPES]);
+       struct dc_stream_status *(*get_stream_status)(
+               struct dc_state *state,
+               const struct dc_stream_state *stream);
+       struct dc_stream_state *(*get_stream_from_id)(const struct dc_state *state, unsigned int id);
 };
 
 struct dml2_dc_svp_callbacks {
        enum mall_stream_type (*get_pipe_subvp_type)(const struct dc_state *state, const struct pipe_ctx *pipe_ctx);
        enum mall_stream_type (*get_stream_subvp_type)(const struct dc_state *state, const struct dc_stream_state *stream);
        struct dc_stream_state *(*get_paired_subvp_stream)(const struct dc_state *state, const struct dc_stream_state *stream);
+       bool (*remove_phantom_streams_and_planes)(
+                       struct dc *dc,
+                       struct dc_state *state);
+       void (*release_phantom_streams_and_planes)(
+                       struct dc *dc,
+                       struct dc_state *state);
+       unsigned int (*calculate_mall_ways_from_bytes)(
+                               const struct dc *dc,
+                               unsigned int total_size_in_mall_bytes);
 };
 
 struct dml2_clks_table_entry {
  *          separate dc_states for validation.
  * Return: True if mode is supported, false otherwise.
  */
-bool dml2_validate(const struct dc *in_dc,
+bool dml2_validate(struct dc *in_dc,
                                   struct dc_state *context,
                                   bool fast_validate);
 
 
        // Convert number of cache lines required to number of ways
        if (dc->debug.force_mall_ss_num_ways > 0) {
                num_ways = dc->debug.force_mall_ss_num_ways;
+       } else if (dc->res_pool->funcs->calculate_mall_ways_from_bytes) {
+               num_ways = dc->res_pool->funcs->calculate_mall_ways_from_bytes(dc, mall_ss_size_bytes);
        } else {
-               num_ways = dcn32_helper_mall_bytes_to_ways(dc, mall_ss_size_bytes);
+               num_ways = 0;
        }
 
        return num_ways;
 
        void (*update_soc_for_wm_a)(
                                struct dc *dc, struct dc_state *context);
 
+       unsigned int (*calculate_mall_ways_from_bytes)(
+                               const struct dc *dc,
+                               unsigned int total_size_in_mall_bytes);
        /**
         * @populate_dml_pipes - Populate pipe data struct
         *
 
                struct pipe_ctx *pipe_ctx);
 
 bool check_subvp_sw_cursor_fallback_req(const struct dc *dc, struct dc_stream_state *stream);
+
+/* Setup dc callbacks for dml2
+ * @dc: the display core structure
+ * @dml2_options: struct to hold callbacks
+ */
+void resource_init_common_dml2_callbacks(struct dc *dc, struct dml2_configuration_options *dml2_options);
 #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */
 
        return pipe_cnt;
 }
 
+unsigned int dcn32_calculate_mall_ways_from_bytes(const struct dc *dc, unsigned int total_size_in_mall_bytes)
+{
+       uint32_t cache_lines_used, lines_per_way, total_cache_lines, num_ways;
+
+       /* add 2 lines for worst case alignment */
+       cache_lines_used = total_size_in_mall_bytes / dc->caps.cache_line_size + 2;
+
+       total_cache_lines = dc->caps.max_cab_allocation_bytes / dc->caps.cache_line_size;
+       lines_per_way = total_cache_lines / dc->caps.cache_num_ways;
+       num_ways = cache_lines_used / lines_per_way;
+       if (cache_lines_used % lines_per_way > 0)
+               num_ways++;
+
+       return num_ways;
+}
+
 static struct dc_cap_funcs cap_funcs = {
        .get_dcc_compression_cap = dcn20_get_dcc_compression_cap,
        .get_subvp_en = dcn32_subvp_in_use,
        .update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
        .add_phantom_pipes = dcn32_add_phantom_pipes,
        .build_pipe_pix_clk_params = dcn20_build_pipe_pix_clk_params,
+       .calculate_mall_ways_from_bytes = dcn32_calculate_mall_ways_from_bytes,
 };
 
 static uint32_t read_pipe_fuses(struct dc_context *ctx)
        dc->dml2_options.use_native_soc_bb_construction = true;
        dc->dml2_options.minimize_dispclk_using_odm = true;
 
-       dc->dml2_options.callbacks.dc = dc;
-       dc->dml2_options.callbacks.build_scaling_params = &resource_build_scaling_params;
+       resource_init_common_dml2_callbacks(dc, &dc->dml2_options);
        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.callbacks.acquire_secondary_pipe_for_mpc_odm = &dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy;
-       dc->dml2_options.callbacks.update_pipes_for_stream_with_slice_count = &resource_update_pipes_for_stream_with_slice_count;
-       dc->dml2_options.callbacks.update_pipes_for_plane_with_slice_count = &resource_update_pipes_for_plane_with_slice_count;
-       dc->dml2_options.callbacks.get_mpc_slice_index = &resource_get_mpc_slice_index;
-       dc->dml2_options.callbacks.get_odm_slice_index = &resource_get_odm_slice_index;
-       dc->dml2_options.callbacks.get_opp_head = &resource_get_opp_head;
-
-       dc->dml2_options.svp_pstate.callbacks.dc = dc;
-       dc->dml2_options.svp_pstate.callbacks.add_phantom_plane = &dc_state_add_phantom_plane;
-       dc->dml2_options.svp_pstate.callbacks.add_phantom_stream = &dc_state_add_phantom_stream;
-       dc->dml2_options.svp_pstate.callbacks.build_scaling_params = &resource_build_scaling_params;
-       dc->dml2_options.svp_pstate.callbacks.create_phantom_plane = &dc_state_create_phantom_plane;
-       dc->dml2_options.svp_pstate.callbacks.remove_phantom_plane = &dc_state_remove_phantom_plane;
-       dc->dml2_options.svp_pstate.callbacks.remove_phantom_stream = &dc_state_remove_phantom_stream;
-       dc->dml2_options.svp_pstate.callbacks.create_phantom_stream = &dc_state_create_phantom_stream;
-       dc->dml2_options.svp_pstate.callbacks.release_phantom_plane = &dc_state_release_phantom_plane;
-       dc->dml2_options.svp_pstate.callbacks.release_phantom_stream = &dc_state_release_phantom_stream;
        dc->dml2_options.svp_pstate.callbacks.release_dsc = &dcn20_release_dsc;
-       dc->dml2_options.svp_pstate.callbacks.get_pipe_subvp_type = &dc_state_get_pipe_subvp_type;
-       dc->dml2_options.svp_pstate.callbacks.get_stream_subvp_type = &dc_state_get_stream_subvp_type;
-       dc->dml2_options.svp_pstate.callbacks.get_paired_subvp_stream = &dc_state_get_paired_subvp_stream;
+       dc->dml2_options.svp_pstate.callbacks.calculate_mall_ways_from_bytes = pool->base.funcs->calculate_mall_ways_from_bytes;
 
        dc->dml2_options.svp_pstate.subvp_fw_processing_delay_us = dc->caps.subvp_fw_processing_delay_us;
        dc->dml2_options.svp_pstate.subvp_prefetch_end_to_mall_start_us = dc->caps.subvp_prefetch_end_to_mall_start_us;
 
                int pipe_cnt,
                int vlevel);
 
-uint32_t dcn32_helper_mall_bytes_to_ways(
-               struct dc *dc,
-               uint32_t total_size_in_mall_bytes);
-
 uint32_t dcn32_helper_calculate_mall_bytes_for_cursor(
                struct dc *dc,
                struct pipe_ctx *pipe_ctx,
 
 void dcn32_override_min_req_dcfclk(struct dc *dc, struct dc_state *context);
 
+unsigned int dcn32_calculate_mall_ways_from_bytes(const struct dc *dc, unsigned int total_size_in_mall_bytes);
+
 /* definitions for run time init of reg offsets */
 
 /* CLK SRC */
 
        .update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
        .add_phantom_pipes = dcn32_add_phantom_pipes,
        .build_pipe_pix_clk_params = dcn20_build_pipe_pix_clk_params,
+       .calculate_mall_ways_from_bytes = dcn32_calculate_mall_ways_from_bytes,
 };
 
 static uint32_t read_pipe_fuses(struct dc_context *ctx)
        dc->dml2_options.use_native_soc_bb_construction = true;
        dc->dml2_options.minimize_dispclk_using_odm = true;
 
-       dc->dml2_options.callbacks.dc = dc;
-       dc->dml2_options.callbacks.build_scaling_params = &resource_build_scaling_params;
+       resource_init_common_dml2_callbacks(dc, &dc->dml2_options);
        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.callbacks.acquire_secondary_pipe_for_mpc_odm = &dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy;
-       dc->dml2_options.callbacks.update_pipes_for_stream_with_slice_count = &resource_update_pipes_for_stream_with_slice_count;
-       dc->dml2_options.callbacks.update_pipes_for_plane_with_slice_count = &resource_update_pipes_for_plane_with_slice_count;
-       dc->dml2_options.callbacks.get_mpc_slice_index = &resource_get_mpc_slice_index;
-       dc->dml2_options.callbacks.get_odm_slice_index = &resource_get_odm_slice_index;
-       dc->dml2_options.callbacks.get_opp_head = &resource_get_opp_head;
-
-       dc->dml2_options.svp_pstate.callbacks.dc = dc;
-       dc->dml2_options.svp_pstate.callbacks.add_phantom_plane = &dc_state_add_phantom_plane;
-       dc->dml2_options.svp_pstate.callbacks.add_phantom_stream = &dc_state_add_phantom_stream;
-       dc->dml2_options.svp_pstate.callbacks.build_scaling_params = &resource_build_scaling_params;
-       dc->dml2_options.svp_pstate.callbacks.create_phantom_plane = &dc_state_create_phantom_plane;
-       dc->dml2_options.svp_pstate.callbacks.remove_phantom_plane = &dc_state_remove_phantom_plane;
-       dc->dml2_options.svp_pstate.callbacks.remove_phantom_stream = &dc_state_remove_phantom_stream;
-       dc->dml2_options.svp_pstate.callbacks.create_phantom_stream = &dc_state_create_phantom_stream;
-       dc->dml2_options.svp_pstate.callbacks.release_phantom_plane = &dc_state_release_phantom_plane;
-       dc->dml2_options.svp_pstate.callbacks.release_phantom_stream = &dc_state_release_phantom_stream;
        dc->dml2_options.svp_pstate.callbacks.release_dsc = &dcn20_release_dsc;
-       dc->dml2_options.svp_pstate.callbacks.get_pipe_subvp_type = &dc_state_get_pipe_subvp_type;
-       dc->dml2_options.svp_pstate.callbacks.get_stream_subvp_type = &dc_state_get_stream_subvp_type;
-       dc->dml2_options.svp_pstate.callbacks.get_paired_subvp_stream = &dc_state_get_paired_subvp_stream;
+       dc->dml2_options.svp_pstate.callbacks.calculate_mall_ways_from_bytes = pool->base.funcs->calculate_mall_ways_from_bytes;
 
        dc->dml2_options.svp_pstate.subvp_fw_processing_delay_us = dc->caps.subvp_fw_processing_delay_us;
        dc->dml2_options.svp_pstate.subvp_prefetch_end_to_mall_start_us = dc->caps.subvp_prefetch_end_to_mall_start_us;
 
                dc->dml2_options.minimize_dispclk_using_odm = true;
        dc->dml2_options.enable_windowed_mpo_odm = dc->config.enable_windowed_mpo_odm;
 
-       dc->dml2_options.callbacks.dc = dc;
-       dc->dml2_options.callbacks.build_scaling_params = &resource_build_scaling_params;
+       resource_init_common_dml2_callbacks(dc, &dc->dml2_options);
        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.callbacks.acquire_secondary_pipe_for_mpc_odm = &dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy;
-       dc->dml2_options.callbacks.update_pipes_for_stream_with_slice_count = &resource_update_pipes_for_stream_with_slice_count;
-       dc->dml2_options.callbacks.update_pipes_for_plane_with_slice_count = &resource_update_pipes_for_plane_with_slice_count;
-       dc->dml2_options.callbacks.get_mpc_slice_index = &resource_get_mpc_slice_index;
-       dc->dml2_options.callbacks.get_odm_slice_index = &resource_get_odm_slice_index;
-       dc->dml2_options.callbacks.get_opp_head = &resource_get_opp_head;
+
        dc->dml2_options.max_segments_per_hubp = 24;
 
        dc->dml2_options.det_segment_size = DCN3_2_DET_SEG_SIZE;/*todo*/
 
                dc->dml2_options.minimize_dispclk_using_odm = true;
        dc->dml2_options.enable_windowed_mpo_odm = dc->config.enable_windowed_mpo_odm;
 
-       dc->dml2_options.callbacks.dc = dc;
-       dc->dml2_options.callbacks.build_scaling_params = &resource_build_scaling_params;
+       resource_init_common_dml2_callbacks(dc, &dc->dml2_options);
        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.callbacks.acquire_secondary_pipe_for_mpc_odm = &dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy;
-       dc->dml2_options.callbacks.update_pipes_for_stream_with_slice_count = &resource_update_pipes_for_stream_with_slice_count;
-       dc->dml2_options.callbacks.update_pipes_for_plane_with_slice_count = &resource_update_pipes_for_plane_with_slice_count;
-       dc->dml2_options.callbacks.get_mpc_slice_index = &resource_get_mpc_slice_index;
-       dc->dml2_options.callbacks.get_odm_slice_index = &resource_get_odm_slice_index;
-       dc->dml2_options.callbacks.get_opp_head = &resource_get_opp_head;
+
        dc->dml2_options.max_segments_per_hubp = 24;
        dc->dml2_options.det_segment_size = DCN3_2_DET_SEG_SIZE;/*todo*/