summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2024-04-11 03:24:41 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2024-04-11 03:24:41 +0000
commit730872c08fdfd890da6c8f739d7f64c0b10c8512 (patch)
tree966982f4ac7a1aa983f0bdeea7cb3f81d7ea4379 /sys
parent3e808cee43d47efd614a6d09a405028f53cecb45 (diff)
drm/amd: Evict resources during PM ops prepare() callback
From Mario Limonciello 8b5f720486ca87e102ee722a73ae0894c12f1e7a in linux-6.6.y/6.6.26 5095d5418193eb2748c7d8553c7150b8f1c44696 in mainline linux
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/drm/amd/amdgpu/amdgpu.h1
-rw-r--r--sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c31
-rw-r--r--sys/dev/pci/drm/amd/amdgpu/amdgpu_drv.c11
3 files changed, 35 insertions, 8 deletions
diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu.h b/sys/dev/pci/drm/amd/amdgpu/amdgpu.h
index afac024456e..38a424f16fb 100644
--- a/sys/dev/pci/drm/amd/amdgpu/amdgpu.h
+++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu.h
@@ -1398,6 +1398,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
void amdgpu_driver_release_kms(struct drm_device *dev);
int amdgpu_device_ip_suspend(struct amdgpu_device *adev);
+int amdgpu_device_prepare(struct drm_device *dev);
int amdgpu_device_suspend(struct drm_device *dev, bool fbcon);
int amdgpu_device_resume(struct drm_device *dev, bool fbcon);
u32 amdgpu_get_vblank_counter_kms(struct drm_crtc *crtc);
diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c
index 7901aeb4dfd..3029753b497 100644
--- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c
+++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c
@@ -1568,6 +1568,7 @@ static void amdgpu_switcheroo_set_state(struct pci_dev *pdev,
} else {
pr_info("switched off\n");
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
+ amdgpu_device_prepare(dev);
amdgpu_device_suspend(dev, true);
amdgpu_device_cache_pci_state(pdev);
/* Shut down the device */
@@ -4206,6 +4207,31 @@ static int amdgpu_device_evict_resources(struct amdgpu_device *adev)
* Suspend & resume.
*/
/**
+ * amdgpu_device_prepare - prepare for device suspend
+ *
+ * @dev: drm dev pointer
+ *
+ * Prepare to put the hw in the suspend state (all asics).
+ * Returns 0 for success or an error on failure.
+ * Called at driver suspend.
+ */
+int amdgpu_device_prepare(struct drm_device *dev)
+{
+ struct amdgpu_device *adev = drm_to_adev(dev);
+ int r;
+
+ 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;
+
+ return 0;
+}
+
+/**
* amdgpu_device_suspend - initiate device suspend
*
* @dev: drm dev pointer
@@ -4230,11 +4256,6 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
adev->in_suspend = true;
- /* Evict the majority of BOs before grabbing the full access */
- r = amdgpu_device_evict_resources(adev);
- if (r)
- return r;
-
if (amdgpu_sriov_vf(adev)) {
amdgpu_virt_fini_data_exchange(adev);
r = amdgpu_virt_request_full_gpu(adev, false);
diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_drv.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_drv.c
index 3c0df8a235e..328f10f9a0d 100644
--- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_drv.c
+++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_drv.c
@@ -2393,8 +2393,9 @@ static int amdgpu_pmops_prepare(struct device *dev)
/* Return a positive number here so
* DPM_FLAG_SMART_SUSPEND works properly
*/
- if (amdgpu_device_supports_boco(drm_dev))
- return pm_runtime_suspended(dev);
+ if (amdgpu_device_supports_boco(drm_dev) &&
+ pm_runtime_suspended(dev))
+ return 1;
/* if we will not support s3 or s2i for the device
* then skip suspend
@@ -2403,7 +2404,7 @@ static int amdgpu_pmops_prepare(struct device *dev)
!amdgpu_acpi_is_s3_active(adev))
return 1;
- return 0;
+ return amdgpu_device_prepare(drm_dev);
}
static void amdgpu_pmops_complete(struct device *dev)
@@ -2605,6 +2606,9 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev)
if (amdgpu_device_supports_boco(drm_dev))
adev->mp1_state = PP_MP1_STATE_UNLOAD;
+ ret = amdgpu_device_prepare(drm_dev);
+ if (ret)
+ return ret;
ret = amdgpu_device_suspend(drm_dev, false);
if (ret) {
adev->in_runpm = false;
@@ -3667,6 +3671,7 @@ amdgpu_activate(struct device *self, int act)
switch (act) {
case DVACT_QUIESCE:
rv = config_activate_children(self, act);
+ amdgpu_device_prepare(dev);
amdgpu_device_suspend(dev, true);
break;
case DVACT_SUSPEND: