summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
diff options
context:
space:
mode:
authorGeorge Shen <george.shen@amd.com>2024-01-05 22:01:03 -0500
committerAlex Deucher <alexander.deucher@amd.com>2024-02-07 12:26:22 -0500
commit288c0254a0b0c9980dba9df7d5afadf27280b99c (patch)
tree1d701e170ee392307183f2444d4f7e8a386aef42 /drivers/gpu/drm/amd/display/dc/core/dc_resource.c
parentead4c6b94d9b9d9801fd73220cbb032cb7908ac9 (diff)
drm/amd/display: Add left edge pixel for YCbCr422/420 + ODM pipe split
[Why] Currently 3-tap chroma subsampling is used for YCbCr422/420. When ODM pipesplit is used, pixels on the left edge of ODM slices need one extra pixel from the right edge of the previous slice to calculate the correct chroma value. Without this change, the chroma value is slightly different than expected. This is usually imperceptible visually, but it impacts test pattern CRCs for compliance test automation. [How] Update logic to use the register for adding extra left edge pixel for YCbCr422/420 ODM cases. Reviewed-by: Alvin Lee <alvin.lee2@amd.com> Acked-by: Hamza Mahfooz <hamza.mahfooz@amd.com> Signed-off-by: George Shen <george.shen@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/core/dc_resource.c')
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_resource.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 259ccbe858b4..528d3eb245ea 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -822,6 +822,16 @@ static struct rect calculate_odm_slice_in_timing_active(struct pipe_ctx *pipe_ct
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;
}
@@ -1438,6 +1448,7 @@ void resource_build_test_pattern_params(struct resource_context *res_ctx,
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;
@@ -1469,10 +1480,36 @@ void resource_build_test_pattern_params(struct resource_context *res_ctx,
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;