drm/amdgpu: add a dev_pm_ops prepare callback (v2)
authorAlex Deucher <alexander.deucher@amd.com>
Wed, 10 Mar 2021 05:41:49 +0000 (00:41 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 9 Apr 2021 20:35:55 +0000 (16:35 -0400)
as per:
https://www.kernel.org/doc/html/latest/driver-api/pm/devices.html

The prepare callback is required to support the DPM_FLAG_SMART_SUSPEND
driver flag.  This allows runtime pm to auto complete when the
system goes into suspend avoiding a wake up on suspend and on resume.
Apply this for hybrid gfx and BOCO systems where d3cold is
provided by the ACPI platform.

v2: check if device is runtime suspended in prepare.

Reviewed-by: Evan Quan <evan.quan@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c

index fcda7189d4ab7627031774c59a98dc49fe90cc89..1508da68cfbb84965adbad24e736192a1475f6eb 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/vga_switcheroo.h>
 #include <drm/drm_probe_helper.h>
 #include <linux/mmu_notifier.h>
+#include <linux/suspend.h>
 
 #include "amdgpu.h"
 #include "amdgpu_irq.h"
@@ -1403,6 +1404,27 @@ static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work)
        return;
 }
 
+static int amdgpu_pmops_prepare(struct device *dev)
+{
+       struct drm_device *drm_dev = dev_get_drvdata(dev);
+
+       /* Return a positive number here so
+        * DPM_FLAG_SMART_SUSPEND works properly
+        */
+       if ((amdgpu_device_supports_atpx(drm_dev) &&
+           amdgpu_is_atpx_hybrid()) ||
+           amdgpu_device_supports_boco(drm_dev))
+               return pm_runtime_suspended(dev) &&
+                       pm_suspend_via_firmware();
+
+       return 0;
+}
+
+static void amdgpu_pmops_complete(struct device *dev)
+{
+       /* nothing to do */
+}
+
 static int amdgpu_pmops_suspend(struct device *dev)
 {
        struct drm_device *drm_dev = dev_get_drvdata(dev);
@@ -1621,6 +1643,8 @@ out:
 }
 
 static const struct dev_pm_ops amdgpu_pm_ops = {
+       .prepare = amdgpu_pmops_prepare,
+       .complete = amdgpu_pmops_complete,
        .suspend = amdgpu_pmops_suspend,
        .resume = amdgpu_pmops_resume,
        .freeze = amdgpu_pmops_freeze,