Merge tag 'drm-misc-next-2023-01-03' of git://anongit.freedesktop.org/drm/drm-misc...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_device.c
index 74ccbd566777343d9ecb408f09533024d7e3735c..076ae400d099490d36e2dd5573e7a3315cb8ba13 100644 (file)
@@ -2473,6 +2473,11 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
                        if (!amdgpu_sriov_vf(adev)) {
                                struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev);
 
+                               if (WARN_ON(!hive)) {
+                                       r = -ENOENT;
+                                       goto init_failed;
+                               }
+
                                if (!hive->reset_domain ||
                                    !amdgpu_reset_get_reset_domain(hive->reset_domain)) {
                                        r = -ENOENT;
@@ -3011,14 +3016,15 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev)
                        continue;
                }
 
-               /* skip suspend of gfx and psp for S0ix
+               /* skip suspend of gfx/mes and psp for S0ix
                 * gfx is in gfxoff state, so on resume it will exit gfxoff just
                 * like at runtime. PSP is also part of the always on hardware
                 * so no need to suspend it.
                 */
                if (adev->in_s0ix &&
                    (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP ||
-                    adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX))
+                    adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX ||
+                    adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_MES))
                        continue;
 
                /* XXX handle errors */
@@ -4105,6 +4111,11 @@ 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);
@@ -4179,21 +4190,15 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
 
        r = amdgpu_device_ip_resume(adev);
 
-       /* no matter what r is, always need to properly release full GPU */
-       if (amdgpu_sriov_vf(adev)) {
-               amdgpu_virt_init_data_exchange(adev);
-               amdgpu_virt_release_full_gpu(adev, true);
-       }
-
        if (r) {
                dev_err(adev->dev, "amdgpu_device_ip_resume failed (%d).\n", r);
-               return r;
+               goto exit;
        }
        amdgpu_fence_driver_hw_init(adev);
 
        r = amdgpu_device_ip_late_init(adev);
        if (r)
-               return r;
+               goto exit;
 
        queue_delayed_work(system_wq, &adev->delayed_init_work,
                           msecs_to_jiffies(AMDGPU_RESUME_MS));
@@ -4201,12 +4206,19 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
        if (!adev->in_s0ix) {
                r = amdgpu_amdkfd_resume(adev, adev->in_runpm);
                if (r)
-                       return r;
+                       goto exit;
+       }
+
+exit:
+       if (amdgpu_sriov_vf(adev)) {
+               amdgpu_virt_init_data_exchange(adev);
+               amdgpu_virt_release_full_gpu(adev, true);
        }
 
+       if (r)
+               return r;
+
        /* Make sure IB tests flushed */
-       if (amdgpu_sriov_vf(adev))
-               amdgpu_irq_gpu_reset_resume_helper(adev);
        flush_delayed_work(&adev->delayed_init_work);
 
        if (adev->in_s0ix) {
@@ -5043,6 +5055,8 @@ static void amdgpu_device_resume_display_audio(struct amdgpu_device *adev)
                pm_runtime_enable(&(p->dev));
                pm_runtime_resume(&(p->dev));
        }
+
+       pci_dev_put(p);
 }
 
 static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
@@ -5081,6 +5095,7 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
 
                if (expires < ktime_get_mono_fast_ns()) {
                        dev_warn(adev->dev, "failed to suspend display audio\n");
+                       pci_dev_put(p);
                        /* TODO: abort the succeeding gpu reset? */
                        return -ETIMEDOUT;
                }
@@ -5088,6 +5103,7 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
 
        pm_runtime_disable(&(p->dev));
 
+       pci_dev_put(p);
        return 0;
 }