* to acquire an idle one to satisfy the request
         */
 
-       if (!pool->funcs->acquire_idle_pipe_for_layer)
-               return NULL;
+       if (!pool->funcs->acquire_idle_pipe_for_layer) {
+               if (!pool->funcs->acquire_idle_pipe_for_head_pipe_in_layer)
+                       return NULL;
+               else
+                       return pool->funcs->acquire_idle_pipe_for_head_pipe_in_layer(context, pool, head_pipe->stream, head_pipe);
+       }
 
        return pool->funcs->acquire_idle_pipe_for_layer(context, pool, head_pipe->stream);
 }
        struct resource_pool *pool = dc->res_pool;
        struct pipe_ctx *head_pipe, *tail_pipe, *free_pipe;
        struct dc_stream_status *stream_status = NULL;
+       struct pipe_ctx *prev_right_head = NULL;
+       struct pipe_ctx *free_right_pipe = NULL;
 
        DC_LOGGER_INIT(stream->ctx->logger);
        for (i = 0; i < context->stream_count; i++)
                                                free_pipe->pipe_idx,
                                                tail_pipe->next_odm_pipe ? tail_pipe->next_odm_pipe->pipe_idx : -1);
 
+                               /*
+                                * We want to avoid the case where the right side already has a pipe assigned to
+                                *  it and is different from free_pipe ( which would cause trigger a pipe
+                                *  reallocation ).
+                                * Check the old context to see if the right side already has a pipe allocated
+                                * - If not, continue to use free_pipe
+                                * - If the right side already has a pipe, use that pipe instead if its available
+                                */
+                               prev_right_head = &dc->current_state->res_ctx.pipe_ctx[tail_pipe->next_odm_pipe->pipe_idx];
+                               if ((prev_right_head->bottom_pipe) && (free_pipe->pipe_idx != prev_right_head->bottom_pipe->pipe_idx)) {
+                                       free_right_pipe = acquire_free_pipe_for_head(context, pool, tail_pipe->next_odm_pipe);
+                                       if (free_right_pipe) {
+                                               free_pipe->stream = NULL;
+                                               memset(&free_pipe->stream_res, 0, sizeof(struct stream_resource));
+                                               memset(&free_pipe->plane_res, 0, sizeof(struct plane_resource));
+                                               free_pipe->plane_state = NULL;
+                                               free_pipe->pipe_idx = 0;
+                                               free_right_pipe->plane_state = plane_state;
+                                               free_pipe = free_right_pipe;
+                                       }
+                               }
+
                                free_pipe->stream_res.tg = tail_pipe->next_odm_pipe->stream_res.tg;
                                free_pipe->stream_res.abm = tail_pipe->next_odm_pipe->stream_res.abm;
                                free_pipe->stream_res.opp = tail_pipe->next_odm_pipe->stream_res.opp;
 
                struct dc *dc,
                struct dc_state *context);
 
+       /*
+        * Acquires a free pipe for the head pipe.
+        * The head pipe is first pipe in the current context that matches the stream
+        *  and does not have a top pipe or prev_odm_pipe.
+        */
        struct pipe_ctx *(*acquire_idle_pipe_for_layer)(
                        struct dc_state *context,
                        const struct resource_pool *pool,
                        struct dc_stream_state *stream);
 
+       /*
+        * Acquires a free pipe for the head pipe with some additional checks for odm.
+        * The head pipe is passed in as an argument unlike acquire_idle_pipe_for_layer
+        *  where it is read from the context.  So this allows us look for different
+        *  idle_pipe if the head_pipes are different ( ex. in odm 2:1 when we have
+        *  a left and right pipe ).
+        *
+        * It also checks the old context to see if:
+        *
+        * 1. a pipe has already been allocated for the head pipe.  If so, it will
+        *  try to select that pipe as the idle pipe if it is available in the current
+        *  context.
+        * 2. if the head_pipe is on the left, it will check if the right pipe has
+        *  a pipe already allocated.  If so, it will not use that pipe if it is
+        *  selected as the idle pipe.
+        */
+       struct pipe_ctx *(*acquire_idle_pipe_for_head_pipe_in_layer)(
+                       struct dc_state *context,
+                       const struct resource_pool *pool,
+                       struct dc_stream_state *stream,
+                       struct pipe_ctx *head_pipe);
+
        enum dc_status (*validate_plane)(const struct dc_plane_state *plane_state, struct dc_caps *caps);
 
        enum dc_status (*add_stream_to_ctx)(