Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: Only use offset for first ODM pipe

[WHY]
Only the first pipe in ODM combine group should have nonzero recout
offset. All other pipes should have recout offset 0;
otherwise there will be gaps in the image.

[HOW]
Set recout.x to 0 if the pipe is not the leftmost ODM pipe.

When computing viewports, calculate the horizontal offset of a pipe's src
based on the current pipe's position in the ODM group, plus whatever offset the
leftmost ODM pipe has; otherwise there will be discontinuity in the image.

Since ODM combine can only combine pipes horizontally, nothing needs to
be done for recout.y.

Signed-off-by: Wesley Chalmers <Wesley.Chalmers@amd.com>
Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Wesley Chalmers and committed by
Alex Deucher
05e3d830 3fb068c3

+19 -10
+19 -10
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
··· 782 782 783 783 calculate_split_count_and_index(pipe_ctx, &split_count, &split_idx); 784 784 785 - data->recout.x = stream->dst.x; 785 + /* 786 + * Only the leftmost ODM pipe should be offset by a nonzero distance 787 + */ 788 + if (!pipe_ctx->prev_odm_pipe) 789 + data->recout.x = stream->dst.x; 790 + else 791 + data->recout.x = 0; 786 792 if (stream->src.x < surf_clip.x) 787 793 data->recout.x += (surf_clip.x - stream->src.x) * stream->dst.width 788 794 / stream->src.width; ··· 963 957 { 964 958 const struct dc_plane_state *plane_state = pipe_ctx->plane_state; 965 959 const struct dc_stream_state *stream = pipe_ctx->stream; 966 - struct pipe_ctx *odm_pipe = pipe_ctx->prev_odm_pipe; 960 + struct pipe_ctx *odm_pipe = pipe_ctx; 967 961 struct scaler_data *data = &pipe_ctx->plane_res.scl_data; 968 962 struct rect src = pipe_ctx->plane_state->src_rect; 969 963 int recout_skip_h, recout_skip_v, surf_size_h, surf_size_v; ··· 994 988 swap(src.width, src.height); 995 989 } 996 990 991 + /*modified recout_skip_h calculation due to odm having no recout offset*/ 992 + while (odm_pipe->prev_odm_pipe) { 993 + odm_idx++; 994 + odm_pipe = odm_pipe->prev_odm_pipe; 995 + } 996 + /*odm_pipe is the leftmost pipe in the ODM group*/ 997 + recout_skip_h = odm_idx * data->recout.width; 998 + 997 999 /* Recout matching initial vp offset = recout_offset - (stream dst offset + 998 1000 * ((surf dst offset - stream src offset) * 1/ stream scaling ratio) 999 1001 * - (surf surf_src offset * 1/ full scl ratio)) 1000 1002 */ 1001 - recout_skip_h = data->recout.x - (stream->dst.x + (plane_state->dst_rect.x - stream->src.x) 1003 + recout_skip_h += odm_pipe->plane_res.scl_data.recout.x 1004 + - (stream->dst.x + (plane_state->dst_rect.x - stream->src.x) 1002 1005 * stream->dst.width / stream->src.width - 1003 1006 src.x * plane_state->dst_rect.width / src.width 1004 1007 * stream->dst.width / stream->src.width); 1005 - /*modified recout_skip_h calculation due to odm having no recout offset*/ 1006 - while (odm_pipe) { 1007 - odm_idx++; 1008 - odm_pipe = odm_pipe->prev_odm_pipe; 1009 - } 1010 - if (odm_idx) 1011 - recout_skip_h += odm_idx * data->recout.width; 1008 + 1012 1009 1013 1010 recout_skip_v = data->recout.y - (stream->dst.y + (plane_state->dst_rect.y - stream->src.y) 1014 1011 * stream->dst.height / stream->src.height -