drm/amd: Evict resources during PM ops prepare() callback
authorjsg <jsg@openbsd.org>
Thu, 11 Apr 2024 03:24:40 +0000 (03:24 +0000)
committerjsg <jsg@openbsd.org>
Thu, 11 Apr 2024 03:24:40 +0000 (03:24 +0000)
From Mario Limonciello
8b5f720486ca87e102ee722a73ae0894c12f1e7a in linux-6.6.y/6.6.26
5095d5418193eb2748c7d8553c7150b8f1c44696 in mainline linux

sys/dev/pci/drm/amd/amdgpu/amdgpu.h
sys/dev/pci/drm/amd/amdgpu/amdgpu_device.c
sys/dev/pci/drm/amd/amdgpu/amdgpu_drv.c

index afac024..38a424f 100644 (file)
@@ -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);
index 7901aeb..3029753 100644 (file)
@@ -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 */
@@ -4205,6 +4206,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
  *
@@ -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);
index 3c0df8a..328f10f 100644 (file)
@@ -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: