[PATCH 20/21] drm/nouveau: probe() against nvkm-provided auxiliary devices
Ben Skeggs
bskeggs at nvidia.com
Thu Jun 13 17:00:12 UTC 2024
Previously, the DRM driver was the entry-point for the pci/platform
bus probe() functions, and calls into NVKM to create an nvkm_device
from pci/platform devices, then continues on with DRM init.
Most of the code handling PCI/Tegra-specific functions has now been
moved to NVKM (though prior to this commit, still *called* from DRM)
and NVKM registers devices named "nvkm.device.<n>" on the auxiliary
bus for each PCI or Tegra GPU in the system.
The final step is to move pci/platform driver registration to NVKM,
and have the DRM driver register as an auxiliary driver, from where
it can gain access to the nvkm_device and proceed as it did before.
Signed-off-by: Ben Skeggs <bskeggs at nvidia.com>
---
drivers/gpu/drm/nouveau/Kbuild | 1 -
drivers/gpu/drm/nouveau/dispnv50/disp.c | 9 +-
drivers/gpu/drm/nouveau/nouveau_display.c | 2 +-
drivers/gpu/drm/nouveau/nouveau_drm.c | 178 ++++--------------
drivers/gpu/drm/nouveau/nouveau_drv.h | 17 +-
drivers/gpu/drm/nouveau/nouveau_platform.c | 93 ---------
drivers/gpu/drm/nouveau/nouveau_platform.h | 27 ---
drivers/gpu/drm/nouveau/nouveau_runpm.h | 2 +-
drivers/gpu/drm/nouveau/nvkm/device/acpi.c | 9 +-
drivers/gpu/drm/nouveau/nvkm/device/pci.c | 42 ++++-
drivers/gpu/drm/nouveau/nvkm/device/tegra.c | 43 ++++-
drivers/gpu/drm/nouveau/nvkm/module.c | 24 +++
.../gpu/drm/nouveau/nvkm/subdev/pci/base.c | 4 +-
13 files changed, 155 insertions(+), 296 deletions(-)
delete mode 100644 drivers/gpu/drm/nouveau/nouveau_platform.c
delete mode 100644 drivers/gpu/drm/nouveau/nouveau_platform.h
diff --git a/drivers/gpu/drm/nouveau/Kbuild b/drivers/gpu/drm/nouveau/Kbuild
index 61eeef83847a..cc471ab6a7ec 100644
--- a/drivers/gpu/drm/nouveau/Kbuild
+++ b/drivers/gpu/drm/nouveau/Kbuild
@@ -23,7 +23,6 @@ nouveau-y += nouveau_drm.o
nouveau-y += nouveau_hwmon.o
nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
nouveau-$(CONFIG_LEDS_CLASS) += nouveau_led.o
-nouveau-$(CONFIG_NOUVEAU_PLATFORM_DRIVER) += nouveau_platform.o
nouveau-y += nouveau_vga.o
# DRM - memory management
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index c0fc5233ebd4..60affaedb933 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -353,7 +353,8 @@ static int
nv50_audio_component_get_eld(struct device *kdev, int port, int dev_id,
bool *enabled, unsigned char *buf, int max_bytes)
{
- struct nouveau_drm *drm = dev_get_drvdata(kdev);
+ struct nvkm_device *device = dev_get_drvdata(kdev);
+ struct nouveau_drm *drm = container_of(device->driver, typeof(*drm), driver);
struct drm_encoder *encoder;
struct nouveau_encoder *nv_encoder;
struct nouveau_crtc *nv_crtc;
@@ -398,7 +399,8 @@ static int
nv50_audio_component_bind(struct device *kdev, struct device *hda_kdev,
void *data)
{
- struct nouveau_drm *drm = dev_get_drvdata(kdev);
+ struct nvkm_device *device = dev_get_drvdata(kdev);
+ struct nouveau_drm *drm = container_of(device->driver, typeof(*drm), driver);
struct drm_audio_component *acomp = data;
if (WARN_ON(!device_link_add(hda_kdev, kdev, DL_FLAG_STATELESS)))
@@ -416,7 +418,8 @@ static void
nv50_audio_component_unbind(struct device *kdev, struct device *hda_kdev,
void *data)
{
- struct nouveau_drm *drm = dev_get_drvdata(kdev);
+ struct nvkm_device *device = dev_get_drvdata(kdev);
+ struct nouveau_drm *drm = container_of(device->driver, typeof(*drm), driver);
struct drm_audio_component *acomp = data;
drm_modeset_lock_all(drm->dev);
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 57d31a17ad68..5ec320fdfaf8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -545,7 +545,7 @@ nouveau_display_acpi_ntfy(struct notifier_block *nb, unsigned long val,
{
struct nouveau_drm *drm = container_of(nb, typeof(*drm), acpi_nb);
struct acpi_bus_event *info = data;
- struct device *dev = drm->dev->dev;
+ struct device *dev = &drm->auxdev->dev;
int ret;
if (!strcmp(info->device_class, ACPI_VIDEO_CLASS)) {
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 2a9faf0fc277..7e77e950eba2 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -40,8 +40,6 @@
#include <core/gpuobj.h>
#include <core/module.h>
#include <core/option.h>
-#include <core/pci.h>
-#include <core/tegra.h>
#include <nvif/driver.h>
#include <nvif/fifo.h>
@@ -65,7 +63,6 @@
#include "nouveau_fence.h"
#include "nouveau_debugfs.h"
#include "nouveau_connector.h"
-#include "nouveau_platform.h"
#include "nouveau_svm.h"
#include "nouveau_dmem.h"
#include "nouveau_exec.h"
@@ -111,8 +108,6 @@ static int nouveau_runtime_pm = -1;
module_param_named(runpm, nouveau_runtime_pm, int, 0400);
static struct drm_driver driver_stub;
-static struct drm_driver driver_pci;
-static struct drm_driver driver_platform;
static inline bool
nouveau_cli_work_ready(struct dma_fence *fence)
@@ -530,6 +525,7 @@ nouveau_drm_device_fini(struct nouveau_drm *drm)
static int
nouveau_drm_device_init(struct nouveau_drm *drm)
{
+ struct nvkm_device *device = container_of(drm->auxdev, typeof(*device), auxdev);
struct drm_device *dev = drm->dev;
int ret;
@@ -623,7 +619,7 @@ nouveau_drm_device_del(struct nouveau_drm *drm)
}
static struct nouveau_drm *
-nouveau_drm_device_new(const struct drm_driver *drm_driver, struct device *parent,
+nouveau_drm_device_new(const struct drm_driver *drm_driver, struct auxiliary_device *parent,
struct nvkm_device *device)
{
const struct nvif_driver *driver;
@@ -636,7 +632,7 @@ nouveau_drm_device_new(const struct drm_driver *drm_driver, struct device *paren
if (!drm)
return ERR_PTR(-ENOMEM);
- drm->nvkm = device;
+ drm->auxdev = parent;
drm->driver = nouveau_driver;
drm->driver.switcheroo = nouveau_switcheroo;
@@ -705,14 +701,14 @@ nouveau_drm_device_new(const struct drm_driver *drm_driver, struct device *paren
goto done;
}
- drm->dev = drm_dev_alloc(drm_driver, parent);
+ drm->dev = drm_dev_alloc(drm_driver, parent->dev.parent);
if (IS_ERR(drm->dev)) {
ret = PTR_ERR(drm->dev);
goto done;
}
drm->dev->dev_private = drm;
- dev_set_drvdata(parent, drm);
+ auxiliary_set_drvdata(parent, drm);
done:
if (ret) {
@@ -723,68 +719,51 @@ nouveau_drm_device_new(const struct drm_driver *drm_driver, struct device *paren
return ret ? ERR_PTR(ret) : drm;
}
-static int nouveau_drm_probe(struct pci_dev *pdev,
- const struct pci_device_id *pent)
+static int
+nouveau_drm_probe(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id)
{
- struct nvkm_device *device;
+ struct nvkm_device *device = container_of(auxdev, typeof(*device), auxdev);
struct nouveau_drm *drm;
int ret;
- /* We need to check that the chipset is supported before booting
- * fbdev off the hardware, as there's no way to put it back.
- */
- ret = nvkm_device_pci_driver.probe(pdev, NULL);
- if (ret)
- return ret;
-
- device = pci_get_drvdata(pdev);
-
- if (nouveau_atomic)
- driver_pci.driver_features |= DRIVER_ATOMIC;
-
- drm = nouveau_drm_device_new(&driver_pci, &pdev->dev, device);
+ drm = nouveau_drm_device_new(&driver_stub, auxdev, device);
if (IS_ERR(drm)) {
ret = PTR_ERR(drm);
- goto fail_nvkm;
+ return ret;
}
ret = nouveau_drm_device_init(drm);
if (ret)
goto fail_drm;
- if (drm->device.impl->ram_size <= 32 * 1024 * 1024)
- drm_fbdev_ttm_setup(drm->dev, 8);
- else
- drm_fbdev_ttm_setup(drm->dev, 32);
+ if (drm->device.impl->disp.oclass) {
+ if (drm->device.impl->ram_size <= 32 * 1024 * 1024)
+ drm_fbdev_ttm_setup(drm->dev, 8);
+ else
+ drm_fbdev_ttm_setup(drm->dev, 32);
+
+ if (nouveau_atomic)
+ drm->dev->driver_features |= DRIVER_ATOMIC;
+ }
return 0;
fail_drm:
nouveau_drm_device_del(drm);
-fail_nvkm:
- nvkm_device_del(&device);
return ret;
}
-void
-nouveau_drm_device_remove(struct nouveau_drm *drm)
+static void
+nouveau_drm_remove(struct auxiliary_device *auxdev)
{
+ struct nouveau_drm *drm = auxiliary_get_drvdata(auxdev);
+
drm_dev_unplug(drm->dev);
nouveau_drm_device_fini(drm);
nouveau_drm_device_del(drm);
}
-static void
-nouveau_drm_remove(struct pci_dev *pdev)
-{
- struct nouveau_drm *drm = pci_get_drvdata(pdev);
-
- nouveau_drm_device_remove(drm);
-
- nvkm_device_pci_driver.remove(pdev);
-}
-
static int
nouveau_do_suspend(struct nouveau_drm *drm, bool runtime)
{
@@ -881,36 +860,25 @@ nouveau_do_resume(struct nouveau_drm *drm, bool runtime)
int
nouveau_pmops_suspend(struct device *dev)
{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct nouveau_drm *drm = pci_get_drvdata(pdev);
- int ret;
+ struct nouveau_drm *drm = dev_get_drvdata(dev);
if (drm->dev->switch_power_state == DRM_SWITCH_POWER_OFF ||
drm->dev->switch_power_state == DRM_SWITCH_POWER_DYNAMIC_OFF)
return 0;
- ret = nouveau_do_suspend(drm, false);
- if (ret)
- return ret;
-
- return nvkm_device_pci_driver.driver.pm->suspend(dev);
+ return nouveau_do_suspend(drm, false);
}
int
nouveau_pmops_resume(struct device *dev)
{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct nouveau_drm *drm = pci_get_drvdata(pdev);
+ struct nouveau_drm *drm = dev_get_drvdata(dev);
int ret;
if (drm->dev->switch_power_state == DRM_SWITCH_POWER_OFF ||
drm->dev->switch_power_state == DRM_SWITCH_POWER_DYNAMIC_OFF)
return 0;
- ret = nvkm_device_pci_driver.driver.pm->resume(dev);
- if (ret)
- return ret;
-
ret = nouveau_do_resume(drm, false);
/* Monitors may have been connected / disconnected during suspend */
@@ -949,8 +917,7 @@ nouveau_pmops_runtime(struct device *dev)
static int
nouveau_pmops_runtime_suspend(struct device *dev)
{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct nouveau_drm *drm = pci_get_drvdata(pdev);
+ struct nouveau_drm *drm = dev_get_drvdata(dev);
int ret;
if (!nouveau_pmops_runtime(dev)) {
@@ -959,7 +926,6 @@ nouveau_pmops_runtime_suspend(struct device *dev)
}
ret = nouveau_do_suspend(drm, true);
- ret = nvkm_device_pci_driver.driver.pm->runtime_suspend(dev);
drm->dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF;
return ret;
}
@@ -967,8 +933,7 @@ nouveau_pmops_runtime_suspend(struct device *dev)
static int
nouveau_pmops_runtime_resume(struct device *dev)
{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct nouveau_drm *drm = pci_get_drvdata(pdev);
+ struct nouveau_drm *drm = dev_get_drvdata(dev);
int ret;
if (!nouveau_pmops_runtime(dev)) {
@@ -976,10 +941,6 @@ nouveau_pmops_runtime_resume(struct device *dev)
return -EBUSY;
}
- ret = nvkm_device_pci_driver.driver.pm->runtime_resume(dev);
- if (ret)
- return ret;
-
ret = nouveau_do_resume(drm, true);
if (ret) {
NV_ERROR(drm, "resume failed with: %d\n", ret);
@@ -1183,21 +1144,6 @@ driver_stub = {
.patchlevel = DRIVER_PATCHLEVEL,
};
-static struct pci_device_id
-nouveau_drm_pci_table[] = {
- {
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
- .class = PCI_BASE_CLASS_DISPLAY << 16,
- .class_mask = 0xff << 16,
- },
- {
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA_SGS, PCI_ANY_ID),
- .class = PCI_BASE_CLASS_DISPLAY << 16,
- .class_mask = 0xff << 16,
- },
- {}
-};
-
static void nouveau_display_options(void)
{
DRM_DEBUG_DRIVER("Loading Nouveau with parameters:\n");
@@ -1226,57 +1172,26 @@ static const struct dev_pm_ops nouveau_pm_ops = {
.runtime_idle = nouveau_pmops_runtime_idle,
};
-static struct pci_driver
-nouveau_drm_pci_driver = {
+static const struct auxiliary_device_id
+nouveau_drm_id_table[] = {
+ { .name = "nouveau.device" },
+ {}
+};
+
+static struct auxiliary_driver
+nouveau_auxdrv = {
.name = "nouveau",
- .id_table = nouveau_drm_pci_table,
+ .id_table = nouveau_drm_id_table,
.probe = nouveau_drm_probe,
.remove = nouveau_drm_remove,
.driver.pm = &nouveau_pm_ops,
};
-struct drm_device *
-nouveau_platform_device_create(const struct nvkm_device_tegra_func *func,
- struct platform_device *pdev,
- struct nvkm_device **pdevice)
-{
- struct nouveau_drm *drm;
- int err;
-
- err = nvkm_device_tegra.probe(pdev);
- if (err)
- return ERR_PTR(err);
-
- *pdevice = platform_get_drvdata(pdev);
-
- drm = nouveau_drm_device_new(&driver_platform, &pdev->dev, *pdevice);
- if (IS_ERR(drm)) {
- err = PTR_ERR(drm);
- goto err_free;
- }
-
- err = nouveau_drm_device_init(drm);
- if (err)
- goto err_put;
-
- return drm->dev;
-
-err_put:
- nouveau_drm_device_del(drm);
-err_free:
- nvkm_device_del(pdevice);
-
- return ERR_PTR(err);
-}
-
static int __init
nouveau_drm_init(void)
{
int ret;
- driver_pci = driver_stub;
- driver_platform = driver_stub;
-
nouveau_display_options();
if (nouveau_modeset == -1) {
@@ -1291,17 +1206,9 @@ nouveau_drm_init(void)
if (ret)
return ret;
-#ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER
- platform_driver_register(&nouveau_platform_driver);
-#endif
-
nouveau_backlight_ctor();
-#ifdef CONFIG_PCI
- return pci_register_driver(&nouveau_drm_pci_driver);
-#else
- return 0;
-#endif
+ return auxiliary_driver_register(&nouveau_auxdrv);
}
static void __exit
@@ -1310,14 +1217,10 @@ nouveau_drm_exit(void)
if (!nouveau_modeset)
return;
-#ifdef CONFIG_PCI
- pci_unregister_driver(&nouveau_drm_pci_driver);
-#endif
+ auxiliary_driver_unregister(&nouveau_auxdrv);
+
nouveau_backlight_dtor();
-#ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER
- platform_driver_unregister(&nouveau_platform_driver);
-#endif
if (IS_ENABLED(CONFIG_DRM_NOUVEAU_SVM))
mmu_notifier_synchronize();
@@ -1327,7 +1230,6 @@ nouveau_drm_exit(void)
module_init(nouveau_drm_init);
module_exit(nouveau_drm_exit);
-MODULE_DEVICE_TABLE(pci, nouveau_drm_pci_table);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 9ca0f6ab4359..ee1116bf7824 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -61,7 +61,6 @@
#include "uapi/drm/nouveau_drm.h"
struct nouveau_channel;
-struct platform_device;
#include "nouveau_fence.h"
#include "nouveau_bios.h"
@@ -201,7 +200,8 @@ u_memcpya(uint64_t user, unsigned int nmemb, unsigned int size)
#include <nvif/parent.h>
struct nouveau_drm {
- struct nvkm_device *nvkm;
+ struct auxiliary_device *auxdev;
+
struct nvif_driver_func driver;
struct nvif_parent parent;
struct nvif_client client;
@@ -322,20 +322,13 @@ int nouveau_pmops_suspend(struct device *);
int nouveau_pmops_resume(struct device *);
bool nouveau_pmops_runtime(struct device *);
-#include <nvkm/core/tegra.h>
-
-struct drm_device *
-nouveau_platform_device_create(const struct nvkm_device_tegra_func *,
- struct platform_device *, struct nvkm_device **);
-void nouveau_drm_device_remove(struct nouveau_drm *);
-
#define NV_PRINTK(l,c,f,a...) do { \
struct nouveau_cli *_cli = (c); \
dev_##l(_cli->drm->dev->dev, "%s: "f, _cli->name, ##a); \
} while(0)
-#define NV_PRINTK_(l,drm,f,a...) do { \
- dev_##l((drm)->nvkm->dev, "drm: "f, ##a); \
+#define NV_PRINTK_(l,drm,f,a...) do { \
+ dev_##l(&(drm)->auxdev->dev, "drm: "f, ##a); \
} while(0)
#define NV_FATAL(drm,f,a...) NV_PRINTK_(crit, (drm), f, ##a)
#define NV_ERROR(drm,f,a...) NV_PRINTK_(err, (drm), f, ##a)
@@ -371,7 +364,7 @@ extern int nouveau_modeset;
static inline struct nvkm_device *
nvxx_device(struct nouveau_drm *drm)
{
- return drm->nvkm;
+ return container_of(drm->auxdev, struct nvkm_device, auxdev);
}
#define nvxx_bios(a) nvxx_device(a)->bios
diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.c b/drivers/gpu/drm/nouveau/nouveau_platform.c
deleted file mode 100644
index 23beac1f96f1..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_platform.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#include "nouveau_platform.h"
-
-static int nouveau_platform_probe(struct platform_device *pdev)
-{
- const struct nvkm_device_tegra_func *func;
- struct nvkm_device *device = NULL;
- struct drm_device *drm;
- int ret;
-
- func = of_device_get_match_data(&pdev->dev);
-
- drm = nouveau_platform_device_create(func, pdev, &device);
- if (IS_ERR(drm))
- return PTR_ERR(drm);
-
- return 0;
-}
-
-static void nouveau_platform_remove(struct platform_device *pdev)
-{
- struct nouveau_drm *drm = platform_get_drvdata(pdev);
-
- nouveau_drm_device_remove(drm);
-
- nvkm_device_tegra.remove_new(pdev);
-}
-
-#if IS_ENABLED(CONFIG_OF)
-static const struct nvkm_device_tegra_func gk20a_platform_data = {
- .iommu_bit = 34,
- .require_vdd = true,
-};
-
-static const struct nvkm_device_tegra_func gm20b_platform_data = {
- .iommu_bit = 34,
- .require_vdd = true,
- .require_ref_clk = true,
-};
-
-static const struct nvkm_device_tegra_func gp10b_platform_data = {
- .iommu_bit = 36,
- /* power provided by generic PM domains */
- .require_vdd = false,
-};
-
-static const struct of_device_id nouveau_platform_match[] = {
- {
- .compatible = "nvidia,gk20a",
- .data = &gk20a_platform_data,
- },
- {
- .compatible = "nvidia,gm20b",
- .data = &gm20b_platform_data,
- },
- {
- .compatible = "nvidia,gp10b",
- .data = &gp10b_platform_data,
- },
- { }
-};
-
-MODULE_DEVICE_TABLE(of, nouveau_platform_match);
-#endif
-
-struct platform_driver nouveau_platform_driver = {
- .driver = {
- .name = "nouveau",
- .of_match_table = of_match_ptr(nouveau_platform_match),
- },
- .probe = nouveau_platform_probe,
- .remove_new = nouveau_platform_remove,
-};
diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.h b/drivers/gpu/drm/nouveau/nouveau_platform.h
deleted file mode 100644
index a90d72767b8b..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_platform.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#ifndef __NOUVEAU_PLATFORM_H__
-#define __NOUVEAU_PLATFORM_H__
-#include "nouveau_drv.h"
-
-extern struct platform_driver nouveau_platform_driver;
-#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_runpm.h b/drivers/gpu/drm/nouveau/nouveau_runpm.h
index 92d6c518bdad..0de62022db58 100644
--- a/drivers/gpu/drm/nouveau/nouveau_runpm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_runpm.h
@@ -6,7 +6,7 @@
static inline struct device *
nouveau_runpm_dev(struct nouveau_drm *drm)
{
- return drm->dev->dev;
+ return &drm->auxdev->dev;
}
static inline void
diff --git a/drivers/gpu/drm/nouveau/nvkm/device/acpi.c b/drivers/gpu/drm/nouveau/nvkm/device/acpi.c
index cbaad3ea10eb..c4cbdf172499 100644
--- a/drivers/gpu/drm/nouveau/nvkm/device/acpi.c
+++ b/drivers/gpu/drm/nouveau/nvkm/device/acpi.c
@@ -191,13 +191,10 @@ static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switchero
return 0;
}
-#include "nouveau_drv.h"
-#include "nouveau_acpi.h"
-
static void
nvkm_acpi_switcheroo_reprobe(struct pci_dev *pdev)
{
- struct nvkm_device *device = ((struct nouveau_drm *)pci_get_drvdata(pdev))->nvkm;
+ struct nvkm_device *device = pci_get_drvdata(pdev);
device->driver->switcheroo.reprobe(device->driver);
}
@@ -206,7 +203,7 @@ static void
nvkm_acpi_switcheroo_set_state(struct pci_dev *pdev,
enum vga_switcheroo_state state)
{
- struct nvkm_device *device = ((struct nouveau_drm *)pci_get_drvdata(pdev))->nvkm;
+ struct nvkm_device *device = pci_get_drvdata(pdev);
if (state == VGA_SWITCHEROO_OFF) {
if (nouveau_dsm_priv.dsm_detected || nouveau_dsm_priv.optimus_detected)
@@ -221,7 +218,7 @@ nvkm_acpi_switcheroo_set_state(struct pci_dev *pdev,
static bool
nvkm_acpi_switcheroo_can_switch(struct pci_dev *pdev)
{
- struct nvkm_device *device = ((struct nouveau_drm *)pci_get_drvdata(pdev))->nvkm;
+ struct nvkm_device *device = pci_get_drvdata(pdev);
return device->driver->switcheroo.can_switch(device->driver);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/device/pci.c
index a66cb9d474d5..735bf0a9931d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/device/pci.c
+++ b/drivers/gpu/drm/nouveau/nvkm/device/pci.c
@@ -1618,12 +1618,10 @@ nvkm_device_pci_func = {
.cpu_coherent = !IS_ENABLED(CONFIG_ARM),
};
-#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 nvkm_device *device = dev_get_drvdata(dev);
struct pci_dev *pdev = nvkm_device_pci(device)->pdev;
int ret;
@@ -1644,7 +1642,7 @@ nvkm_device_pci_pm_runtime_resume(struct device *dev)
static int
nvkm_device_pci_pm_runtime_suspend(struct device *dev)
{
- struct nvkm_device *device = ((struct nouveau_drm *)dev_get_drvdata(dev))->nvkm;
+ struct nvkm_device *device = dev_get_drvdata(dev);
struct pci_dev *pdev = nvkm_device_pci(device)->pdev;
nvkm_acpi_switcheroo_set_powerdown();
@@ -1659,7 +1657,7 @@ nvkm_device_pci_pm_runtime_suspend(struct device *dev)
static int
nvkm_device_pci_pm_resume(struct device *dev)
{
- struct nvkm_device *device = ((struct nouveau_drm *)dev_get_drvdata(dev))->nvkm;
+ struct nvkm_device *device = dev_get_drvdata(dev);
struct pci_dev *pdev = nvkm_device_pci(device)->pdev;
int ret;
@@ -1677,7 +1675,7 @@ nvkm_device_pci_pm_resume(struct device *dev)
static int
nvkm_device_pci_pm_suspend(struct device *dev)
{
- struct nvkm_device *device = ((struct nouveau_drm *)dev_get_drvdata(dev))->nvkm;
+ struct nvkm_device *device = dev_get_drvdata(dev);
struct pci_dev *pdev = nvkm_device_pci(device)->pdev;
pci_save_state(pdev);
@@ -1698,8 +1696,12 @@ nvkm_device_pci_pm = {
static void
nvkm_device_pci_remove(struct pci_dev *dev)
{
- struct drm_device *drm_dev = pci_get_drvdata(dev);
- struct nvkm_device *device = nouveau_drm(drm_dev)->nvkm;
+ struct nvkm_device *device = pci_get_drvdata(dev);
+
+ if (device->runpm) {
+ pm_runtime_get_sync(device->dev);
+ pm_runtime_forbid(device->dev);
+ }
nvkm_device_del(&device);
}
@@ -1855,12 +1857,36 @@ nvkm_device_pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
}
}
+ if (device->runpm) {
+ pm_runtime_allow(device->dev);
+ pm_runtime_put(device->dev);
+ }
+
return 0;
}
+static struct pci_device_id
+nvkm_device_pci_id_table[] = {
+ {
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
+ .class = PCI_BASE_CLASS_DISPLAY << 16,
+ .class_mask = 0xff << 16,
+ },
+ {
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA_SGS, PCI_ANY_ID),
+ .class = PCI_BASE_CLASS_DISPLAY << 16,
+ .class_mask = 0xff << 16,
+ },
+ {}
+};
+
struct pci_driver
nvkm_device_pci_driver = {
+ .name = "nvkm",
+ .id_table = nvkm_device_pci_id_table,
.probe = nvkm_device_pci_probe,
.remove = nvkm_device_pci_remove,
.driver.pm = &nvkm_device_pci_pm,
};
+
+MODULE_DEVICE_TABLE(pci, nvkm_device_pci_id_table);
diff --git a/drivers/gpu/drm/nouveau/nvkm/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/device/tegra.c
index f0c1258170f4..743a781586c0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/device/tegra.c
+++ b/drivers/gpu/drm/nouveau/nvkm/device/tegra.c
@@ -233,12 +233,10 @@ nvkm_device_tegra_func = {
.cpu_coherent = false,
};
-#include "nouveau_drv.h"
-
static void
nvkm_device_tegra_remove(struct platform_device *pdev)
{
- struct nvkm_device *device = ((struct nouveau_drm *)platform_get_drvdata(pdev))->nvkm;
+ struct nvkm_device *device = platform_get_drvdata(dev);
nvkm_device_del(&device);
}
@@ -336,11 +334,50 @@ nvkm_device_tegra_probe(struct platform_device *pdev)
return ret;
}
+static const struct nvkm_device_tegra_func gk20a_platform_data = {
+ .iommu_bit = 34,
+ .require_vdd = true,
+};
+
+static const struct nvkm_device_tegra_func gm20b_platform_data = {
+ .iommu_bit = 34,
+ .require_vdd = true,
+ .require_ref_clk = true,
+};
+
+static const struct nvkm_device_tegra_func gp10b_platform_data = {
+ .iommu_bit = 36,
+ /* power provided by generic PM domains */
+ .require_vdd = false,
+};
+
+static const struct of_device_id nouveau_platform_match[] = {
+ {
+ .compatible = "nvidia,gk20a",
+ .data = &gk20a_platform_data,
+ },
+ {
+ .compatible = "nvidia,gm20b",
+ .data = &gm20b_platform_data,
+ },
+ {
+ .compatible = "nvidia,gp10b",
+ .data = &gp10b_platform_data,
+ },
+ { }
+};
+
struct platform_driver
nvkm_device_tegra = {
+ .driver = {
+ .name = "nvkm",
+ .of_match_table = of_match_ptr(nouveau_platform_match),
+ },
.probe = nvkm_device_tegra_probe,
.remove_new = nvkm_device_tegra_remove,
};
+
+MODULE_DEVICE_TABLE(of, nouveau_platform_match);
#else
struct platform_driver
nvkm_device_tegra = {
diff --git a/drivers/gpu/drm/nouveau/nvkm/module.c b/drivers/gpu/drm/nouveau/nvkm/module.c
index 7a56ef8c3b6b..c14dd7fa15c2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/module.c
+++ b/drivers/gpu/drm/nouveau/nvkm/module.c
@@ -20,6 +20,8 @@
* DEALINGS IN THE SOFTWARE.
*/
#include <core/module.h>
+#include <core/pci.h>
+#include <core/tegra.h>
#include <device/acpi.h>
int nvkm_runpm = -1;
@@ -27,12 +29,34 @@ int nvkm_runpm = -1;
void __exit
nvkm_exit(void)
{
+#ifdef CONFIG_PCI
nvkm_acpi_switcheroo_fini();
+ pci_unregister_driver(&nvkm_device_pci_driver);
+#endif
+
+#ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER
+ platform_driver_unregister(&nvkm_device_tegra);
+#endif
}
int __init
nvkm_init(void)
{
+ int ret;
+
+#ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER
+ ret = platform_driver_register(&nvkm_device_tegra);
+ if (ret)
+ return ret;
+#endif
+
+#ifdef CONFIG_PCI
nvkm_acpi_switcheroo_init();
+
+ ret = pci_register_driver(&nvkm_device_pci_driver);
+ if (ret)
+ return ret;
+#endif
+
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
index e4737b89cb63..919e07d85f2e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
@@ -64,12 +64,10 @@ nvkm_pci_mask(struct nvkm_pci *pci, u16 addr, u32 mask, u32 value)
return data;
}
-#include "nouveau_drv.h"
-
static unsigned int
nvkm_pci_vga_set_decode(struct pci_dev *pdev, bool state)
{
- struct nvkm_device *device = ((struct nouveau_drm *)pci_get_drvdata(pdev))->nvkm;
+ struct nvkm_device *device = pci_get_drvdata(pdev);
if (device->card_type == NV_40 &&
device->chipset >= 0x4c)
--
2.44.0
More information about the Nouveau
mailing list