[PATCH 17/21] drm/nouveau/nvkm: move pci pm ops from drm
Ben Skeggs
bskeggs at nvidia.com
Thu Jun 13 17:00:09 UTC 2024
Moves the PCI-specific portions of nouveau_pmops to NVKM, leaving the
DRM pieces where they are. The NVKM functions are called through the
the nvkm_device_pci_driver struct from DRM for now, but will be fully
separated once the DRM driver is implemented on an auxiliary device.
Signed-off-by: Ben Skeggs <bskeggs at nvidia.com>
---
drivers/gpu/drm/nouveau/nouveau_acpi.h | 3 -
drivers/gpu/drm/nouveau/nouveau_drm.c | 24 ++-----
drivers/gpu/drm/nouveau/nvkm/device/pci.c | 76 +++++++++++++++++++++++
3 files changed, 80 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.h b/drivers/gpu/drm/nouveau/nouveau_acpi.h
index be1b218cb921..b4c7ae78cedc 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.h
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.h
@@ -5,13 +5,10 @@
#define ROM_BIOS_PAGE 4096
#if defined(CONFIG_ACPI) && defined(CONFIG_X86)
-#include <device/acpi.h>
-static inline void nouveau_switcheroo_optimus_dsm(void) { nvkm_acpi_switcheroo_set_powerdown(); }
void *nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
bool nouveau_acpi_video_backlight_use_native(void);
void nouveau_acpi_video_register_backlight(void);
#else
-static inline void nouveau_switcheroo_optimus_dsm(void) {}
static inline void *nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { return NULL; }
static inline bool nouveau_acpi_video_backlight_use_native(void) { return true; }
static inline void nouveau_acpi_video_register_backlight(void) {}
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 76eddf172bb5..aa54aee23814 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -901,11 +901,7 @@ nouveau_pmops_suspend(struct device *dev)
if (ret)
return ret;
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
- udelay(200);
- return 0;
+ return nvkm_device_pci_driver.driver.pm->suspend(dev);
}
int
@@ -919,12 +915,9 @@ nouveau_pmops_resume(struct device *dev)
drm->dev->switch_power_state == DRM_SWITCH_POWER_DYNAMIC_OFF)
return 0;
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- ret = pci_enable_device(pdev);
+ ret = nvkm_device_pci_driver.driver.pm->resume(dev);
if (ret)
return ret;
- pci_set_master(pdev);
ret = nouveau_do_resume(drm, false);
@@ -973,12 +966,8 @@ nouveau_pmops_runtime_suspend(struct device *dev)
return -EBUSY;
}
- nouveau_switcheroo_optimus_dsm();
ret = nouveau_do_suspend(drm, true);
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_ignore_hotplug(pdev);
- pci_set_power_state(pdev, PCI_D3cold);
+ ret = nvkm_device_pci_driver.driver.pm->runtime_suspend(dev);
drm->dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF;
return ret;
}
@@ -995,12 +984,9 @@ nouveau_pmops_runtime_resume(struct device *dev)
return -EBUSY;
}
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- ret = pci_enable_device(pdev);
+ ret = nvkm_device_pci_driver.driver.pm->runtime_resume(dev);
if (ret)
return ret;
- pci_set_master(pdev);
ret = nouveau_do_resume(drm, true);
if (ret) {
@@ -1008,8 +994,6 @@ nouveau_pmops_runtime_resume(struct device *dev)
return ret;
}
- /* do magic */
- nvif_mask(&drm->device, 0x088488, (1 << 25), (1 << 25));
drm->dev->switch_power_state = DRM_SWITCH_POWER_ON;
/* Monitors may have been connected / disconnected during suspend */
diff --git a/drivers/gpu/drm/nouveau/nvkm/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/device/pci.c
index d454d56a7909..a66cb9d474d5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/device/pci.c
+++ b/drivers/gpu/drm/nouveau/nvkm/device/pci.c
@@ -1620,6 +1620,81 @@ nvkm_device_pci_func = {
#include "nouveau_drv.h"
+static int
+nvkm_device_pci_pm_runtime_resume(struct device *dev)
+{
+ struct nvkm_device *device = ((struct nouveau_drm *)dev_get_drvdata(dev))->nvkm;
+ struct pci_dev *pdev = nvkm_device_pci(device)->pdev;
+ int ret;
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+
+ ret = pci_enable_device(pdev);
+ if (ret)
+ return ret;
+
+ pci_set_master(pdev);
+
+ /* do magic */
+ nvkm_mask(device, 0x088488, (1 << 25), (1 << 25));
+ return 0;
+}
+
+static int
+nvkm_device_pci_pm_runtime_suspend(struct device *dev)
+{
+ struct nvkm_device *device = ((struct nouveau_drm *)dev_get_drvdata(dev))->nvkm;
+ struct pci_dev *pdev = nvkm_device_pci(device)->pdev;
+
+ nvkm_acpi_switcheroo_set_powerdown();
+
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+ pci_ignore_hotplug(pdev);
+ pci_set_power_state(pdev, PCI_D3cold);
+ return 0;
+}
+
+static int
+nvkm_device_pci_pm_resume(struct device *dev)
+{
+ struct nvkm_device *device = ((struct nouveau_drm *)dev_get_drvdata(dev))->nvkm;
+ struct pci_dev *pdev = nvkm_device_pci(device)->pdev;
+ int ret;
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+
+ ret = pci_enable_device(pdev);
+ if (ret)
+ return ret;
+
+ pci_set_master(pdev);
+ return 0;
+}
+
+static int
+nvkm_device_pci_pm_suspend(struct device *dev)
+{
+ struct nvkm_device *device = ((struct nouveau_drm *)dev_get_drvdata(dev))->nvkm;
+ struct pci_dev *pdev = nvkm_device_pci(device)->pdev;
+
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+ udelay(200);
+ return 0;
+}
+
+static const struct dev_pm_ops
+nvkm_device_pci_pm = {
+ .suspend = nvkm_device_pci_pm_suspend,
+ .resume = nvkm_device_pci_pm_resume,
+ .runtime_suspend = nvkm_device_pci_pm_runtime_suspend,
+ .runtime_resume = nvkm_device_pci_pm_runtime_resume,
+};
+
static void
nvkm_device_pci_remove(struct pci_dev *dev)
{
@@ -1787,4 +1862,5 @@ struct pci_driver
nvkm_device_pci_driver = {
.probe = nvkm_device_pci_probe,
.remove = nvkm_device_pci_remove,
+ .driver.pm = &nvkm_device_pci_pm,
};
--
2.44.0
More information about the dri-devel
mailing list