Skip to content

Commit 7671f62

Browse files
Josip Pavicalexdeucher
Josip Pavic
authored andcommitted
drm/amd/display: Clear update flags after update has been applied
[Why] Since the surface/stream update flags aren't cleared after applying updates, those same updates may be applied again in a future call to update surfaces/streams for surfaces/streams that aren't actually part of that update (i.e. applying an update for one surface/stream can trigger unintended programming on a different surface/stream). For example, when an update results in a call to program_front_end_for_ctx, that function may call program_pipe on all pipes. If there are surface update flags that were never cleared on the surface some pipe is attached to, then the same update will be programmed again. [How] Clear the surface and stream update flags after applying the updates. Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3441 Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3616 Cc: Melissa Wen <mwen@igalia.com> Reviewed-by: Aric Cyr <aric.cyr@amd.com> Signed-off-by: Josip Pavic <Josip.Pavic@amd.com> Signed-off-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
1 parent de08e41 commit 7671f62

File tree

1 file changed

+34
-11
lines changed
  • drivers/gpu/drm/amd/display/dc/core

1 file changed

+34
-11
lines changed

drivers/gpu/drm/amd/display/dc/core/dc.c

+34-11
Original file line numberDiff line numberDiff line change
@@ -5129,11 +5129,26 @@ static bool update_planes_and_stream_v3(struct dc *dc,
51295129
return true;
51305130
}
51315131

5132+
static void clear_update_flags(struct dc_surface_update *srf_updates,
5133+
int surface_count, struct dc_stream_state *stream)
5134+
{
5135+
int i;
5136+
5137+
if (stream)
5138+
stream->update_flags.raw = 0;
5139+
5140+
for (i = 0; i < surface_count; i++)
5141+
if (srf_updates[i].surface)
5142+
srf_updates[i].surface->update_flags.raw = 0;
5143+
}
5144+
51325145
bool dc_update_planes_and_stream(struct dc *dc,
51335146
struct dc_surface_update *srf_updates, int surface_count,
51345147
struct dc_stream_state *stream,
51355148
struct dc_stream_update *stream_update)
51365149
{
5150+
bool ret = false;
5151+
51375152
dc_exit_ips_for_hw_access(dc);
51385153
/*
51395154
* update planes and stream version 3 separates FULL and FAST updates
@@ -5150,10 +5165,16 @@ bool dc_update_planes_and_stream(struct dc *dc,
51505165
* features as they are now transparent to the new sequence.
51515166
*/
51525167
if (dc->ctx->dce_version >= DCN_VERSION_4_01)
5153-
return update_planes_and_stream_v3(dc, srf_updates,
5168+
ret = update_planes_and_stream_v3(dc, srf_updates,
51545169
surface_count, stream, stream_update);
5155-
return update_planes_and_stream_v2(dc, srf_updates,
5170+
else
5171+
ret = update_planes_and_stream_v2(dc, srf_updates,
51565172
surface_count, stream, stream_update);
5173+
5174+
if (ret)
5175+
clear_update_flags(srf_updates, surface_count, stream);
5176+
5177+
return ret;
51575178
}
51585179

51595180
void dc_commit_updates_for_stream(struct dc *dc,
@@ -5163,24 +5184,26 @@ void dc_commit_updates_for_stream(struct dc *dc,
51635184
struct dc_stream_update *stream_update,
51645185
struct dc_state *state)
51655186
{
5187+
bool ret = false;
5188+
51665189
dc_exit_ips_for_hw_access(dc);
51675190
/* TODO: Since change commit sequence can have a huge impact,
51685191
* we decided to only enable it for DCN3x. However, as soon as
51695192
* we get more confident about this change we'll need to enable
51705193
* the new sequence for all ASICs.
51715194
*/
51725195
if (dc->ctx->dce_version >= DCN_VERSION_4_01) {
5173-
update_planes_and_stream_v3(dc, srf_updates, surface_count,
5196+
ret = update_planes_and_stream_v3(dc, srf_updates, surface_count,
51745197
stream, stream_update);
5175-
return;
5176-
}
5177-
if (dc->ctx->dce_version >= DCN_VERSION_3_2) {
5178-
update_planes_and_stream_v2(dc, srf_updates, surface_count,
5198+
} else if (dc->ctx->dce_version >= DCN_VERSION_3_2) {
5199+
ret = update_planes_and_stream_v2(dc, srf_updates, surface_count,
51795200
stream, stream_update);
5180-
return;
5181-
}
5182-
update_planes_and_stream_v1(dc, srf_updates, surface_count, stream,
5183-
stream_update, state);
5201+
} else
5202+
ret = update_planes_and_stream_v1(dc, srf_updates, surface_count, stream,
5203+
stream_update, state);
5204+
5205+
if (ret)
5206+
clear_update_flags(srf_updates, surface_count, stream);
51845207
}
51855208

51865209
uint8_t dc_get_current_stream_count(struct dc *dc)

0 commit comments

Comments
 (0)