From cce1652c62c42c858de64c306ea0ddc7af3bd0b1 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 18 Jul 2025 18:40:26 -0400 Subject: [PATCH] drm/amd/display: refine framebuffer placement checks When we commit planes, we need to make sure the framebuffer memory locations are compatible. Various hardware has the following requirements for display buffers: dGPUs, old APUs, raven1 - must be in VRAM cazziro/stoney - must be in VRAM or GTT, but not both newer APUs (raven2/picasso and newer) - can be in VRAM or GTT You should always get a compatible memory buffer due to amdgpu_bo_get_preferred_domain(). amdgpu_display_supported_domains() will ensure you always get VRAM or GTT or VRAM | GTT depending on what the chip supports. Then amdgpu_bo_get_preferred_domain() will either leave that as is when pinning, or force VRAM or GTT for the STONEY/CARRIZO case. As such the checks could probably be removed, but on the off chance we do end up getting different memory pool for the old and new framebuffers, refine the check to take into account the hardware capabilities. Fixes: a7c0cad0dc06 ("drm/amd/display: ensure async flips are only accepted for fast updates") Reported-by: Brian Geffon Cc: Leo Li Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 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 129476b6d5fa9..de2bd789ec15b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -9288,6 +9288,18 @@ static void amdgpu_dm_enable_self_refresh(struct amdgpu_crtc *acrtc_attach, } } +static bool amdgpu_dm_mem_type_compatible(struct amdgpu_device *adev, + struct drm_framebuffer *old_fb, + struct drm_framebuffer *new_fb) +{ + if (!adev->mode_info.gpu_vm_support || + (adev->asic_type == CHIP_CARRIZO) || + (adev->asic_type == CHIP_STONEY)) + return get_mem_type(old_fb) == get_mem_type(new_fb); + + return true; +} + static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, struct drm_device *dev, struct amdgpu_display_manager *dm, @@ -9465,7 +9477,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, */ if (crtc->state->async_flip && (acrtc_state->update_type != UPDATE_TYPE_FAST || - get_mem_type(old_plane_state->fb) != get_mem_type(fb))) + !amdgpu_dm_mem_type_compatible(dm->adev, old_plane_state->fb, fb))) drm_warn_once(state->dev, "[PLANE:%d:%s] async flip with non-fast update\n", plane->base.id, plane->name); @@ -9473,7 +9485,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, bundle->flip_addrs[planes_count].flip_immediate = crtc->state->async_flip && acrtc_state->update_type == UPDATE_TYPE_FAST && - get_mem_type(old_plane_state->fb) == get_mem_type(fb); + amdgpu_dm_mem_type_compatible(dm->adev, old_plane_state->fb, fb); timestamp_ns = ktime_get_ns(); bundle->flip_addrs[planes_count].flip_timestamp_in_us = div_u64(timestamp_ns, 1000); @@ -11760,6 +11772,7 @@ static bool amdgpu_dm_crtc_mem_type_changed(struct drm_device *dev, struct drm_atomic_state *state, struct drm_crtc_state *crtc_state) { + struct amdgpu_device *adev = drm_to_adev(dev); struct drm_plane *plane; struct drm_plane_state *new_plane_state, *old_plane_state; @@ -11773,7 +11786,8 @@ static bool amdgpu_dm_crtc_mem_type_changed(struct drm_device *dev, } if (old_plane_state->fb && new_plane_state->fb && - get_mem_type(old_plane_state->fb) != get_mem_type(new_plane_state->fb)) + !amdgpu_dm_mem_type_compatible(adev, old_plane_state->fb, + new_plane_state->fb)) return true; } -- 2.50.1