[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 Nouveau mailing list