Skip to content

Commit 0a9906c

Browse files
Josip Pavicalexdeucher
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 <[email protected]> Reviewed-by: Aric Cyr <[email protected]> Signed-off-by: Josip Pavic <[email protected]> Signed-off-by: Rodrigo Siqueira <[email protected]> Tested-by: Daniel Wheeler <[email protected]> Signed-off-by: Alex Deucher <[email protected]> (cherry picked from commit 7671f62) Cc: [email protected]
1 parent d6b9f49 commit 0a9906c

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

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5065,11 +5065,26 @@ static bool update_planes_and_stream_v3(struct dc *dc,
50655065
return true;
50665066
}
50675067

5068+
static void clear_update_flags(struct dc_surface_update *srf_updates,
5069+
int surface_count, struct dc_stream_state *stream)
5070+
{
5071+
int i;
5072+
5073+
if (stream)
5074+
stream->update_flags.raw = 0;
5075+
5076+
for (i = 0; i < surface_count; i++)
5077+
if (srf_updates[i].surface)
5078+
srf_updates[i].surface->update_flags.raw = 0;
5079+
}
5080+
50685081
bool dc_update_planes_and_stream(struct dc *dc,
50695082
struct dc_surface_update *srf_updates, int surface_count,
50705083
struct dc_stream_state *stream,
50715084
struct dc_stream_update *stream_update)
50725085
{
5086+
bool ret = false;
5087+
50735088
dc_exit_ips_for_hw_access(dc);
50745089
/*
50755090
* update planes and stream version 3 separates FULL and FAST updates
@@ -5086,10 +5101,16 @@ bool dc_update_planes_and_stream(struct dc *dc,
50865101
* features as they are now transparent to the new sequence.
50875102
*/
50885103
if (dc->ctx->dce_version >= DCN_VERSION_4_01)
5089-
return update_planes_and_stream_v3(dc, srf_updates,
5104+
ret = update_planes_and_stream_v3(dc, srf_updates,
50905105
surface_count, stream, stream_update);
5091-
return update_planes_and_stream_v2(dc, srf_updates,
5106+
else
5107+
ret = update_planes_and_stream_v2(dc, srf_updates,
50925108
surface_count, stream, stream_update);
5109+
5110+
if (ret)
5111+
clear_update_flags(srf_updates, surface_count, stream);
5112+
5113+
return ret;
50935114
}
50945115

50955116
void dc_commit_updates_for_stream(struct dc *dc,
@@ -5099,24 +5120,26 @@ void dc_commit_updates_for_stream(struct dc *dc,
50995120
struct dc_stream_update *stream_update,
51005121
struct dc_state *state)
51015122
{
5123+
bool ret = false;
5124+
51025125
dc_exit_ips_for_hw_access(dc);
51035126
/* TODO: Since change commit sequence can have a huge impact,
51045127
* we decided to only enable it for DCN3x. However, as soon as
51055128
* we get more confident about this change we'll need to enable
51065129
* the new sequence for all ASICs.
51075130
*/
51085131
if (dc->ctx->dce_version >= DCN_VERSION_4_01) {
5109-
update_planes_and_stream_v3(dc, srf_updates, surface_count,
5132+
ret = update_planes_and_stream_v3(dc, srf_updates, surface_count,
51105133
stream, stream_update);
5111-
return;
5112-
}
5113-
if (dc->ctx->dce_version >= DCN_VERSION_3_2) {
5114-
update_planes_and_stream_v2(dc, srf_updates, surface_count,
5134+
} else if (dc->ctx->dce_version >= DCN_VERSION_3_2) {
5135+
ret = update_planes_and_stream_v2(dc, srf_updates, surface_count,
51155136
stream, stream_update);
5116-
return;
5117-
}
5118-
update_planes_and_stream_v1(dc, srf_updates, surface_count, stream,
5119-
stream_update, state);
5137+
} else
5138+
ret = update_planes_and_stream_v1(dc, srf_updates, surface_count, stream,
5139+
stream_update, state);
5140+
5141+
if (ret)
5142+
clear_update_flags(srf_updates, surface_count, stream);
51205143
}
51215144

51225145
uint8_t dc_get_current_stream_count(struct dc *dc)

0 commit comments

Comments
 (0)