@@ -538,6 +538,8 @@ struct nvif_device_impl {
u64 ram_size;
u64 ram_user;
+ bool runpm;
+
u64 (*time)(struct nvif_device_priv *);
struct {
@@ -55,6 +55,12 @@ struct nvkm_device {
struct notifier_block nb;
} acpi;
+ enum {
+ NVKM_DEVICE_RUNPM_NONE = 0,
+ NVKM_DEVICE_RUNPM_V1,
+ NVKM_DEVICE_RUNPM_OPTIMUS,
+ } runpm;
+
#define NVKM_LAYOUT_ONCE(type,data,ptr) data *ptr;
#define NVKM_LAYOUT_INST(type,data,ptr,cnt) data *ptr[cnt];
#include <core/layout.h>
@@ -5,4 +5,6 @@
int __init nvkm_init(void);
void __exit nvkm_exit(void);
+
+extern int nvkm_runpm;
#endif
@@ -486,7 +486,7 @@ nouveau_drm_device_fini(struct nouveau_drm *drm)
struct drm_device *dev = drm->dev;
struct nouveau_cli *cli, *temp_cli;
- if (nouveau_pmops_runtime()) {
+ if (nouveau_pmops_runtime(dev->dev)) {
pm_runtime_get_sync(dev->dev);
pm_runtime_forbid(dev->dev);
}
@@ -584,7 +584,7 @@ nouveau_drm_device_init(struct nouveau_drm *drm)
nouveau_dmem_init(drm);
nouveau_led_init(dev);
- if (nouveau_pmops_runtime()) {
+ if (nouveau_pmops_runtime(dev->dev)) {
pm_runtime_use_autosuspend(dev->dev);
pm_runtime_set_autosuspend_delay(dev->dev, 5000);
pm_runtime_set_active(dev->dev);
@@ -1031,10 +1031,13 @@ nouveau_pmops_thaw(struct device *dev)
}
bool
-nouveau_pmops_runtime(void)
+nouveau_pmops_runtime(struct device *dev)
{
+ struct nouveau_drm *drm = nouveau_drm(dev_get_drvdata(dev));
+
if (nouveau_runtime_pm == -1)
- return nouveau_is_optimus() || nouveau_is_v1_dsm();
+ return drm->device.impl->runpm;
+
return nouveau_runtime_pm == 1;
}
@@ -1045,7 +1048,7 @@ nouveau_pmops_runtime_suspend(struct device *dev)
struct nouveau_drm *drm = pci_get_drvdata(pdev);
int ret;
- if (!nouveau_pmops_runtime()) {
+ if (!nouveau_pmops_runtime(dev)) {
pm_runtime_forbid(dev);
return -EBUSY;
}
@@ -1067,7 +1070,7 @@ nouveau_pmops_runtime_resume(struct device *dev)
struct nouveau_drm *drm = pci_get_drvdata(pdev);
int ret;
- if (!nouveau_pmops_runtime()) {
+ if (!nouveau_pmops_runtime(dev)) {
pm_runtime_forbid(dev);
return -EBUSY;
}
@@ -1098,7 +1101,7 @@ nouveau_pmops_runtime_resume(struct device *dev)
static int
nouveau_pmops_runtime_idle(struct device *dev)
{
- if (!nouveau_pmops_runtime()) {
+ if (!nouveau_pmops_runtime(dev)) {
pm_runtime_forbid(dev);
return -EBUSY;
}
@@ -324,7 +324,7 @@ nouveau_drm_use_coherent_gpu_mapping(struct nouveau_drm *drm)
int nouveau_pmops_suspend(struct device *);
int nouveau_pmops_resume(struct device *);
-bool nouveau_pmops_runtime(void);
+bool nouveau_pmops_runtime(struct device *);
#include <nvkm/core/tegra.h>
@@ -63,7 +63,7 @@ void
nouveau_vga_init(struct nouveau_drm *drm)
{
struct drm_device *dev = drm->dev;
- bool runtime = nouveau_pmops_runtime();
+ bool runtime = nouveau_pmops_runtime(dev->dev);
struct pci_dev *pdev;
/* only relevant for PCI devices */
@@ -85,7 +85,7 @@ void
nouveau_vga_fini(struct nouveau_drm *drm)
{
struct drm_device *dev = drm->dev;
- bool runtime = nouveau_pmops_runtime();
+ bool runtime = nouveau_pmops_runtime(dev->dev);
struct pci_dev *pdev;
/* only relevant for PCI devices */
@@ -22,6 +22,8 @@
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
#include <core/pci.h>
+#include <core/module.h>
+#include "acpi.h"
#include "priv.h"
struct nvkm_device_pci_device {
@@ -1704,5 +1706,15 @@ nvkm_device_pci_new(struct pci_dev *pci_dev, const char *cfg, const char *dbg,
}
*pdevice = &pdev->device;
+
+ if (nvkm_runpm) {
+ if (!nouveau_dsm_priv.optimus_detected) {
+ if (nouveau_dsm_priv.dsm_detected)
+ device->runpm = NVKM_DEVICE_RUNPM_V1;
+ } else {
+ device->runpm = NVKM_DEVICE_RUNPM_OPTIMUS;
+ }
+ }
+
return 0;
}
@@ -393,6 +393,8 @@ nvkm_udevice_new(struct nvkm_device *device,
if (device->imem && udev->impl.ram_size > 0)
udev->impl.ram_user = udev->impl.ram_user - device->imem->reserved;
+ udev->impl.runpm = (device->runpm != NVKM_DEVICE_RUNPM_NONE);
+
if (device->vfn) {
udev->impl.usermode.oclass = device->vfn->user.base.oclass;
udev->impl.usermode.new = nvkm_udevice_usermode_new;
@@ -22,6 +22,8 @@
#include <core/module.h>
#include <device/acpi.h>
+int nvkm_runpm = -1;
+
void __exit
nvkm_exit(void)
{
The DRM driver uses "nouveau_is_optimus() || nouveau_is_v1_dsm()", which have been moved to NVKM, to determine support for runtime pm. Replace with a feature flag returned when allocating an nvif_device. Signed-off-by: Ben Skeggs <bskeggs@nvidia.com> --- drivers/gpu/drm/nouveau/include/nvif/driverif.h | 2 ++ .../gpu/drm/nouveau/include/nvkm/core/device.h | 6 ++++++ .../gpu/drm/nouveau/include/nvkm/core/module.h | 2 ++ drivers/gpu/drm/nouveau/nouveau_drm.c | 17 ++++++++++------- drivers/gpu/drm/nouveau/nouveau_drv.h | 2 +- drivers/gpu/drm/nouveau/nouveau_vga.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/device/pci.c | 12 ++++++++++++ drivers/gpu/drm/nouveau/nvkm/device/user.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/module.c | 2 ++ 9 files changed, 39 insertions(+), 10 deletions(-)