Skip to content

Commit 87b7ebc

Browse files
Rodrigo Siqueiraalexdeucher
authored andcommitted
drm/amd/display: Fix green screen issue after suspend
[why] We have seen a green screen after resume from suspend in a Raven system connected with two displays (HDMI and DP) on X based system. We noticed that this issue is related to bad DCC metadata from user space which may generate hangs and consequently an underflow on HUBP. After taking a deep look at the code path we realized that after resume we try to restore the commit with the DCC enabled framebuffer but the framebuffer is no longer valid. [how] This problem was only reported on Raven based system and after suspend, for this reason, this commit adds a new parameter on fill_plane_dcc_attributes() to give the option of disabling DCC programmatically. In summary, for disabling DCC we first verify if is a Raven system and if it is in suspend; if both conditions are true we disable DCC temporarily, otherwise, it is enabled. Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1099 Co-developed-by: Nicholas Kazlauskas <[email protected]> Signed-off-by: Nicholas Kazlauskas <[email protected]> Signed-off-by: Rodrigo Siqueira <[email protected]> Reviewed-by: Nicholas Kazlauskas <[email protected]> Acked-by: Rodrigo Siqueira <[email protected]> Signed-off-by: Alex Deucher <[email protected]> Cc: [email protected]
1 parent 718a556 commit 87b7ebc

File tree

1 file changed

+29
-9
lines changed

1 file changed

+29
-9
lines changed

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3340,7 +3340,8 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
33403340
const union dc_tiling_info *tiling_info,
33413341
const uint64_t info,
33423342
struct dc_plane_dcc_param *dcc,
3343-
struct dc_plane_address *address)
3343+
struct dc_plane_address *address,
3344+
bool force_disable_dcc)
33443345
{
33453346
struct dc *dc = adev->dm.dc;
33463347
struct dc_dcc_surface_param input;
@@ -3352,6 +3353,9 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
33523353
memset(&input, 0, sizeof(input));
33533354
memset(&output, 0, sizeof(output));
33543355

3356+
if (force_disable_dcc)
3357+
return 0;
3358+
33553359
if (!offset)
33563360
return 0;
33573361

@@ -3401,7 +3405,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
34013405
union dc_tiling_info *tiling_info,
34023406
struct plane_size *plane_size,
34033407
struct dc_plane_dcc_param *dcc,
3404-
struct dc_plane_address *address)
3408+
struct dc_plane_address *address,
3409+
bool force_disable_dcc)
34053410
{
34063411
const struct drm_framebuffer *fb = &afb->base;
34073412
int ret;
@@ -3507,7 +3512,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
35073512

35083513
ret = fill_plane_dcc_attributes(adev, afb, format, rotation,
35093514
plane_size, tiling_info,
3510-
tiling_flags, dcc, address);
3515+
tiling_flags, dcc, address,
3516+
force_disable_dcc);
35113517
if (ret)
35123518
return ret;
35133519
}
@@ -3599,7 +3605,8 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
35993605
const struct drm_plane_state *plane_state,
36003606
const uint64_t tiling_flags,
36013607
struct dc_plane_info *plane_info,
3602-
struct dc_plane_address *address)
3608+
struct dc_plane_address *address,
3609+
bool force_disable_dcc)
36033610
{
36043611
const struct drm_framebuffer *fb = plane_state->fb;
36053612
const struct amdgpu_framebuffer *afb =
@@ -3681,7 +3688,8 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
36813688
plane_info->rotation, tiling_flags,
36823689
&plane_info->tiling_info,
36833690
&plane_info->plane_size,
3684-
&plane_info->dcc, address);
3691+
&plane_info->dcc, address,
3692+
force_disable_dcc);
36853693
if (ret)
36863694
return ret;
36873695

@@ -3704,6 +3712,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
37043712
struct dc_plane_info plane_info;
37053713
uint64_t tiling_flags;
37063714
int ret;
3715+
bool force_disable_dcc = false;
37073716

37083717
ret = fill_dc_scaling_info(plane_state, &scaling_info);
37093718
if (ret)
@@ -3718,9 +3727,11 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
37183727
if (ret)
37193728
return ret;
37203729

3730+
force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend;
37213731
ret = fill_dc_plane_info_and_addr(adev, plane_state, tiling_flags,
37223732
&plane_info,
3723-
&dc_plane_state->address);
3733+
&dc_plane_state->address,
3734+
force_disable_dcc);
37243735
if (ret)
37253736
return ret;
37263737

@@ -5342,6 +5353,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
53425353
uint64_t tiling_flags;
53435354
uint32_t domain;
53445355
int r;
5356+
bool force_disable_dcc = false;
53455357

53465358
dm_plane_state_old = to_dm_plane_state(plane->state);
53475359
dm_plane_state_new = to_dm_plane_state(new_state);
@@ -5400,11 +5412,13 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
54005412
dm_plane_state_old->dc_state != dm_plane_state_new->dc_state) {
54015413
struct dc_plane_state *plane_state = dm_plane_state_new->dc_state;
54025414

5415+
force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend;
54035416
fill_plane_buffer_attributes(
54045417
adev, afb, plane_state->format, plane_state->rotation,
54055418
tiling_flags, &plane_state->tiling_info,
54065419
&plane_state->plane_size, &plane_state->dcc,
5407-
&plane_state->address);
5420+
&plane_state->address,
5421+
force_disable_dcc);
54085422
}
54095423

54105424
return 0;
@@ -6676,7 +6690,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
66766690
fill_dc_plane_info_and_addr(
66776691
dm->adev, new_plane_state, tiling_flags,
66786692
&bundle->plane_infos[planes_count],
6679-
&bundle->flip_addrs[planes_count].address);
6693+
&bundle->flip_addrs[planes_count].address,
6694+
false);
6695+
6696+
DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n",
6697+
new_plane_state->plane->index,
6698+
bundle->plane_infos[planes_count].dcc.enable);
66806699

66816700
bundle->surface_updates[planes_count].plane_info =
66826701
&bundle->plane_infos[planes_count];
@@ -8096,7 +8115,8 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm,
80968115
ret = fill_dc_plane_info_and_addr(
80978116
dm->adev, new_plane_state, tiling_flags,
80988117
plane_info,
8099-
&flip_addr->address);
8118+
&flip_addr->address,
8119+
false);
81008120
if (ret)
81018121
goto cleanup;
81028122

0 commit comments

Comments
 (0)