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@xxxxxxxxxx> --- 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