BREAK_TO_DEBUGGER();
                        goto fail;
                }
-
-               for (i = 0; i < context->stream_count; i++) {
-                       struct pipe_ctx *otg_master = resource_get_otg_master_for_stream(&context->res_ctx,
-                                       context->streams[i]);
-
-                       if (otg_master && otg_master->stream->test_pattern.type != DP_TEST_PATTERN_VIDEO_MODE)
-                               resource_build_test_pattern_params(&context->res_ctx, otg_master);
-               }
        }
        update_seamless_boot_flags(dc, context, surface_count, stream);
 
                        }
 
                        if (stream_update->pending_test_pattern) {
-                               dc_link_dp_set_test_pattern(stream->link,
+                               /*
+                                * test pattern params depends on ODM topology
+                                * changes that we could be applying to front
+                                * end. Since at the current stage front end
+                                * changes are not yet applied. We can only
+                                * apply test pattern in hw based on current
+                                * state and populate the final test pattern
+                                * params in new state. If current and new test
+                                * pattern params are different as result of
+                                * different ODM topology being used, it will be
+                                * detected and handle during front end
+                                * programming update.
+                                */
+                               dc->link_srv->dp_set_test_pattern(stream->link,
                                        stream->test_pattern.type,
                                        stream->test_pattern.color_space,
                                        stream->test_pattern.p_link_settings,
                                        stream->test_pattern.p_custom_pattern,
                                        stream->test_pattern.cust_pattern_size);
+                               resource_build_test_pattern_params(&context->res_ctx, pipe_ctx);
                        }
 
                        if (stream_update->dpms_off) {
 
        controller_color_space = convert_dp_to_controller_color_space(
                        otg_master->stream->test_pattern.color_space);
 
+       if (controller_test_pattern == CONTROLLER_DP_TEST_PATTERN_VIDEOMODE)
+               return;
+
        odm_cnt = resource_get_opp_heads_for_otg_master(otg_master, res_ctx, opp_heads);
 
        odm_slice_width = h_active / odm_cnt;
 
        if (pool->funcs->build_pipe_pix_clk_params)
                pool->funcs->build_pipe_pix_clk_params(otg_master);
+
+       if (otg_master->stream->test_pattern.type != DP_TEST_PATTERN_VIDEO_MODE)
+               resource_build_test_pattern_params(&context->res_ctx, otg_master);
        return result;
 }
 
 {
        dml2_options->callbacks.dc = dc;
        dml2_options->callbacks.build_scaling_params = &resource_build_scaling_params;
+       dml2_options->callbacks.build_test_pattern_params = &resource_build_test_pattern_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;
 
                                        return false;
                        }
                }
+
+               for (i = 0; i < context->stream_count; i++) {
+                       struct pipe_ctx *otg_master = resource_get_otg_master_for_stream(&context->res_ctx,
+                                       context->streams[i]);
+
+                       if (otg_master && otg_master->stream->test_pattern.type != DP_TEST_PATTERN_VIDEO_MODE)
+                               resource_build_test_pattern_params(&context->res_ctx, otg_master);
+               }
        }
        return true;
 }
 
                                ASSERT(false);
                        }
                }
+
+               if (ctx->config.callbacks.build_test_pattern_params &&
+                               pipe->stream &&
+                               pipe->prev_odm_pipe == NULL &&
+                               pipe->top_pipe == NULL)
+                       ctx->config.callbacks.build_test_pattern_params(&state->res_ctx, pipe);
        }
 
        return true;
 
 struct dml2_dc_callbacks {
        struct dc *dc;
        bool (*build_scaling_params)(struct pipe_ctx *pipe_ctx);
+       void (*build_test_pattern_params)(struct resource_context *res_ctx, struct pipe_ctx *otg_master);
        bool (*can_support_mclk_switch_using_fw_based_vblank_stretch)(struct dc *dc, struct dc_state *context);
        bool (*acquire_secondary_pipe_for_mpc_odm)(const struct dc *dc, struct dc_state *state, struct pipe_ctx *pri_pipe, struct pipe_ctx *sec_pipe, bool odm);
        bool (*update_pipes_for_stream_with_slice_count)(