if (otg_master && otg_master->stream->test_pattern.type != DP_TEST_PATTERN_VIDEO_MODE)
                                resource_build_test_pattern_params(&context->res_ctx, otg_master);
+
+                       if (otg_master && (otg_master->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422 ||
+                                       otg_master->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420))
+                               resource_build_subsampling_params(&context->res_ctx, otg_master);
                }
        }
 
 
                        stream->timing.v_border_bottom +
                        stream->timing.v_border_top;
 
+       /* Recout for ODM slices after the first slice need one extra left edge pixel
+        * for 3-tap chroma subsampling.
+        */
+       if (odm_slice_idx > 0 &&
+                       (pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422 ||
+                               pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)) {
+               odm_rec.x -= 1;
+               odm_rec.width += 1;
+       }
+
        return odm_rec;
 }
 
        enum controller_dp_test_pattern controller_test_pattern;
        enum controller_dp_color_space controller_color_space;
        enum dc_color_depth color_depth = otg_master->stream->timing.display_color_depth;
+       enum dc_pixel_encoding pixel_encoding = otg_master->stream->timing.pixel_encoding;
        int h_active = otg_master->stream->timing.h_addressable +
                otg_master->stream->timing.h_border_left +
                otg_master->stream->timing.h_border_right;
                else
                        params->width = last_odm_slice_width;
 
+               /* Extra left edge pixel is required for 3-tap chroma subsampling. */
+               if (i != 0 && (pixel_encoding == PIXEL_ENCODING_YCBCR422 ||
+                               pixel_encoding == PIXEL_ENCODING_YCBCR420)) {
+                       params->offset -= 1;
+                       params->width += 1;
+               }
+
                offset += odm_slice_width;
        }
 }
 
+void resource_build_subsampling_params(struct resource_context *res_ctx,
+       struct pipe_ctx *otg_master)
+{
+       struct pipe_ctx *opp_heads[MAX_PIPES];
+       int odm_cnt = 1;
+       int i;
+
+       odm_cnt = resource_get_opp_heads_for_otg_master(otg_master, res_ctx, opp_heads);
+
+       /* For ODM slices after the first slice, extra left edge pixel is required
+        * for 3-tap chroma subsampling.
+        */
+       if (otg_master->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422 ||
+                       otg_master->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) {
+               for (i = 0; i < odm_cnt; i++)
+                       opp_heads[i]->stream_res.left_edge_extra_pixel = (i == 0) ? false : true;
+       }
+}
+
 bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
 {
        const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
 
        if (old_pipe->stream_res.tg != new_pipe->stream_res.tg)
                new_pipe->update_flags.bits.tg_changed = 1;
 
+       if (resource_is_pipe_type(new_pipe, OPP_HEAD)) {
+               if (old_pipe->stream_res.left_edge_extra_pixel != new_pipe->stream_res.left_edge_extra_pixel)
+                       new_pipe->update_flags.bits.opp_changed = 1;
+       }
+
        /*
         * Detect mpcc blending changes, only dpp inst and opp matter here,
         * mpccs getting removed/inserted update connected ones during their own
                        pipe_ctx->stream_res.opp,
                        &pipe_ctx->stream->bit_depth_params,
                        &pipe_ctx->stream->clamping);
+
+               if (resource_is_pipe_type(pipe_ctx, OPP_HEAD))
+                       pipe_ctx->stream_res.opp->funcs->opp_program_left_edge_extra_pixel(
+                               pipe_ctx->stream_res.opp,
+                               pipe_ctx->stream_res.left_edge_extra_pixel);
        }
 
        /* Set ABM pipe after other pipe configurations done */
 
                struct resource_context *res_ctx,
                struct pipe_ctx *pipe_ctx);
 
+void resource_build_subsampling_params(
+               struct resource_context *res_ctx,
+               struct pipe_ctx *pipe_ctx);
+
 bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx);
 
 enum dc_status resource_build_scaling_params_for_context(