[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.

Co-developed-by: Nicholas Kazlauskas <nicholas.kazlaus...@amd.com>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlaus...@amd.com>
Signed-off-by: Rodrigo Siqueira <rodrigo.sique...@amd.com>
Reviewed-by: Nicholas Kazlauskas <nicholas.kazlaus...@amd.com>
Acked-by: Rodrigo Siqueira <rodrigo.sique...@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 38 ++++++++++++++-----
 1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 209b9bf8bf11..04098b344ca3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3421,7 +3421,8 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
                          const union dc_tiling_info *tiling_info,
                          const uint64_t info,
                          struct dc_plane_dcc_param *dcc,
-                         struct dc_plane_address *address)
+                         struct dc_plane_address *address,
+                         bool force_disable_dcc)
 {
        struct dc *dc = adev->dm.dc;
        struct dc_dcc_surface_param input;
@@ -3433,6 +3434,9 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
        memset(&input, 0, sizeof(input));
        memset(&output, 0, sizeof(output));
 
+       if (force_disable_dcc)
+               return 0;
+
        if (!offset)
                return 0;
 
@@ -3483,7 +3487,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
                             struct plane_size *plane_size,
                             struct dc_plane_dcc_param *dcc,
                             struct dc_plane_address *address,
-                            bool tmz_surface)
+                            bool tmz_surface,
+                            bool force_disable_dcc)
 {
        const struct drm_framebuffer *fb = &afb->base;
        int ret;
@@ -3591,7 +3596,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
 
                ret = fill_plane_dcc_attributes(adev, afb, format, rotation,
                                                plane_size, tiling_info,
-                                               tiling_flags, dcc, address);
+                                               tiling_flags, dcc, address,
+                                               force_disable_dcc);
                if (ret)
                        return ret;
        }
@@ -3684,7 +3690,8 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
                            const uint64_t tiling_flags,
                            struct dc_plane_info *plane_info,
                            struct dc_plane_address *address,
-                           bool tmz_surface)
+                           bool tmz_surface,
+                           bool force_disable_dcc)
 {
        const struct drm_framebuffer *fb = plane_state->fb;
        const struct amdgpu_framebuffer *afb =
@@ -3766,7 +3773,8 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
                                           plane_info->rotation, tiling_flags,
                                           &plane_info->tiling_info,
                                           &plane_info->plane_size,
-                                          &plane_info->dcc, address, 
tmz_surface);
+                                          &plane_info->dcc, address,
+                                          tmz_surface, force_disable_dcc);
        if (ret)
                return ret;
 
@@ -3790,6 +3798,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device 
*adev,
        uint64_t tiling_flags;
        int ret;
        bool tmz_surface = false;
+       bool force_disable_dcc = false;
 
        ret = fill_dc_scaling_info(plane_state, &scaling_info);
        if (ret)
@@ -3804,10 +3813,12 @@ static int fill_dc_plane_attributes(struct 
amdgpu_device *adev,
        if (ret)
                return ret;
 
+       force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend;
        ret = fill_dc_plane_info_and_addr(adev, plane_state, tiling_flags,
                                          &plane_info,
                                          &dc_plane_state->address,
-                                         tmz_surface);
+                                         tmz_surface,
+                                         force_disable_dcc);
        if (ret)
                return ret;
 
@@ -5429,6 +5440,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
        uint32_t domain;
        int r;
        bool tmz_surface = false;
+       bool force_disable_dcc = false;
 
        dm_plane_state_old = to_dm_plane_state(plane->state);
        dm_plane_state_new = to_dm_plane_state(new_state);
@@ -5489,11 +5501,13 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
                        dm_plane_state_old->dc_state != 
dm_plane_state_new->dc_state) {
                struct dc_plane_state *plane_state = 
dm_plane_state_new->dc_state;
 
+               force_disable_dcc = adev->asic_type == CHIP_RAVEN && 
adev->in_suspend;
                fill_plane_buffer_attributes(
                        adev, afb, plane_state->format, plane_state->rotation,
                        tiling_flags, &plane_state->tiling_info,
                        &plane_state->plane_size, &plane_state->dcc,
-                       &plane_state->address, tmz_surface);
+                       &plane_state->address, tmz_surface,
+                       force_disable_dcc);
        }
 
        return 0;
@@ -6773,7 +6787,12 @@ static void amdgpu_dm_commit_planes(struct 
drm_atomic_state *state,
                fill_dc_plane_info_and_addr(
                        dm->adev, new_plane_state, tiling_flags,
                        &bundle->plane_infos[planes_count],
-                       &bundle->flip_addrs[planes_count].address, tmz_surface);
+                       &bundle->flip_addrs[planes_count].address, tmz_surface,
+                       false);
+
+               DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n",
+                                new_plane_state->plane->index,
+                                bundle->plane_infos[planes_count].dcc.enable);
 
                bundle->surface_updates[planes_count].plane_info =
                        &bundle->plane_infos[planes_count];
@@ -8196,7 +8215,8 @@ dm_determine_update_type_for_commit(struct 
amdgpu_display_manager *dm,
                                ret = fill_dc_plane_info_and_addr(
                                        dm->adev, new_plane_state, tiling_flags,
                                        plane_info,
-                                       &flip_addr->address, tmz_surface);
+                                       &flip_addr->address, tmz_surface,
+                                       false);
                                if (ret)
                                        goto cleanup;
 
-- 
2.26.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to