--- /dev/null
+From 3a9626c816db901def438dc2513622e281186d39 Mon Sep 17 00:00:00 2001
+From: Mario Limonciello <mario.limonciello@amd.com>
+Date: Wed, 7 Feb 2024 23:52:55 -0600
+Subject: drm/amd: Stop evicting resources on APUs in suspend
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+commit 3a9626c816db901def438dc2513622e281186d39 upstream.
+
+commit 5095d5418193 ("drm/amd: Evict resources during PM ops prepare()
+callback") intentionally moved the eviction of resources to earlier in
+the suspend process, but this introduced a subtle change that it occurs
+before adev->in_s0ix or adev->in_s3 are set. This meant that APUs
+actually started to evict resources at suspend time as well.
+
+Explicitly set s0ix or s3 in the prepare() stage, and unset them if the
+prepare() stage failed.
+
+v2: squash in warning fix from Stephen Rothwell
+
+Reported-by: Jürg Billeter <j@bitron.ch>
+Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3132#note_2271038
+Fixes: 5095d5418193 ("drm/amd: Evict resources during PM ops prepare() callback")
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 ++
+ drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 15 +++++++++++++++
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 11 +++++++++--
+ 3 files changed, 26 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -1509,9 +1509,11 @@ static inline int amdgpu_acpi_smart_shif
+ #if defined(CONFIG_ACPI) && defined(CONFIG_SUSPEND)
+ bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev);
+ bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev);
++void amdgpu_choose_low_power_state(struct amdgpu_device *adev);
+ #else
+ static inline bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) { return false; }
+ static inline bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev) { return false; }
++static inline void amdgpu_choose_low_power_state(struct amdgpu_device *adev) { }
+ #endif
+
+ #if defined(CONFIG_DRM_AMD_DC)
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+@@ -1519,4 +1519,19 @@ bool amdgpu_acpi_is_s0ix_active(struct a
+ #endif /* CONFIG_AMD_PMC */
+ }
+
++/**
++ * amdgpu_choose_low_power_state
++ *
++ * @adev: amdgpu_device_pointer
++ *
++ * Choose the target low power state for the GPU
++ */
++void amdgpu_choose_low_power_state(struct amdgpu_device *adev)
++{
++ if (amdgpu_acpi_is_s0ix_active(adev))
++ adev->in_s0ix = true;
++ else if (amdgpu_acpi_is_s3_active(adev))
++ adev->in_s3 = true;
++}
++
+ #endif /* CONFIG_SUSPEND */
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -4441,13 +4441,15 @@ int amdgpu_device_prepare(struct drm_dev
+ struct amdgpu_device *adev = drm_to_adev(dev);
+ int i, r;
+
++ amdgpu_choose_low_power_state(adev);
++
+ if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+ return 0;
+
+ /* Evict the majority of BOs before starting suspend sequence */
+ r = amdgpu_device_evict_resources(adev);
+ if (r)
+- return r;
++ goto unprepare;
+
+ for (i = 0; i < adev->num_ip_blocks; i++) {
+ if (!adev->ip_blocks[i].status.valid)
+@@ -4456,10 +4458,15 @@ int amdgpu_device_prepare(struct drm_dev
+ continue;
+ r = adev->ip_blocks[i].version->funcs->prepare_suspend((void *)adev);
+ if (r)
+- return r;
++ goto unprepare;
+ }
+
+ return 0;
++
++unprepare:
++ adev->in_s0ix = adev->in_s3 = false;
++
++ return r;
+ }
+
+ /**