Skip to content

Commit 5842abd

Browse files
Wesley Chalmersalexdeucher
authored andcommitted
drm/amd/display: Use the largest vready_offset in pipe group
[WHY] Corruption can occur in LB if vready_offset is not large enough. DML calculates vready_offset for each pipe, but we currently select the top pipe's vready_offset, which is not necessarily enough for all pipes in the group. [HOW] Wherever program_global_sync is currently called, iterate through the entire pipe group and find the highest vready_offset. Reviewed-by: Dillon Varone <[email protected]> Acked-by: Jasdeep Dhillon <[email protected]> Signed-off-by: Wesley Chalmers <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 725a521 commit 5842abd

File tree

2 files changed

+55
-4
lines changed

2 files changed

+55
-4
lines changed

drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,32 @@ static void false_optc_underflow_wa(
869869
tg->funcs->clear_optc_underflow(tg);
870870
}
871871

872+
static int calculate_vready_offset_for_group(struct pipe_ctx *pipe)
873+
{
874+
struct pipe_ctx *other_pipe;
875+
int vready_offset = pipe->pipe_dlg_param.vready_offset;
876+
877+
/* Always use the largest vready_offset of all connected pipes */
878+
for (other_pipe = pipe->bottom_pipe; other_pipe != NULL; other_pipe = other_pipe->bottom_pipe) {
879+
if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
880+
vready_offset = other_pipe->pipe_dlg_param.vready_offset;
881+
}
882+
for (other_pipe = pipe->top_pipe; other_pipe != NULL; other_pipe = other_pipe->top_pipe) {
883+
if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
884+
vready_offset = other_pipe->pipe_dlg_param.vready_offset;
885+
}
886+
for (other_pipe = pipe->next_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->next_odm_pipe) {
887+
if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
888+
vready_offset = other_pipe->pipe_dlg_param.vready_offset;
889+
}
890+
for (other_pipe = pipe->prev_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->prev_odm_pipe) {
891+
if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
892+
vready_offset = other_pipe->pipe_dlg_param.vready_offset;
893+
}
894+
895+
return vready_offset;
896+
}
897+
872898
enum dc_status dcn10_enable_stream_timing(
873899
struct pipe_ctx *pipe_ctx,
874900
struct dc_state *context,
@@ -912,7 +938,7 @@ enum dc_status dcn10_enable_stream_timing(
912938
pipe_ctx->stream_res.tg->funcs->program_timing(
913939
pipe_ctx->stream_res.tg,
914940
&stream->timing,
915-
pipe_ctx->pipe_dlg_param.vready_offset,
941+
calculate_vready_offset_for_group(pipe_ctx),
916942
pipe_ctx->pipe_dlg_param.vstartup_start,
917943
pipe_ctx->pipe_dlg_param.vupdate_offset,
918944
pipe_ctx->pipe_dlg_param.vupdate_width,
@@ -2908,7 +2934,7 @@ void dcn10_program_pipe(
29082934

29092935
pipe_ctx->stream_res.tg->funcs->program_global_sync(
29102936
pipe_ctx->stream_res.tg,
2911-
pipe_ctx->pipe_dlg_param.vready_offset,
2937+
calculate_vready_offset_for_group(pipe_ctx),
29122938
pipe_ctx->pipe_dlg_param.vstartup_start,
29132939
pipe_ctx->pipe_dlg_param.vupdate_offset,
29142940
pipe_ctx->pipe_dlg_param.vupdate_width);

drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1652,6 +1652,31 @@ static void dcn20_update_dchubp_dpp(
16521652
hubp->funcs->phantom_hubp_post_enable(hubp);
16531653
}
16541654

1655+
static int calculate_vready_offset_for_group(struct pipe_ctx *pipe)
1656+
{
1657+
struct pipe_ctx *other_pipe;
1658+
int vready_offset = pipe->pipe_dlg_param.vready_offset;
1659+
1660+
/* Always use the largest vready_offset of all connected pipes */
1661+
for (other_pipe = pipe->bottom_pipe; other_pipe != NULL; other_pipe = other_pipe->bottom_pipe) {
1662+
if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
1663+
vready_offset = other_pipe->pipe_dlg_param.vready_offset;
1664+
}
1665+
for (other_pipe = pipe->top_pipe; other_pipe != NULL; other_pipe = other_pipe->top_pipe) {
1666+
if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
1667+
vready_offset = other_pipe->pipe_dlg_param.vready_offset;
1668+
}
1669+
for (other_pipe = pipe->next_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->next_odm_pipe) {
1670+
if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
1671+
vready_offset = other_pipe->pipe_dlg_param.vready_offset;
1672+
}
1673+
for (other_pipe = pipe->prev_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->prev_odm_pipe) {
1674+
if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
1675+
vready_offset = other_pipe->pipe_dlg_param.vready_offset;
1676+
}
1677+
1678+
return vready_offset;
1679+
}
16551680

16561681
static void dcn20_program_pipe(
16571682
struct dc *dc,
@@ -1670,7 +1695,7 @@ static void dcn20_program_pipe(
16701695
&& !pipe_ctx->prev_odm_pipe) {
16711696
pipe_ctx->stream_res.tg->funcs->program_global_sync(
16721697
pipe_ctx->stream_res.tg,
1673-
pipe_ctx->pipe_dlg_param.vready_offset,
1698+
calculate_vready_offset_for_group(pipe_ctx),
16741699
pipe_ctx->pipe_dlg_param.vstartup_start,
16751700
pipe_ctx->pipe_dlg_param.vupdate_offset,
16761701
pipe_ctx->pipe_dlg_param.vupdate_width);
@@ -2067,7 +2092,7 @@ bool dcn20_update_bandwidth(
20672092

20682093
pipe_ctx->stream_res.tg->funcs->program_global_sync(
20692094
pipe_ctx->stream_res.tg,
2070-
pipe_ctx->pipe_dlg_param.vready_offset,
2095+
calculate_vready_offset_for_group(pipe_ctx),
20712096
pipe_ctx->pipe_dlg_param.vstartup_start,
20722097
pipe_ctx->pipe_dlg_param.vupdate_offset,
20732098
pipe_ctx->pipe_dlg_param.vupdate_width);

0 commit comments

Comments
 (0)