diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2021-03-10 00:41:49 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2021-04-09 16:35:55 -0400 |
commit | e25443d2765f40a9b3d0056dc4d560a007dd850c (patch) | |
tree | b613c822cef797d35f4a8a0bc65b656db28b5fc7 /drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | |
parent | ed098aa34c51d81a16de93f59c64e36a136fd201 (diff) | |
download | lwn-e25443d2765f40a9b3d0056dc4d560a007dd850c.tar.gz lwn-e25443d2765f40a9b3d0056dc4d560a007dd850c.zip |
drm/amdgpu: add a dev_pm_ops prepare callback (v2)
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>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index fcda7189d4ab..1508da68cfbb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -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, |