Takashi Iwai 319dae
From 08da182175db4c7f80850354849d95f2670e8cd9 Mon Sep 17 00:00:00 2001
Takashi Iwai 319dae
From: Hamza Mahfooz <hamza.mahfooz@amd.com>
Takashi Iwai 319dae
Date: Fri, 14 Apr 2023 14:26:27 -0400
Takashi Iwai 319dae
Subject: [PATCH] drm/amd/display: fix flickering caused by S/G mode
Takashi Iwai 319dae
Git-commit: 08da182175db4c7f80850354849d95f2670e8cd9
Takashi Iwai 319dae
Patch-mainline: v6.4-rc1
Takashi Iwai 319dae
References: git-fixes
Takashi Iwai 319dae
Takashi Iwai 319dae
Currently, on a handful of ASICs. We allow the framebuffer for a given
Takashi Iwai 319dae
plane to exist in either VRAM or GTT. However, if the plane's new
Takashi Iwai 319dae
framebuffer is in a different memory domain than it's previous
Takashi Iwai 319dae
framebuffer, flipping between them can cause the screen to flicker. So,
Takashi Iwai 319dae
to fix this, don't perform an immediate flip in the aforementioned case.
Takashi Iwai 319dae
Takashi Iwai 319dae
Cc: stable@vger.kernel.org
Takashi Iwai 319dae
Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2354
Takashi Iwai 319dae
Reviewed-by: Roman Li <Roman.Li@amd.com>
Takashi Iwai 319dae
Fixes: 81d0bcf99009 ("drm/amdgpu: make display pinning more flexible (v2)")
Takashi Iwai 319dae
Signed-off-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
Takashi Iwai 319dae
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Takashi Iwai 319dae
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai 319dae
Takashi Iwai 319dae
---
Takashi Iwai 319dae
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   13 +++++++++++--
Takashi Iwai 319dae
 1 file changed, 11 insertions(+), 2 deletions(-)
Takashi Iwai 319dae
Takashi Iwai 319dae
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
Takashi Iwai 319dae
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
Takashi Iwai 319dae
@@ -8589,6 +8589,13 @@ static void amdgpu_dm_commit_cursors(str
Takashi Iwai 319dae
 			handle_cursor_update(plane, old_plane_state);
Takashi Iwai 319dae
 }
Takashi Iwai 319dae
 
Takashi Iwai 319dae
+static inline uint32_t get_mem_type(struct drm_framebuffer *fb)
Takashi Iwai 319dae
+{
Takashi Iwai 319dae
+	struct amdgpu_bo *abo = gem_to_amdgpu_bo(fb->obj[0]);
Takashi Iwai 319dae
+
Takashi Iwai 319dae
+	return abo->tbo.resource ? abo->tbo.resource->mem_type : 0;
Takashi Iwai 319dae
+}
Takashi Iwai 319dae
+
Takashi Iwai 319dae
 static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
Takashi Iwai 319dae
 				    struct dc_state *dc_state,
Takashi Iwai 319dae
 				    struct drm_device *dev,
Takashi Iwai 319dae
@@ -8709,11 +8716,13 @@ static void amdgpu_dm_commit_planes(stru
Takashi Iwai 319dae
 
Takashi Iwai 319dae
 		/*
Takashi Iwai 319dae
 		 * Only allow immediate flips for fast updates that don't
Takashi Iwai 319dae
-		 * change FB pitch, DCC state, rotation or mirroing.
Takashi Iwai 319dae
+		 * change memory domain, FB pitch, DCC state, rotation or
Takashi Iwai 319dae
+		 * mirroring.
Takashi Iwai 319dae
 		 */
Takashi Iwai 319dae
 		bundle->flip_addrs[planes_count].flip_immediate =
Takashi Iwai 319dae
 			crtc->state->async_flip &&
Takashi Iwai 319dae
-			acrtc_state->update_type == UPDATE_TYPE_FAST;
Takashi Iwai 319dae
+			acrtc_state->update_type == UPDATE_TYPE_FAST &&
Takashi Iwai 319dae
+			get_mem_type(old_plane_state->fb) == get_mem_type(fb);
Takashi Iwai 319dae
 
Takashi Iwai 319dae
 		timestamp_ns = ktime_get_ns();
Takashi Iwai 319dae
 		bundle->flip_addrs[planes_count].flip_timestamp_in_us = div_u64(timestamp_ns, 1000);