Re: [PATCH] drm/nouveau/i2c: rename aux.c and aux.h to auxch.c and auxch.h
On 3/6/24 19:15, egyszer...@freemail.hu wrote: From: Benjamin Szőke The goal is to clean-up Linux repository from AUX file names, because the use of such file names is prohibited on other operating systems such as Windows, so the Linux repository cannot be cloned and edited on them. Signed-off-by: Benjamin Szőke Reviewed-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/{aux.c => auxch.c} | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/{aux.h => auxch.h} | 0 drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padg94.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgf119.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgm200.c | 2 +- 11 files changed, 10 insertions(+), 10 deletions(-) rename drivers/gpu/drm/nouveau/nvkm/subdev/i2c/{aux.c => auxch.c} (99%) rename drivers/gpu/drm/nouveau/nvkm/subdev/i2c/{aux.h => auxch.h} (100%) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild index 819703913a00..2c551bdc9bc9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild @@ -25,7 +25,7 @@ nvkm-y += nvkm/subdev/i2c/busnv50.o nvkm-y += nvkm/subdev/i2c/busgf119.o nvkm-y += nvkm/subdev/i2c/bit.o -nvkm-y += nvkm/subdev/i2c/aux.o +nvkm-y += nvkm/subdev/i2c/auxch.o nvkm-y += nvkm/subdev/i2c/auxg94.o nvkm-y += nvkm/subdev/i2c/auxgf119.o nvkm-y += nvkm/subdev/i2c/auxgm200.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c index dd391809fef7..6c76e5e14b75 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c @@ -24,7 +24,7 @@ #define anx9805_pad(p) container_of((p), struct anx9805_pad, base) #define anx9805_bus(p) container_of((p), struct anx9805_bus, base) #define anx9805_aux(p) container_of((p), struct anx9805_aux, base) -#include "aux.h" +#include "auxch.h" #include "bus.h" struct anx9805_pad { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxch.c similarity index 99% rename from drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c rename to drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxch.c index d063d0dc13c5..fafc634acbf6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxch.c @@ -24,7 +24,7 @@ #include -#include "aux.h" +#include "auxch.h" #include "pad.h" static int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxch.h similarity index 100% rename from drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h rename to drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxch.h diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c index 47068f6f9c55..854bb4b5fdb4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #define g94_i2c_aux(p) container_of((p), struct g94_i2c_aux, base) -#include "aux.h" +#include "auxch.h" struct g94_i2c_aux { struct nvkm_i2c_aux base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c index dab40cd8fe3a..c17d5647cb99 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c @@ -19,7 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "aux.h" +#include "auxch.h" static const struct nvkm_i2c_aux_func gf119_i2c_aux = { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c index 8bd1d442e465..3c5005e3b330 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #define gm200_i2c_aux(p) container_of((p), struct gm200_i2c_aux, base) -#include "aux.h" +#include "auxch.h" struct gm200_i2c_aux { struct nvkm_i2c_aux base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c index 976539de4220..ab86e11e7780 100644 --- a/drivers/gp
Re: [PATCH] nouveau: fix the fwsec sb verification register.
On 28/8/24 12:37, Dave Airlie wrote: From: Dave Airlie This aligns with what open gpu does, the 0x15 hex is just to trick you. Fixes: 176fdcbddfd2 ("drm/nouveau/gsp/r535: add support for booting GSP-RM") Reviewed-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/fwsec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/fwsec.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/fwsec.c index 330d72b1a4af..52412965fac1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/fwsec.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/fwsec.c @@ -324,7 +324,7 @@ nvkm_gsp_fwsec_sb(struct nvkm_gsp *gsp) return ret; /* Verify. */ - err = nvkm_rd32(device, 0x001400 + (0xf * 4)) & 0x; + err = nvkm_rd32(device, 0x001400 + (0x15 * 4)) & 0x; if (err) { nvkm_error(subdev, "fwsec-sb: 0x%04x\n", err); return -EIO;
Re: [PATCH 0/3] Nouveau fixes for TTM refcount rework
On 19/7/24 02:58, Danilo Krummrich wrote: Hi Christian, Those three patches should unblock your series to use GEM references instead of TTM ones. @Lyude, Dave: Can you please double check? Hi Danilo, These look fine to me, and appear to resolve the issues I see with just the refcount series applied. Ben. Reviewed-by: Ben Skeggs - Danilo Danilo Krummrich (3): drm/nouveau: prime: fix refcount underflow drm/nouveau: bo: remove unused functions drm/nouveau: use GEM references instead of TTMs drivers/gpu/drm/nouveau/dispnv04/crtc.c | 43 +++-- drivers/gpu/drm/nouveau/dispnv50/disp.c | 4 +- drivers/gpu/drm/nouveau/nouveau_bo.h| 50 ++--- drivers/gpu/drm/nouveau/nouveau_chan.c | 2 +- drivers/gpu/drm/nouveau/nouveau_dmem.c | 4 +- drivers/gpu/drm/nouveau/nouveau_prime.c | 3 +- drivers/gpu/drm/nouveau/nv10_fence.c| 2 +- drivers/gpu/drm/nouveau/nv17_fence.c| 2 +- drivers/gpu/drm/nouveau/nv50_fence.c| 2 +- drivers/gpu/drm/nouveau/nv84_fence.c| 4 +- 10 files changed, 46 insertions(+), 70 deletions(-) base-commit: 99e0fb8b087120b5a7019f1cff6c5c2b5b925ae5
Re: [RFC] GPU driver with separate "core" and "DRM" modules
On 18/6/24 03:30, Danilo Krummrich wrote: On Fri, Jun 14, 2024 at 03:02:09AM +1000, Ben Skeggs wrote: NVIDIA has been exploring ways to better support the effort for an upstream kernel mode driver for GPUs that are capable of running GSP-RM firmware, since the introduction[1] to Nova. Use cases have been identified for which separating the core GPU programming out of the full DRM driver stack is a strong requirement from our key customers. An upstreamed NVIDIA GPU driver should be able to support current and emerging customer use cases for vGPU hosts. NVIDIA's vGPU deployments to date do not support compute or graphics functionality within the hypervisor host, and have no dependency on the Linux graphics subsystem, instead implementing the minimal functionality required to run vGPU guest VMs. For security-sensitive environments such as cloud infrastructure, it's important to continue support for running a minimal footprint vGPU host driver in a stripped-down / barebones kernel environment. This can be achieved by supporting both VFIO and DRM drivers as clients of a core driver, without requiring a full-fledged DRM driver (or the DRM subsystem itself) to be built into the host kernel. A core driver would be responsible for booting and communicating with GSP-RM, enumeration of HW configuration, shared/partitioned resource management, exception handling, and event dispatch. The DRM driver would do all the standard things a DRM driver does, and implement GPU memory management (TTM/HMM), KMS, command submission etc, as well as providing UAPI for userspace clients. These features would be implemented using HW resources allocated from a core driver, rather than the DRM driver being directly responsible for HW programming. As Nouveau's KMD is already split (in the logical sense) along similar lines, we're using it here for the purposes of this RFC to demonstrate the feasibility of such an architecture, and open it up for discussion. Generally, I think that approach is reasonable and I like it. There's only a few concerns I have for now. We've already had (and still have) quite a few difficulties due to this split in Nouveau. Especially when it comes to VMM and handling page tables. There are cases where the locking architecture must be closely aligned with the upper layers, i.e. the (VM_BIND) uAPI. Having a separate (local) locking architecture doesn't work out well in this case due to the implications of dealing with dma_fences and their signalling paths. Unfortunately, we can't even argue that we solved this problem in Nouveau. I think it's fair to say that we found ways (without rewriting / restructuring a lot of the VMM code to use a more global locking architecture) to make it work in practice, but surely there are still conditions that (at least theoretically) can lock things up. I'm not saying that it's impossible to work this out, but having a strong separation is likely to make those things quite a bit more difficult. Yeah, I think there's a bit of work ahead to determine where exactly all the pieces should live. For VMM specifically, I'd be looking more at an architecture where the DRM driver "owns" all the memory remaining after GSP has booted (or was allocated to its VFIO partition) etc, and manages it however it sees fit. And, rather than calling into the core driver for mapping into a VMM, the DRM driver would allocate its own PDB, inform the core driver of its location, and manage its own page tables directly from there. This is similar to how the interface between NVKM and GSP-RM works now at least. I've looked a little bit recently into how to approach fixing this in nouveau, but don't have a solid plan yet. On the other hand this is a problem we might have to deal with either way, it shouldn't matter too much having separate modules for VFIO and the GPU core. Besides that, do we expect semantical changes in the firmware that can potentially propagate up in the following sense? [GSP firmware -> Host GPU core driver -> VFIO driver -> Guest GPU core driver] If so, how do we deal with those? In the context of ensuring compatibility, can we ensure this can't lead to increasing maintainance and testing effort over time? That's a very good question. I suspect it's inevitable that those type of changes could flow through from FW updates, and we'll need to come up with a plan for how to deal with them. In general, it seems like the same kind of problem as with maintaining UAPI compatibility, but I'm not sure if there's any additional considerations for virt. Ben. - Danilo A link[2] to a tree containing the patches is below. [1] https://lore.kernel.org/all/3ed356488c9b0ca93845501425d427309f4cf616.ca...@redhat.com/ [2] https://gitlab.freedesktop.org/bskeggs/nouveau/-/tree/00.03-module *** BLURB HERE *** Ben Skeggs (2
Re: [RFC] GPU driver with separate "core" and "DRM" modules
On 17/6/24 23:55, Daniel Vetter wrote: On Fri, Jun 14, 2024 at 03:02:09AM +1000, Ben Skeggs wrote: NVIDIA has been exploring ways to better support the effort for an upstream kernel mode driver for GPUs that are capable of running GSP-RM firmware, since the introduction[1] to Nova. Use cases have been identified for which separating the core GPU programming out of the full DRM driver stack is a strong requirement from our key customers. An upstreamed NVIDIA GPU driver should be able to support current and emerging customer use cases for vGPU hosts. NVIDIA's vGPU deployments to date do not support compute or graphics functionality within the hypervisor host, and have no dependency on the Linux graphics subsystem, instead implementing the minimal functionality required to run vGPU guest VMs. For security-sensitive environments such as cloud infrastructure, it's important to continue support for running a minimal footprint vGPU host driver in a stripped-down / barebones kernel environment. This can be achieved by supporting both VFIO and DRM drivers as clients of a core driver, without requiring a full-fledged DRM driver (or the DRM subsystem itself) to be built into the host kernel. A core driver would be responsible for booting and communicating with GSP-RM, enumeration of HW configuration, shared/partitioned resource management, exception handling, and event dispatch. The DRM driver would do all the standard things a DRM driver does, and implement GPU memory management (TTM/HMM), KMS, command submission etc, as well as providing UAPI for userspace clients. These features would be implemented using HW resources allocated from a core driver, rather than the DRM driver being directly responsible for HW programming. As Nouveau's KMD is already split (in the logical sense) along similar lines, we're using it here for the purposes of this RFC to demonstrate the feasibility of such an architecture, and open it up for discussion. Sounds reasonable. Only bikeshed I have to add is that the blessed way (according to the cool kernel maintainers at least or something) to structure this is using auxbus. Definitely when you end up with more than one driver binding to the core (like maybe some system management interface thing, or perhaps a special compute-only kernel driver). https://dri.freedesktop.org/docs/drm/driver-api/auxiliary_bus.html Hey! Yes indeed. I sent this[1] series at the same time, which was initially written to so that nouveau.ko would still get auto-loaded alongside nvkm.ko. Ben. [1] https://lists.freedesktop.org/archives/nouveau/2024-June/044861.html Cheers, Sima A link[2] to a tree containing the patches is below. [1] https://lore.kernel.org/all/3ed356488c9b0ca93845501425d427309f4cf616.ca...@redhat.com/ [2] https://gitlab.freedesktop.org/bskeggs/nouveau/-/tree/00.03-module *** BLURB HERE *** Ben Skeggs (2): drm/nouveau/nvkm: export symbols needed by the drm driver drm/nouveau/nvkm: separate out into nvkm.ko drivers/gpu/drm/nouveau/Kbuild | 4 ++-- drivers/gpu/drm/nouveau/include/nvkm/core/module.h | 3 --- drivers/gpu/drm/nouveau/nouveau_drm.c | 10 +- drivers/gpu/drm/nouveau/nvkm/core/driver.c | 1 + drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/core/mm.c | 4 drivers/gpu/drm/nouveau/nvkm/device/acpi.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c | 1 + drivers/gpu/drm/nouveau/nvkm/module.c | 8 ++-- drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c | 3 +++ drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c | 3 +++ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c| 1 + drivers/gpu/drm/nouveau/nvkm/subdev/therm/fan.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c | 1 + 19 files changed, 33 insertions(+), 16 deletions(-) -- 2.44.0
Re: [PATCH] nouveau: rip out busy fence waits
On 17/4/24 15:40, Dave Airlie wrote: External email: Use caution opening links or attachments From: Dave Airlie I'm pretty sure this optimisation is actually not a great idea, and is racy with other things waiting for fences. Just nuke it, there should be no need to do fence waits in a busy CPU loop. Signed-off-by: Dave Airlie Reviewed-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c| 2 +- drivers/gpu/drm/nouveau/nouveau_chan.c | 2 +- drivers/gpu/drm/nouveau/nouveau_dmem.c | 2 +- drivers/gpu/drm/nouveau/nouveau_fence.c | 30 + drivers/gpu/drm/nouveau/nouveau_fence.h | 2 +- drivers/gpu/drm/nouveau/nouveau_gem.c | 2 +- 6 files changed, 6 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 8a30f5a0525b..a4e8f625fce6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -902,7 +902,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, * Without this the operation can timeout and we'll fallback to a * software copy, which might take several minutes to finish. */ - nouveau_fence_wait(fence, false, false); + nouveau_fence_wait(fence, false); ret = ttm_bo_move_accel_cleanup(bo, &fence->base, evict, false, new_reg); nouveau_fence_unref(&fence); diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 7c97b2886807..66fca95c10c7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -72,7 +72,7 @@ nouveau_channel_idle(struct nouveau_channel *chan) ret = nouveau_fence_new(&fence, chan); if (!ret) { - ret = nouveau_fence_wait(fence, false, false); + ret = nouveau_fence_wait(fence, false); nouveau_fence_unref(&fence); } diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c b/drivers/gpu/drm/nouveau/nouveau_dmem.c index 12feecf71e75..033a09cd3c8f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dmem.c +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c @@ -128,7 +128,7 @@ static void nouveau_dmem_page_free(struct page *page) static void nouveau_dmem_fence_done(struct nouveau_fence **fence) { if (fence) { - nouveau_fence_wait(*fence, true, false); + nouveau_fence_wait(*fence, false); nouveau_fence_unref(fence); } else { /* diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index c3ea3cd933cd..8de941379324 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -312,39 +312,11 @@ nouveau_fence_wait_legacy(struct dma_fence *f, bool intr, long wait) return timeout - t; } -static int -nouveau_fence_wait_busy(struct nouveau_fence *fence, bool intr) -{ - int ret = 0; - - while (!nouveau_fence_done(fence)) { - if (time_after_eq(jiffies, fence->timeout)) { - ret = -EBUSY; - break; - } - - __set_current_state(intr ? - TASK_INTERRUPTIBLE : - TASK_UNINTERRUPTIBLE); - - if (intr && signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - } - - __set_current_state(TASK_RUNNING); - return ret; -} - int -nouveau_fence_wait(struct nouveau_fence *fence, bool lazy, bool intr) +nouveau_fence_wait(struct nouveau_fence *fence, bool intr) { long ret; - if (!lazy) - return nouveau_fence_wait_busy(fence, intr); - ret = dma_fence_wait_timeout(&fence->base, intr, 15 * HZ); if (ret < 0) return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h index bc13110bdfa4..88213014b675 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.h +++ b/drivers/gpu/drm/nouveau/nouveau_fence.h @@ -23,7 +23,7 @@ void nouveau_fence_unref(struct nouveau_fence **); int nouveau_fence_emit(struct nouveau_fence *); bool nouveau_fence_done(struct nouveau_fence *); -int nouveau_fence_wait(struct nouveau_fence *, bool lazy, bool intr); +int nouveau_fence_wait(struct nouveau_fence *, bool intr); int nouveau_fence_sync(struct nouveau_bo *, struct nouveau_channel *, bool exclusive, bool intr); struct nouveau_fence_chan { diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 49c2bcbef129..f715e381da69 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -928,7 +928,7 @@ nouv
[PATCH 08/21] drm/nouveau/nvkm: move vgaarb code from drm
Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_vga.c | 27 .../gpu/drm/nouveau/nvkm/subdev/pci/base.c| 32 +++ 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c index 83496af605a1..53b332708061 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vga.c +++ b/drivers/gpu/drm/nouveau/nouveau_vga.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: MIT -#include #include #include @@ -8,28 +7,6 @@ #include "nouveau_acpi.h" #include "nouveau_vga.h" -static unsigned int -nouveau_vga_set_decode(struct pci_dev *pdev, bool state) -{ - struct nouveau_drm *drm = pci_get_drvdata(pdev); - struct nvif_device *device = &drm->device; - - if (device->impl->family == NVIF_DEVICE_CURIE && - device->impl->chipset >= 0x4c) - nvif_wr32(device, 0x088060, state); - else - if (device->impl->chipset >= 0x40) - nvif_wr32(device, 0x088054, state); - else - nvif_wr32(device, 0x001854, state); - - if (state) - return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | - VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; - else - return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; -} - static void nouveau_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) @@ -94,8 +71,6 @@ nouveau_vga_init(struct nouveau_drm *drm) return; pdev = to_pci_dev(dev->dev); - vga_client_register(pdev, nouveau_vga_set_decode); - /* don't register Thunderbolt eGPU with vga_switcheroo */ if (pci_is_thunderbolt_attached(pdev)) return; @@ -118,8 +93,6 @@ nouveau_vga_fini(struct nouveau_drm *drm) return; pdev = to_pci_dev(dev->dev); - vga_client_unregister(pdev); - if (pci_is_thunderbolt_attached(pdev)) return; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c index 5a0de45d36ce..e4737b89cb63 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c @@ -27,6 +27,8 @@ #include #include +#include + void nvkm_pci_msi_rearm(struct nvkm_device *device) { @@ -62,6 +64,29 @@ 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; + + if (device->card_type == NV_40 && + device->chipset >= 0x4c) + nvkm_wr32(device, 0x088060, state); + else + if (device->chipset >= 0x40) + nvkm_wr32(device, 0x088054, state); + else + nvkm_wr32(device, 0x001854, state); + + if (state) + return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | + VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; + else + return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; +} + void nvkm_pci_rom_shadow(struct nvkm_pci *pci, bool shadow) { @@ -76,11 +101,16 @@ nvkm_pci_rom_shadow(struct nvkm_pci *pci, bool shadow) static int nvkm_pci_fini(struct nvkm_subdev *subdev, bool suspend) { + struct nvkm_device_pci *pdev = subdev->device->func->pci(subdev->device); struct nvkm_pci *pci = nvkm_pci(subdev); + if (!subdev->use.enabled) + return 0; + if (pci->agp.bridge) nvkm_agp_fini(pci); + vga_client_unregister(pdev->pdev); return 0; } @@ -111,6 +141,7 @@ nvkm_pci_oneinit(struct nvkm_subdev *subdev) static int nvkm_pci_init(struct nvkm_subdev *subdev) { + struct nvkm_device_pci *pdev = subdev->device->func->pci(subdev->device); struct nvkm_pci *pci = nvkm_pci(subdev); int ret; @@ -131,6 +162,7 @@ nvkm_pci_init(struct nvkm_subdev *subdev) if (pci->msi) pci->func->msi_rearm(pci); + vga_client_register(pdev->pdev, nvkm_pci_vga_set_decode); return 0; } -- 2.44.0
[RFC] GPU driver with separate "core" and "DRM" modules
NVIDIA has been exploring ways to better support the effort for an upstream kernel mode driver for GPUs that are capable of running GSP-RM firmware, since the introduction[1] to Nova. Use cases have been identified for which separating the core GPU programming out of the full DRM driver stack is a strong requirement from our key customers. An upstreamed NVIDIA GPU driver should be able to support current and emerging customer use cases for vGPU hosts. NVIDIA's vGPU deployments to date do not support compute or graphics functionality within the hypervisor host, and have no dependency on the Linux graphics subsystem, instead implementing the minimal functionality required to run vGPU guest VMs. For security-sensitive environments such as cloud infrastructure, it's important to continue support for running a minimal footprint vGPU host driver in a stripped-down / barebones kernel environment. This can be achieved by supporting both VFIO and DRM drivers as clients of a core driver, without requiring a full-fledged DRM driver (or the DRM subsystem itself) to be built into the host kernel. A core driver would be responsible for booting and communicating with GSP-RM, enumeration of HW configuration, shared/partitioned resource management, exception handling, and event dispatch. The DRM driver would do all the standard things a DRM driver does, and implement GPU memory management (TTM/HMM), KMS, command submission etc, as well as providing UAPI for userspace clients. These features would be implemented using HW resources allocated from a core driver, rather than the DRM driver being directly responsible for HW programming. As Nouveau's KMD is already split (in the logical sense) along similar lines, we're using it here for the purposes of this RFC to demonstrate the feasibility of such an architecture, and open it up for discussion. A link[2] to a tree containing the patches is below. [1] https://lore.kernel.org/all/3ed356488c9b0ca93845501425d427309f4cf616.ca...@redhat.com/ [2] https://gitlab.freedesktop.org/bskeggs/nouveau/-/tree/00.03-module *** BLURB HERE *** Ben Skeggs (2): drm/nouveau/nvkm: export symbols needed by the drm driver drm/nouveau/nvkm: separate out into nvkm.ko drivers/gpu/drm/nouveau/Kbuild | 4 ++-- drivers/gpu/drm/nouveau/include/nvkm/core/module.h | 3 --- drivers/gpu/drm/nouveau/nouveau_drm.c | 10 +- drivers/gpu/drm/nouveau/nvkm/core/driver.c | 1 + drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/core/mm.c | 4 drivers/gpu/drm/nouveau/nvkm/device/acpi.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c | 1 + drivers/gpu/drm/nouveau/nvkm/module.c | 8 ++-- drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c | 3 +++ drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c | 3 +++ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c| 1 + drivers/gpu/drm/nouveau/nvkm/subdev/therm/fan.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c | 1 + 19 files changed, 33 insertions(+), 16 deletions(-) -- 2.44.0
[PATCH 14/21] drm/nouveau/nvkm: move pci probe() fb handoff from drm
Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/device.h | 1 + drivers/gpu/drm/nouveau/nouveau_drm.c | 5 - drivers/gpu/drm/nouveau/nvkm/device/base.c | 6 ++ drivers/gpu/drm/nouveau/nvkm/device/pci.c | 11 +++ 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index 3c11d3068ced..d8596fe0adea 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h @@ -89,6 +89,7 @@ struct nvkm_device_func { struct nvkm_device_tegra *(*tegra)(struct nvkm_device *); void *(*dtor)(struct nvkm_device *); int (*preinit)(struct nvkm_device *); + int (*oneinit)(struct nvkm_device *); int (*init)(struct nvkm_device *); void (*fini)(struct nvkm_device *, bool suspend); int (*irq)(struct nvkm_device *); diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 3f1f93fa7029..be31e8ea4fee 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -804,11 +804,6 @@ static int nouveau_drm_probe(struct pci_dev *pdev, device = pci_get_drvdata(pdev); - /* Remove conflicting drivers (vesafb, efifb etc). */ - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver_pci); - if (ret) - return ret; - pci_set_master(pdev); if (nouveau_atomic) diff --git a/drivers/gpu/drm/nouveau/nvkm/device/base.c b/drivers/gpu/drm/nouveau/nvkm/device/base.c index 1b76c2a60799..4f8298bf71ee 100644 --- a/drivers/gpu/drm/nouveau/nvkm/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/device/base.c @@ -2954,6 +2954,12 @@ nvkm_device_oneinit(struct nvkm_device *device) #undef NVKM_LAYOUT_INST #undef NVKM_LAYOUT_ONCE + if (device->func->oneinit) { + ret = device->func->oneinit(device); + if (ret) + goto done; + } + ret = nvkm_intr_install(device); done: if (ret) { diff --git a/drivers/gpu/drm/nouveau/nvkm/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/device/pci.c index 21ca094df54f..7d0ddc968246 100644 --- a/drivers/gpu/drm/nouveau/nvkm/device/pci.c +++ b/drivers/gpu/drm/nouveau/nvkm/device/pci.c @@ -26,6 +26,7 @@ #include "acpi.h" #include "priv.h" +#include #include struct nvkm_device_pci_device { @@ -1608,6 +1609,15 @@ nvkm_device_pci_preinit(struct nvkm_device *device) return 0; } +static int +nvkm_device_pci_oneinit(struct nvkm_device *device) +{ + struct nvkm_device_pci *pdev = nvkm_device_pci(device); + + /* Remove conflicting drivers (vesafb, efifb etc). */ + return aperture_remove_conflicting_pci_devices(pdev->pdev, "nvkm"); +} + static void * nvkm_device_pci_dtor(struct nvkm_device *device) { @@ -1621,6 +1631,7 @@ nvkm_device_pci_func = { .pci = nvkm_device_pci, .dtor = nvkm_device_pci_dtor, .preinit = nvkm_device_pci_preinit, + .oneinit = nvkm_device_pci_oneinit, .fini = nvkm_device_pci_fini, .irq = nvkm_device_pci_irq, .resource_addr = nvkm_device_pci_resource_addr, -- 2.44.0
[PATCH 16/21] drm/nouveau/nvkm: move pci probe() runpm quirk from drm
Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/include/nvkm/core/pci.h | 2 + drivers/gpu/drm/nouveau/nouveau_drm.c | 61 -- drivers/gpu/drm/nouveau/nouveau_drv.h | 2 - drivers/gpu/drm/nouveau/nvkm/device/pci.c | 62 +++ 4 files changed, 64 insertions(+), 63 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h b/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h index 0797225ab038..95deea8c65ff 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h @@ -7,6 +7,8 @@ struct nvkm_device_pci { struct nvkm_device device; struct pci_dev *pdev; + u8 old_pm_cap; + struct dev_pm_domain vga_pm_domain; }; diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 4bcfc2291c4d..76eddf172bb5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -731,63 +731,6 @@ nouveau_drm_device_new(const struct drm_driver *drm_driver, struct device *paren return ret ? ERR_PTR(ret) : drm; } -/* - * On some Intel PCIe bridge controllers doing a - * D0 -> D3hot -> D3cold -> D0 sequence causes Nvidia GPUs to not reappear. - * Skipping the intermediate D3hot step seems to make it work again. This is - * probably caused by not meeting the expectation the involved AML code has - * when the GPU is put into D3hot state before invoking it. - * - * This leads to various manifestations of this issue: - * - AML code execution to power on the GPU hits an infinite loop (as the - *code waits on device memory to change). - * - kernel crashes, as all PCI reads return -1, which most code isn't able - *to handle well enough. - * - * In all cases dmesg will contain at least one line like this: - * 'nouveau :01:00.0: Refused to change power state, currently in D3' - * followed by a lot of nouveau timeouts. - * - * In the \_SB.PCI0.PEG0.PG00._OFF code deeper down writes bit 0x80 to the not - * documented PCI config space register 0x248 of the Intel PCIe bridge - * controller (0x1901) in order to change the state of the PCIe link between - * the PCIe port and the GPU. There are alternative code paths using other - * registers, which seem to work fine (executed pre Windows 8): - * - 0xbc bit 0x20 (publicly available documentation claims 'reserved') - * - 0xb0 bit 0x10 (link disable) - * Changing the conditions inside the firmware by poking into the relevant - * addresses does resolve the issue, but it seemed to be ACPI private memory - * and not any device accessible memory at all, so there is no portable way of - * changing the conditions. - * On a XPS 9560 that means bits [0,3] on \CPEX need to be cleared. - * - * The only systems where this behavior can be seen are hybrid graphics laptops - * with a secondary Nvidia Maxwell, Pascal or Turing GPU. It's unclear whether - * this issue only occurs in combination with listed Intel PCIe bridge - * controllers and the mentioned GPUs or other devices as well. - * - * documentation on the PCIe bridge controller can be found in the - * "7th Generation Intel® Processor Families for H Platforms Datasheet Volume 2" - * Section "12 PCI Express* Controller (x16) Registers" - */ - -static void quirk_broken_nv_runpm(struct pci_dev *pdev) -{ - struct nouveau_drm *drm = pci_get_drvdata(pdev); - struct pci_dev *bridge = pci_upstream_bridge(pdev); - - if (!bridge || bridge->vendor != PCI_VENDOR_ID_INTEL) - return; - - switch (bridge->device) { - case 0x1901: - drm->old_pm_cap = pdev->pm_cap; - pdev->pm_cap = 0; - NV_INFO(drm, "Disabling PCI power management to avoid bug\n"); - break; - } -} - static int nouveau_drm_probe(struct pci_dev *pdev, const struct pci_device_id *pent) { @@ -822,7 +765,6 @@ static int nouveau_drm_probe(struct pci_dev *pdev, else drm_fbdev_ttm_setup(drm->dev, 32); - quirk_broken_nv_runpm(pdev); return 0; fail_drm: @@ -846,9 +788,6 @@ nouveau_drm_remove(struct pci_dev *pdev) { struct nouveau_drm *drm = pci_get_drvdata(pdev); - /* revert our workaround */ - if (drm->old_pm_cap) - pdev->pm_cap = drm->old_pm_cap; nouveau_drm_device_remove(drm); nvkm_device_pci_driver.remove(pdev); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index b44f0d408ccc..9ca0f6ab4359 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -218,8 +218,6 @@ struct nouveau_drm { */ struct mutex clients_lock; - u8 old_pm_cap; - struct { struct agp_bridge_data *bridge; u32 bas
[PATCH 17/21] drm/nouveau/nvkm: move pci pm ops from drm
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 --- 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 -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(); +
[PATCH 13/21] drm/nouveau/nvkm: move pci probe() defer from drm
Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drm.c | 3 --- drivers/gpu/drm/nouveau/nvkm/device/pci.c | 5 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 632635c16b88..3f1f93fa7029 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -795,9 +795,6 @@ static int nouveau_drm_probe(struct pci_dev *pdev, struct nouveau_drm *drm; int ret; - if (vga_switcheroo_client_probe_defer(pdev)) - return -EPROBE_DEFER; - /* We need to check that the chipset is supported before booting * fbdev off the hardware, as there's no way to put it back. */ diff --git a/drivers/gpu/drm/nouveau/nvkm/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/device/pci.c index be6433eab814..21ca094df54f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/device/pci.c +++ b/drivers/gpu/drm/nouveau/nvkm/device/pci.c @@ -26,6 +26,8 @@ #include "acpi.h" #include "priv.h" +#include + struct nvkm_device_pci_device { u16 device; const char *name; @@ -1648,6 +1650,9 @@ nvkm_device_pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) struct nvkm_device *device; int ret, bits; + if (vga_switcheroo_client_probe_defer(pci_dev)) + return -EPROBE_DEFER; + switch (pci_dev->vendor) { case 0x10de: pcid = nvkm_device_pci_10de; break; default: -- 2.44.0
[PATCH 10/21] drm/nouveau/nvif: add runpm supported flag to device impl
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 --- 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(-) diff --git a/drivers/gpu/drm/nouveau/include/nvif/driverif.h b/drivers/gpu/drm/nouveau/include/nvif/driverif.h index 638c72c1b580..e1d3ccc2128c 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/driverif.h +++ b/drivers/gpu/drm/nouveau/include/nvif/driverif.h @@ -538,6 +538,8 @@ struct nvif_device_impl { u64 ram_size; u64 ram_user; + bool runpm; + u64 (*time)(struct nvif_device_priv *); struct { diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index c9965934b0d5..3c11d3068ced 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h @@ -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 diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/module.h b/drivers/gpu/drm/nouveau/include/nvkm/core/module.h index 5cf80e4deb90..fc42ace93a1c 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/module.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/module.h @@ -5,4 +5,6 @@ int __init nvkm_init(void); void __exit nvkm_exit(void); + +extern int nvkm_runpm; #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 0ac17da04819..52c4c3f58799 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -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; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 52589d5eab63..c2014a29891c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -324,7 +324,7 @@ nouveau_drm_use_coherent_gpu_mapping(struct nouveau_drm *drm) int nouveau_pmops_suspend(struct dev
[PATCH 05/21] drm/nouveau/nvif: add nvif_driver_func for nvkm->drm callbacks
A later patch in this series will move the code that binds to a PCI/ Tegra device into NVKM, and requires a couple of callbacks to handle switcheroo, etc. nvif_event is generally used for NVKM->DRM callbacks, but these will need to be registered before nvif_event is ready. This patch replaces the event() function pointer that was passed to nvkm_driver_ctor() during init with a nvif_driver_func struct, that contains the existing event() callback. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/driverif.h| 4 drivers/gpu/drm/nouveau/include/nvif/event.h | 2 ++ drivers/gpu/drm/nouveau/include/nvkm/core/client.h | 3 +-- drivers/gpu/drm/nouveau/include/nvkm/core/device.h | 2 ++ drivers/gpu/drm/nouveau/nouveau_drm.c | 7 +++ drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + drivers/gpu/drm/nouveau/nvif/event.c | 9 + drivers/gpu/drm/nouveau/nvkm/core/client.c | 13 + drivers/gpu/drm/nouveau/nvkm/core/driver.c | 14 +- 9 files changed, 36 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvif/driverif.h b/drivers/gpu/drm/nouveau/include/nvif/driverif.h index 0476dd6621b5..638c72c1b580 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/driverif.h +++ b/drivers/gpu/drm/nouveau/include/nvif/driverif.h @@ -34,6 +34,10 @@ struct nvif_event_impl { int (*block)(struct nvif_event_priv *); }; +struct nvif_driver_func { + enum nvif_event_stat (*event)(u64 token, void *repv, u32 repc); +}; + struct nvif_driver { const char *name; int (*suspend)(struct nvif_client_priv *); diff --git a/drivers/gpu/drm/nouveau/include/nvif/event.h b/drivers/gpu/drm/nouveau/include/nvif/event.h index 6c52de0e17d0..ce14e478b1fe 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/event.h +++ b/drivers/gpu/drm/nouveau/include/nvif/event.h @@ -5,6 +5,8 @@ #include struct nvif_event; +enum nvif_event_stat nvif_event(u64 token, void *repv, u32 repc); + typedef enum nvif_event_stat (*nvif_event_func)(struct nvif_event *, void *repv, u32 repc); struct nvif_event { diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h index 5c9a54d4bd64..4e5d56056b81 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h @@ -14,10 +14,9 @@ struct nvkm_client { spinlock_t obj_lock; void *data; - int (*event)(u64 token, void *argv, u32 argc); }; -int nvkm_client_new(const char *name, struct nvkm_device *, int (*event)(u64, void *, u32), +int nvkm_client_new(const char *name, struct nvkm_device *, const struct nvif_client_impl **, struct nvif_client_priv **); int nvkm_client_event(struct nvkm_client *client, u64 token, void *repv, u32 repc); diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index fff0d7dd0e1b..c9965934b0d5 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h @@ -71,6 +71,8 @@ struct nvkm_device { bool armed; bool legacy_done; } intr; + + const struct nvif_driver_func *driver; }; struct nvkm_subdev *nvkm_device_subdev(struct nvkm_device *, int type, int inst); diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 18990d21dc48..09947790f677 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -614,6 +614,11 @@ nouveau_drm_device_init(struct nouveau_drm *drm) return ret; } +static const struct nvif_driver_func +nouveau_driver = { + .event = nvif_event, +}; + static void nouveau_drm_device_del(struct nouveau_drm *drm) { @@ -643,9 +648,11 @@ nouveau_drm_device_new(const struct drm_driver *drm_driver, struct device *paren return ERR_PTR(-ENOMEM); drm->nvkm = device; + drm->driver = nouveau_driver; device->cfgopt = nouveau_config; device->dbgopt = nouveau_debug; + device->driver = &drm->driver; nvif_parent_ctor(&nouveau_parent, &drm->parent); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 832651fe9f42..52589d5eab63 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -202,6 +202,7 @@ u_memcpya(uint64_t user, unsigned int nmemb, unsigned int size) struct nouveau_drm { struct nvkm_device *nvkm; + struct nvif_driver_func driver; struct nvif_parent parent; struct nvif_client client; struct nvif_device device; diff --git a/drivers/gpu/drm/nouveau/nvif/event.c b/drivers/gpu/drm/nouveau/nvif/event.c index 2974ec8e13af..816e3d1bedb4 100644 --- a/driver
[PATCH 15/21] drm/nouveau/nvkm: move pci probe() enable/disable handling from drm
Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/include/nvkm/core/pci.h | 1 - drivers/gpu/drm/nouveau/nouveau_drm.c | 11 +--- drivers/gpu/drm/nouveau/nvkm/device/pci.c | 28 ++- 3 files changed, 3 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h b/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h index b9e10dad6ee9..0797225ab038 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h @@ -6,7 +6,6 @@ struct nvkm_device_pci { struct nvkm_device device; struct pci_dev *pdev; - bool suspend; struct dev_pm_domain vga_pm_domain; }; diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index be31e8ea4fee..4bcfc2291c4d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -804,8 +804,6 @@ static int nouveau_drm_probe(struct pci_dev *pdev, device = pci_get_drvdata(pdev); - pci_set_master(pdev); - if (nouveau_atomic) driver_pci.driver_features |= DRIVER_ATOMIC; @@ -815,13 +813,9 @@ static int nouveau_drm_probe(struct pci_dev *pdev, goto fail_nvkm; } - ret = pci_enable_device(pdev); - if (ret) - goto fail_drm; - ret = nouveau_drm_device_init(drm); if (ret) - goto fail_pci; + goto fail_drm; if (drm->device.impl->ram_size <= 32 * 1024 * 1024) drm_fbdev_ttm_setup(drm->dev, 8); @@ -831,8 +825,6 @@ static int nouveau_drm_probe(struct pci_dev *pdev, quirk_broken_nv_runpm(pdev); return 0; -fail_pci: - pci_disable_device(pdev); fail_drm: nouveau_drm_device_del(drm); fail_nvkm: @@ -858,7 +850,6 @@ nouveau_drm_remove(struct pci_dev *pdev) if (drm->old_pm_cap) pdev->pm_cap = drm->old_pm_cap; nouveau_drm_device_remove(drm); - pci_disable_device(pdev); nvkm_device_pci_driver.remove(pdev); } diff --git a/drivers/gpu/drm/nouveau/nvkm/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/device/pci.c index 7d0ddc968246..d9b8e3bc4169 100644 --- a/drivers/gpu/drm/nouveau/nvkm/device/pci.c +++ b/drivers/gpu/drm/nouveau/nvkm/device/pci.c @@ -1585,30 +1585,6 @@ nvkm_device_pci_irq(struct nvkm_device *device) return nvkm_device_pci(device)->pdev->irq; } -static void -nvkm_device_pci_fini(struct nvkm_device *device, bool suspend) -{ - struct nvkm_device_pci *pdev = nvkm_device_pci(device); - if (suspend) { - pci_disable_device(pdev->pdev); - pdev->suspend = true; - } -} - -static int -nvkm_device_pci_preinit(struct nvkm_device *device) -{ - struct nvkm_device_pci *pdev = nvkm_device_pci(device); - if (pdev->suspend) { - int ret = pci_enable_device(pdev->pdev); - if (ret) - return ret; - pci_set_master(pdev->pdev); - pdev->suspend = false; - } - return 0; -} - static int nvkm_device_pci_oneinit(struct nvkm_device *device) { @@ -1630,9 +1606,7 @@ static const struct nvkm_device_func nvkm_device_pci_func = { .pci = nvkm_device_pci, .dtor = nvkm_device_pci_dtor, - .preinit = nvkm_device_pci_preinit, .oneinit = nvkm_device_pci_oneinit, - .fini = nvkm_device_pci_fini, .irq = nvkm_device_pci_irq, .resource_addr = nvkm_device_pci_resource_addr, .resource_size = nvkm_device_pci_resource_size, @@ -1700,6 +1674,8 @@ nvkm_device_pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) return ret; } + pci_set_master(pci_dev); + ret = nvkm_device_ctor(&nvkm_device_pci_func, quirk, &pci_dev->dev, pci_is_pcie(pci_dev) ? NVKM_DEVICE_PCIE : pci_find_capability(pci_dev, PCI_CAP_ID_AGP) ? -- 2.44.0
[PATCH 07/21] drm/nouveau/nvkm: cleanup in nvkm_device_{pci, tegra}_new() on failure
These previously depended on the caller calling nvkm_device_del() to cleanup if nvkm_device_*_new() fails. That's a little odd for starters, but only the Tegra path cleaned up, and the PCI path would have leaked the memory, FWs etc that had been allocated as NVKM ran each subdev's ctor(). A later patch turns these into pci/platform driver probe() functions, so they need to learn how to clean up after themselves regardless. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drm.c | 2 +- drivers/gpu/drm/nouveau/nvkm/device/pci.c | 26 ++--- drivers/gpu/drm/nouveau/nvkm/device/tegra.c | 11 + 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 0bf39b05926f..6c1cfc38d8fa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -1351,7 +1351,7 @@ nouveau_platform_device_create(const struct nvkm_device_tegra_func *func, err = nvkm_device_tegra_new(func, pdev, nouveau_config, nouveau_debug, pdevice); if (err) - goto err_free; + return ERR_PTR(err); drm = nouveau_drm_device_new(&driver_platform, &pdev->dev, *pdevice); if (IS_ERR(drm)) { diff --git a/drivers/gpu/drm/nouveau/nvkm/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/device/pci.c index 8bfedd79d7a5..e48f3219f047 100644 --- a/drivers/gpu/drm/nouveau/nvkm/device/pci.c +++ b/drivers/gpu/drm/nouveau/nvkm/device/pci.c @@ -1633,12 +1633,9 @@ nvkm_device_pci_new(struct pci_dev *pci_dev, const char *cfg, const char *dbg, const struct nvkm_device_pci_vendor *pciv; const char *name = NULL; struct nvkm_device_pci *pdev; + struct nvkm_device *device; int ret, bits; - ret = pci_enable_device(pci_dev); - if (ret) - return ret; - switch (pci_dev->vendor) { case 0x10de: pcid = nvkm_device_pci_10de; break; default: @@ -1664,12 +1661,16 @@ nvkm_device_pci_new(struct pci_dev *pci_dev, const char *cfg, const char *dbg, pcid++; } - if (!(pdev = kzalloc(sizeof(*pdev), GFP_KERNEL))) { - pci_disable_device(pci_dev); + if (!(pdev = kzalloc(sizeof(*pdev), GFP_KERNEL))) return -ENOMEM; - } - *pdevice = &pdev->device; pdev->pdev = pci_dev; + device = &pdev->device; + + ret = pci_enable_device(pci_dev); + if (ret) { + kfree(pdev); + return ret; + } ret = nvkm_device_ctor(&nvkm_device_pci_func, quirk, &pci_dev->dev, pci_is_pcie(pci_dev) ? NVKM_DEVICE_PCIE : @@ -1682,7 +1683,7 @@ nvkm_device_pci_new(struct pci_dev *pci_dev, const char *cfg, const char *dbg, &pdev->device); if (ret) - return ret; + goto done; /* Set DMA mask based on capabilities reported by the MMU subdev. */ if (pdev->device.mmu && !pdev->device.pci->agp.bridge) @@ -1696,5 +1697,12 @@ nvkm_device_pci_new(struct pci_dev *pci_dev, const char *cfg, const char *dbg, pdev->device.mmu->dma_bits = 32; } +done: + if (ret) { + nvkm_device_del(&device); + return ret; + } + + *pdevice = &pdev->device; return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/device/tegra.c index bb514ccdfff4..9c3673c74b19 100644 --- a/drivers/gpu/drm/nouveau/nvkm/device/tegra.c +++ b/drivers/gpu/drm/nouveau/nvkm/device/tegra.c @@ -240,6 +240,7 @@ nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func, struct nvkm_device **pdevice) { struct nvkm_device_tegra *tdev; + struct nvkm_device *device; unsigned long rate; int ret; @@ -248,6 +249,7 @@ nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func, tdev->func = func; tdev->pdev = pdev; + device = &tdev->device; if (func->require_vdd) { tdev->vdd = devm_regulator_get(&pdev->dev, "vdd"); @@ -311,15 +313,14 @@ nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func, ret = nvkm_device_ctor(&nvkm_device_tegra_func, NULL, &pdev->dev, NVKM_DEVICE_TEGRA, pdev->id, NULL, &tdev->device); - if (ret) - goto powerdown; + if (ret) { + nvkm_device_del(&device); + return ret; + } *pdevice = &tdev->device; - return 0; -powerdown: - nvkm_device_tegra_power_down(tdev); remove: nvkm_device_tegra_remove_iommu(tdev); free: -- 2.44.0
[PATCH 04/21] drm/nouveau/nvif: add nvif_event_stat
Return an enum rather than an int from nvif_event callbacks. Also moves the NVIF_EVENT_* definitions to driverif.h, with the rest of the DRM<->NVKM interfaces. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv04/crtc.c | 4 ++-- drivers/gpu/drm/nouveau/dispnv04/disp.h | 2 +- drivers/gpu/drm/nouveau/dispnv50/head.c | 2 +- drivers/gpu/drm/nouveau/include/nvif/driverif.h | 5 + drivers/gpu/drm/nouveau/include/nvif/event.h| 5 ++--- drivers/gpu/drm/nouveau/nouveau_chan.c | 2 +- drivers/gpu/drm/nouveau/nouveau_connector.c | 4 ++-- drivers/gpu/drm/nouveau/nouveau_fence.c | 2 +- drivers/gpu/drm/nouveau/nouveau_svm.c | 2 +- 9 files changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c index 225716d47c56..d7575ece9214 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c @@ -1072,7 +1072,7 @@ nv04_finish_page_flip(struct nouveau_channel *chan, return 0; } -int +enum nvif_event_stat nv04_flip_complete(struct nvif_event *event, void *argv, u32 argc) { struct nv04_display *disp = container_of(event, typeof(*disp), flip); @@ -1272,7 +1272,7 @@ static const struct drm_plane_funcs nv04_primary_plane_funcs = { DRM_PLANE_NON_ATOMIC_FUNCS, }; -static int +static enum nvif_event_stat nv04_crtc_vblank_handler(struct nvif_event *event, void *repv, u32 repc) { struct nouveau_crtc *nv_crtc = container_of(event, struct nouveau_crtc, vblank); diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.h b/drivers/gpu/drm/nouveau/dispnv04/disp.h index 8eba76ab880e..88df31b6ac6b 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/disp.h +++ b/drivers/gpu/drm/nouveau/dispnv04/disp.h @@ -182,5 +182,5 @@ nouveau_bios_run_init_table(struct drm_device *dev, u16 table, ); } -int nv04_flip_complete(struct nvif_event *, void *, u32); +enum nvif_event_stat nv04_flip_complete(struct nvif_event *, void *, u32); #endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c index 4ad117b01d69..fd7791540f6f 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head.c @@ -549,7 +549,7 @@ nvd9_head_func = { .late_register = nv50_head_late_register, }; -static int +static enum nvif_event_stat nv50_head_vblank_handler(struct nvif_event *event, void *repv, u32 repc) { struct nouveau_crtc *nv_crtc = container_of(event, struct nouveau_crtc, vblank); diff --git a/drivers/gpu/drm/nouveau/include/nvif/driverif.h b/drivers/gpu/drm/nouveau/include/nvif/driverif.h index 40f58a94c09a..0476dd6621b5 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/driverif.h +++ b/drivers/gpu/drm/nouveau/include/nvif/driverif.h @@ -23,6 +23,11 @@ struct nvif_cgrp_priv; struct nvif_chan_priv; struct nvif_engobj_priv; +enum nvif_event_stat { + NVIF_EVENT_KEEP, + NVIF_EVENT_DROP, +}; + struct nvif_event_impl { void (*del)(struct nvif_event_priv *); int (*allow)(struct nvif_event_priv *); diff --git a/drivers/gpu/drm/nouveau/include/nvif/event.h b/drivers/gpu/drm/nouveau/include/nvif/event.h index 42c2d0b5f66b..6c52de0e17d0 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/event.h +++ b/drivers/gpu/drm/nouveau/include/nvif/event.h @@ -2,11 +2,10 @@ #ifndef __NVIF_EVENT_H__ #define __NVIF_EVENT_H__ #include +#include struct nvif_event; -#define NVIF_EVENT_KEEP 0 -#define NVIF_EVENT_DROP 1 -typedef int (*nvif_event_func)(struct nvif_event *, void *repv, u32 repc); +typedef enum nvif_event_stat (*nvif_event_func)(struct nvif_event *, void *repv, u32 repc); struct nvif_event { const struct nvif_event_impl *impl; diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 3a17e30d6c49..6a2b7e21afbf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -47,7 +47,7 @@ nouveau_channel_kill(struct nouveau_channel *chan) nouveau_fence_context_kill(chan->fence, -ENODEV); } -static int +static enum nvif_event_stat nouveau_channel_killed(struct nvif_event *event, void *repv, u32 repc) { struct nouveau_channel *chan = container_of(event, typeof(*chan), kill); diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 7d9cba7bcb8f..e3071ea845e6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -1199,7 +1199,7 @@ nouveau_connector_hpd(struct nouveau_connector *nv_connector, u64 bits) spin_unlock_irqrestore(&drm->hpd_lock, flags); } -static int +static enum nvif_event_stat nouveau_connector_irq(struct nvif_event *event, void *repv, u32 repc) { struct nouveau_connector *nv_connector = container_of(event, typeof(*nv_connector),
[PATCH 2/2] drm/nouveau/nvkm: separate out into nvkm.ko
Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Kbuild | 4 ++-- drivers/gpu/drm/nouveau/include/nvkm/core/module.h | 3 --- drivers/gpu/drm/nouveau/nouveau_drm.c | 10 +- drivers/gpu/drm/nouveau/nvkm/module.c | 8 ++-- 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/nouveau/Kbuild b/drivers/gpu/drm/nouveau/Kbuild index cc471ab6a7ec..b62c6858fb7b 100644 --- a/drivers/gpu/drm/nouveau/Kbuild +++ b/drivers/gpu/drm/nouveau/Kbuild @@ -8,11 +8,11 @@ ccflags-y += -I $(NOUVEAU_PATH)/$(src) # NVKM - HW resource manager include $(src)/nvkm/Kbuild -nouveau-y := $(nvkm-y) +obj-$(CONFIG_DRM_NOUVEAU) += nvkm.o # NVIF - NVKM interface library (NVKM user interface also defined here) include $(src)/nvif/Kbuild -nouveau-y += $(nvif-y) +nouveau-y := $(nvif-y) # DRM - general ifdef CONFIG_X86 diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/module.h b/drivers/gpu/drm/nouveau/include/nvkm/core/module.h index fc42ace93a1c..d1ad6aae9911 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/module.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/module.h @@ -3,8 +3,5 @@ #define __NVKM_MODULE_H__ #include -int __init nvkm_init(void); -void __exit nvkm_exit(void); - extern int nvkm_runpm; #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 7e77e950eba2..4f55cd73d1b3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -1174,7 +1174,7 @@ static const struct dev_pm_ops nouveau_pm_ops = { static const struct auxiliary_device_id nouveau_drm_id_table[] = { - { .name = "nouveau.device" }, + { .name = "nvkm.device" }, {} }; @@ -1190,8 +1190,6 @@ nouveau_auxdrv = { static int __init nouveau_drm_init(void) { - int ret; - nouveau_display_options(); if (nouveau_modeset == -1) { @@ -1202,10 +1200,6 @@ nouveau_drm_init(void) if (!nouveau_modeset) return 0; - ret = nvkm_init(); - if (ret) - return ret; - nouveau_backlight_ctor(); return auxiliary_driver_register(&nouveau_auxdrv); @@ -1223,8 +1217,6 @@ nouveau_drm_exit(void) if (IS_ENABLED(CONFIG_DRM_NOUVEAU_SVM)) mmu_notifier_synchronize(); - - nvkm_exit(); } module_init(nouveau_drm_init); diff --git a/drivers/gpu/drm/nouveau/nvkm/module.c b/drivers/gpu/drm/nouveau/nvkm/module.c index c14dd7fa15c2..d0ae023cdc74 100644 --- a/drivers/gpu/drm/nouveau/nvkm/module.c +++ b/drivers/gpu/drm/nouveau/nvkm/module.c @@ -26,7 +26,7 @@ int nvkm_runpm = -1; -void __exit +static void __exit nvkm_exit(void) { #ifdef CONFIG_PCI @@ -39,7 +39,7 @@ nvkm_exit(void) #endif } -int __init +static int __init nvkm_init(void) { int ret; @@ -60,3 +60,7 @@ nvkm_init(void) return 0; } + +MODULE_LICENSE("GPL and additional rights"); +module_init(nvkm_init); +module_exit(nvkm_exit); -- 2.44.0
[PATCH 1/2] drm/nouveau/nvkm: export symbols needed by the drm driver
The primary interfaces to NVKM are through NVIF, but there are a small number of functions which are called directly. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/core/driver.c | 1 + drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/core/mm.c | 4 drivers/gpu/drm/nouveau/nvkm/device/acpi.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c | 3 +++ drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c | 3 +++ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c| 1 + drivers/gpu/drm/nouveau/nvkm/subdev/therm/fan.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c | 1 + 15 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/core/driver.c b/drivers/gpu/drm/nouveau/nvkm/core/driver.c index dcc5dc7f246e..d6e8117a2a74 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/driver.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/driver.c @@ -78,3 +78,4 @@ nvkm_driver_ctor(struct nvkm_device *device, const struct nvif_driver **pdrv, *pdrv = &nvkm_driver; return 0; } +EXPORT_SYMBOL(nvkm_driver_ctor); diff --git a/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c b/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c index d6de2b3ed2c3..a06ced74fb10 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c @@ -224,6 +224,7 @@ nvkm_gpuobj_del(struct nvkm_gpuobj **pgpuobj) *pgpuobj = NULL; } } +EXPORT_SYMBOL(nvkm_gpuobj_del); int nvkm_gpuobj_new(struct nvkm_device *device, u32 size, int align, bool zero, @@ -240,6 +241,7 @@ nvkm_gpuobj_new(struct nvkm_device *device, u32 size, int align, bool zero, nvkm_gpuobj_del(pgpuobj); return ret; } +EXPORT_SYMBOL(nvkm_gpuobj_new); /* the below is basically only here to support sharing the paged dma object * for PCI(E)GART on <=nv4x chipsets, and should *not* be expected to work diff --git a/drivers/gpu/drm/nouveau/nvkm/core/mm.c b/drivers/gpu/drm/nouveau/nvkm/core/mm.c index f78a06a6b2f1..c2a66cfe2a1e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/mm.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/mm.c @@ -81,6 +81,7 @@ nvkm_mm_free(struct nvkm_mm *mm, struct nvkm_mm_node **pthis) *pthis = NULL; } +EXPORT_SYMBOL(nvkm_mm_free); static struct nvkm_mm_node * region_head(struct nvkm_mm *mm, struct nvkm_mm_node *a, u32 size) @@ -156,6 +157,7 @@ nvkm_mm_head(struct nvkm_mm *mm, u8 heap, u8 type, u32 size_max, u32 size_min, return -ENOSPC; } +EXPORT_SYMBOL(nvkm_mm_head); static struct nvkm_mm_node * region_tail(struct nvkm_mm *mm, struct nvkm_mm_node *a, u32 size) @@ -278,6 +280,7 @@ nvkm_mm_init(struct nvkm_mm *mm, u8 heap, u32 offset, u32 length, u32 block) mm->heap_nodes++; return 0; } +EXPORT_SYMBOL(nvkm_mm_init); int nvkm_mm_fini(struct nvkm_mm *mm) @@ -305,3 +308,4 @@ nvkm_mm_fini(struct nvkm_mm *mm) mm->heap_nodes = 0; return 0; } +EXPORT_SYMBOL(nvkm_mm_fini); diff --git a/drivers/gpu/drm/nouveau/nvkm/device/acpi.c b/drivers/gpu/drm/nouveau/nvkm/device/acpi.c index ff8a3027c1bc..941e7d2a29a8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/device/acpi.c +++ b/drivers/gpu/drm/nouveau/nvkm/device/acpi.c @@ -109,6 +109,7 @@ void nvkm_acpi_switcheroo_set_powerdown(void) NOUVEAU_DSM_OPTIMUS_SET_POWERDOWN, &result); } +EXPORT_SYMBOL(nvkm_acpi_switcheroo_set_powerdown); /* * On some platforms, _DSM(nvkm_op_dsm_muid, func0) has special diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c index f5e68f09df76..151c10558c82 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c @@ -76,6 +76,7 @@ nvkm_gr_units(struct nvkm_gr *gr) return gr->func->units(gr); return 0; } +EXPORT_SYMBOL(nvkm_gr_units); int nvkm_gr_tlb_flush(struct nvkm_gr *gr) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c index b54f044c4483..3ac3dbc0c03a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c @@ -2317,6 +2317,7 @@ nvbios_exec(struct nvbios_init *init) init->nested--; return 0; } +EXPORT_SYMBOL(nvbios_exec); int nvbios_post(struct nvkm_subdev *subdev, bool execute) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c index 2ec84b8a3b3a..1cd5b1996489 100644 --- a/drivers/gpu/drm/nouv
[PATCH 09/21] drm/nouveau/nvkm: move switcheroo init from drm
Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_acpi.c | 344 - drivers/gpu/drm/nouveau/nouveau_acpi.h | 7 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 2 - drivers/gpu/drm/nouveau/nvkm/device/acpi.c | 339 +++- drivers/gpu/drm/nouveau/nvkm/device/acpi.h | 19 ++ drivers/gpu/drm/nouveau/nvkm/module.c | 3 + 6 files changed, 362 insertions(+), 352 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 8f0c69aad248..b9c43fe552c0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -2,55 +2,12 @@ #include #include #include -#include -#include #include #include #include "nouveau_drv.h" #include "nouveau_acpi.h" -#define NOUVEAU_DSM_LED 0x02 -#define NOUVEAU_DSM_LED_STATE 0x00 -#define NOUVEAU_DSM_LED_OFF 0x10 -#define NOUVEAU_DSM_LED_STAMINA 0x11 -#define NOUVEAU_DSM_LED_SPEED 0x12 - -#define NOUVEAU_DSM_POWER 0x03 -#define NOUVEAU_DSM_POWER_STATE 0x00 -#define NOUVEAU_DSM_POWER_SPEED 0x01 -#define NOUVEAU_DSM_POWER_STAMINA 0x02 - -#define NOUVEAU_DSM_OPTIMUS_CAPS 0x1A -#define NOUVEAU_DSM_OPTIMUS_FLAGS 0x1B - -#define NOUVEAU_DSM_OPTIMUS_POWERDOWN_PS3 (3 << 24) -#define NOUVEAU_DSM_OPTIMUS_NO_POWERDOWN_PS3 (2 << 24) -#define NOUVEAU_DSM_OPTIMUS_FLAGS_CHANGED (1) - -#define NOUVEAU_DSM_OPTIMUS_SET_POWERDOWN (NOUVEAU_DSM_OPTIMUS_POWERDOWN_PS3 | NOUVEAU_DSM_OPTIMUS_FLAGS_CHANGED) - -/* result of the optimus caps function */ -#define OPTIMUS_ENABLED (1 << 0) -#define OPTIMUS_STATUS_MASK (3 << 3) -#define OPTIMUS_STATUS_OFF (0 << 3) -#define OPTIMUS_STATUS_ON_ENABLED (1 << 3) -#define OPTIMUS_STATUS_PWR_STABLE (3 << 3) -#define OPTIMUS_DISPLAY_HOTPLUG (1 << 6) -#define OPTIMUS_CAPS_MASK (7 << 24) -#define OPTIMUS_DYNAMIC_PWR_CAP (1 << 24) - -#define OPTIMUS_AUDIO_CAPS_MASK (3 << 27) -#define OPTIMUS_HDA_CODEC_MASK (2 << 27) /* hda bios control */ - -static struct nouveau_dsm_priv { - bool dsm_detected; - bool optimus_detected; - bool optimus_flags_detected; - bool optimus_skip_dsm; - acpi_handle dhandle; -} nouveau_dsm_priv; - bool nouveau_is_optimus(void) { return nouveau_dsm_priv.optimus_detected; } @@ -59,307 +16,6 @@ bool nouveau_is_v1_dsm(void) { return nouveau_dsm_priv.dsm_detected; } -#ifdef CONFIG_VGA_SWITCHEROO -static const guid_t nouveau_dsm_muid = - GUID_INIT(0x9D95A0A0, 0x0060, 0x4D48, - 0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4); - -static const guid_t nouveau_op_dsm_muid = - GUID_INIT(0xA486D8F8, 0x0BDA, 0x471B, - 0xA7, 0x2B, 0x60, 0x42, 0xA6, 0xB5, 0xBE, 0xE0); - -static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *result) -{ - int i; - union acpi_object *obj; - char args_buff[4]; - union acpi_object argv4 = { - .buffer.type = ACPI_TYPE_BUFFER, - .buffer.length = 4, - .buffer.pointer = args_buff - }; - - /* ACPI is little endian, AABBCCDD becomes {DD,CC,BB,AA} */ - for (i = 0; i < 4; i++) - args_buff[i] = (arg >> i * 8) & 0xFF; - - *result = 0; - obj = acpi_evaluate_dsm_typed(handle, &nouveau_op_dsm_muid, 0x0100, - func, &argv4, ACPI_TYPE_BUFFER); - if (!obj) { - acpi_handle_info(handle, "failed to evaluate _DSM\n"); - return AE_ERROR; - } else { - if (obj->buffer.length == 4) { - *result |= obj->buffer.pointer[0]; - *result |= (obj->buffer.pointer[1] << 8); - *result |= (obj->buffer.pointer[2] << 16); - *result |= (obj->buffer.pointer[3] << 24); - } - ACPI_FREE(obj); - } - - return 0; -} - -/* - * On some platforms, _DSM(nouveau_op_dsm_muid, func0) has special - * requirements on the fourth parameter, so a private implementation - * instead of using acpi_check_dsm(). - */ -static int nouveau_dsm_get_optimus_functions(acpi_handle handle) -{ - int result; - - /* -* Function 0 returns a Buffer containing available functions. -* The args parameter is ignored for function 0, so just put 0 in it -*/ - if (nouveau_optimus_dsm(handle, 0, 0, &result)) - return 0; - - /* -* ACPI Spec v4 9.14.1: if bit 0 is zero, no function is supported. -* If the n-th bit is enabled, function n is supported -*/ - if (result & 1 && result & (1 << NOUVEAU_DSM_OPTIMUS_CAPS)) - return result; - return 0; -} - -static int nouveau_dsm(acpi_handle handle, int func, int ar
[PATCH 21/21] drm/nouveau/nvkm: s/nouveau/nvkm/ over code moved from drm
The move and renames were kept separate for cleaner diffs. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/device/acpi.c | 113 ++-- drivers/gpu/drm/nouveau/nvkm/device/acpi.h | 4 +- drivers/gpu/drm/nouveau/nvkm/device/pci.c | 8 +- drivers/gpu/drm/nouveau/nvkm/device/tegra.c | 6 +- 4 files changed, 64 insertions(+), 67 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/device/acpi.c b/drivers/gpu/drm/nouveau/nvkm/device/acpi.c index c4cbdf172499..ff8a3027c1bc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/device/acpi.c +++ b/drivers/gpu/drm/nouveau/nvkm/device/acpi.c @@ -32,9 +32,9 @@ #include #ifdef CONFIG_VGA_SWITCHEROO -struct nouveau_dsm_priv nouveau_dsm_priv = {}; +struct nvkm_dsm_priv nvkm_dsm_priv = {}; -static const guid_t nouveau_op_dsm_muid = +static const guid_t nvkm_op_dsm_muid = GUID_INIT(0xA486D8F8, 0x0BDA, 0x471B, 0xA7, 0x2B, 0x60, 0x42, 0xA6, 0xB5, 0xBE, 0xE0); @@ -60,7 +60,7 @@ static const guid_t nouveau_op_dsm_muid = #define OPTIMUS_AUDIO_CAPS_MASK (3 << 27) #define OPTIMUS_HDA_CODEC_MASK (2 << 27) /* hda bios control */ -static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *result) +static int nvkm_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *result) { int i; union acpi_object *obj; @@ -76,7 +76,7 @@ static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t * args_buff[i] = (arg >> i * 8) & 0xFF; *result = 0; - obj = acpi_evaluate_dsm_typed(handle, &nouveau_op_dsm_muid, 0x0100, + obj = acpi_evaluate_dsm_typed(handle, &nvkm_op_dsm_muid, 0x0100, func, &argv4, ACPI_TYPE_BUFFER); if (!obj) { acpi_handle_info(handle, "failed to evaluate _DSM\n"); @@ -98,24 +98,24 @@ static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t * void nvkm_acpi_switcheroo_set_powerdown(void) { u32 result = 0; - if (!nouveau_dsm_priv.optimus_detected || nouveau_dsm_priv.optimus_skip_dsm) + if (!nvkm_dsm_priv.optimus_detected || nvkm_dsm_priv.optimus_skip_dsm) return; - if (nouveau_dsm_priv.optimus_flags_detected) - nouveau_optimus_dsm(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_OPTIMUS_FLAGS, - 0x3, &result); + if (nvkm_dsm_priv.optimus_flags_detected) + nvkm_optimus_dsm(nvkm_dsm_priv.dhandle, NOUVEAU_DSM_OPTIMUS_FLAGS, +0x3, &result); - nouveau_optimus_dsm(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_OPTIMUS_CAPS, - NOUVEAU_DSM_OPTIMUS_SET_POWERDOWN, &result); + nvkm_optimus_dsm(nvkm_dsm_priv.dhandle, NOUVEAU_DSM_OPTIMUS_CAPS, +NOUVEAU_DSM_OPTIMUS_SET_POWERDOWN, &result); } /* - * On some platforms, _DSM(nouveau_op_dsm_muid, func0) has special + * On some platforms, _DSM(nvkm_op_dsm_muid, func0) has special * requirements on the fourth parameter, so a private implementation * instead of using acpi_check_dsm(). */ -static int nouveau_dsm_get_optimus_functions(acpi_handle handle) +static int nvkm_dsm_get_optimus_functions(acpi_handle handle) { int result; @@ -123,7 +123,7 @@ static int nouveau_dsm_get_optimus_functions(acpi_handle handle) * Function 0 returns a Buffer containing available functions. * The args parameter is ignored for function 0, so just put 0 in it */ - if (nouveau_optimus_dsm(handle, 0, 0, &result)) + if (nvkm_optimus_dsm(handle, 0, 0, &result)) return 0; /* @@ -135,7 +135,7 @@ static int nouveau_dsm_get_optimus_functions(acpi_handle handle) return 0; } -static const guid_t nouveau_dsm_muid = +static const guid_t nvkm_dsm_muid = GUID_INIT(0x9D95A0A0, 0x0060, 0x4D48, 0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4); @@ -150,7 +150,7 @@ static const guid_t nouveau_dsm_muid = #define NOUVEAU_DSM_POWER_SPEED 0x01 #define NOUVEAU_DSM_POWER_STAMINA 0x02 -static int nouveau_dsm(acpi_handle handle, int func, int arg) +static int nvkm_dsm(acpi_handle handle, int func, int arg) { int ret = 0; union acpi_object *obj; @@ -159,7 +159,7 @@ static int nouveau_dsm(acpi_handle handle, int func, int arg) .integer.value = arg, }; - obj = acpi_evaluate_dsm_typed(handle, &nouveau_dsm_muid, 0x0102, + obj = acpi_evaluate_dsm_typed(handle, &nvkm_dsm_muid, 0x0102, func, &argv4, ACPI_TYPE_INTEGER); if (!obj) { acpi_handle_info(handle, "failed to evaluate _DSM\n"); @@ -173,21 +173,21 @@ static int nouveau_dsm(acpi_handle handle, int func, int arg) return ret; } -static int nouveau_dsm_switch_m
[PATCH 19/21] drm/nouveau: wrap pm_runtime_* calls with nouveau_runpm
This wraps direct calls to pm_runtime functions to cleanup some common usage patterns, and keep the logic in one place. >From the next commit, the pm_runtime calls will need to operate against the DRM driver's auxiliary device instead of directly on the underlying PCI device. This commit will help make that switch cleaner. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 31 --- drivers/gpu/drm/nouveau/nouveau_connector.c | 12 ++- drivers/gpu/drm/nouveau/nouveau_connector.h | 1 + drivers/gpu/drm/nouveau/nouveau_debugfs.c | 24 +++--- drivers/gpu/drm/nouveau/nouveau_display.c | 19 ++--- drivers/gpu/drm/nouveau/nouveau_drm.c | 45 --- drivers/gpu/drm/nouveau/nouveau_gem.c | 30 +++ drivers/gpu/drm/nouveau/nouveau_runpm.h | 89 + 8 files changed, 156 insertions(+), 95 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nouveau_runpm.h diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 64f3a1b00173..c0fc5233ebd4 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -952,17 +952,16 @@ static int nv50_mstc_detect(struct drm_connector *connector, struct drm_modeset_acquire_ctx *ctx, bool force) { + struct nouveau_drm *drm = nouveau_drm(connector->dev); struct nv50_mstc *mstc = nv50_mstc(connector); int ret; if (drm_connector_is_unregistered(connector)) return connector_status_disconnected; - ret = pm_runtime_get_sync(connector->dev->dev); - if (ret < 0 && ret != -EACCES) { - pm_runtime_put_autosuspend(connector->dev->dev); + ret = nouveau_runpm_get(drm); + if (ret) return connector_status_disconnected; - } ret = drm_dp_mst_detect_port(connector, ctx, mstc->port->mgr, mstc->port); @@ -970,8 +969,7 @@ nv50_mstc_detect(struct drm_connector *connector, goto out; out: - pm_runtime_mark_last_busy(connector->dev->dev); - pm_runtime_put_autosuspend(connector->dev->dev); + nouveau_runpm_put(drm); return ret; } @@ -1950,7 +1948,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) asyh->clr.mask, asyh->set.mask); if (old_crtc_state->active && !new_crtc_state->active) { - pm_runtime_put_noidle(dev->dev); + nouveau_runpm_put_noidle(drm); drm_crtc_vblank_off(crtc); } @@ -2040,7 +2038,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) if (new_crtc_state->active) { if (!old_crtc_state->active) { drm_crtc_vblank_on(crtc); - pm_runtime_get_noresume(dev->dev); + nouveau_runpm_get_noresume(drm); } if (new_crtc_state->event) drm_crtc_vblank_get(crtc); @@ -2159,8 +2157,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) drm_atomic_state_put(state); /* Drop the RPM ref we got from nv50_disp_atomic_commit() */ - pm_runtime_mark_last_busy(dev->dev); - pm_runtime_put_autosuspend(dev->dev); + nouveau_runpm_put(drm); } static void @@ -2175,15 +2172,14 @@ static int nv50_disp_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state, bool nonblock) { + struct nouveau_drm *drm = nouveau_drm(dev); struct drm_plane_state *new_plane_state; struct drm_plane *plane; int ret, i; - ret = pm_runtime_get_sync(dev->dev); - if (ret < 0 && ret != -EACCES) { - pm_runtime_put_autosuspend(dev->dev); + ret = nouveau_runpm_get(drm); + if (ret) return ret; - } ret = drm_atomic_helper_setup_commit(state, nonblock); if (ret) @@ -2219,7 +2215,7 @@ nv50_disp_atomic_commit(struct drm_device *dev, * Grab another RPM ref for the commit tail, which will release the * ref when it's finished */ - pm_runtime_get_noresume(dev->dev); + nouveau_runpm_get_noresume(drm); if (nonblock) queue_work(system_unbound_wq, &state->commit_work); @@ -2230,7 +2226,7 @@ nv50_disp_atomic_commit(struct drm_device *dev, if (ret) drm_atomic_helper_unprepare_planes(dev, state); done: - pm_runtime_put_autosuspend(dev->dev); + nouveau_runpm_put(drm); return ret; } @@ -2439,6 +2435,7 @@ static inline void nv50_display_read_hw_or_state(struct drm_device *dev, struc
[PATCH 11/21] drm/nouveau/nvkm: move switcheroo from drm
The DRM driver needs to do things in response to vga_switcheroo_client callbacks, so this move isn't a direct copy+paste. 3 new callbacks are added to nvif_driver_func, which are basically the same as the switcheroo callbacks, except NVKM handles all the PCI/ACPI parts, and calls into the DRM driver for the rest. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/include/nvif/driverif.h | 7 ++ .../gpu/drm/nouveau/include/nvkm/core/pci.h | 2 + drivers/gpu/drm/nouveau/nouveau_acpi.c| 8 -- drivers/gpu/drm/nouveau/nouveau_acpi.h| 4 - drivers/gpu/drm/nouveau/nouveau_drm.c | 5 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 2 - drivers/gpu/drm/nouveau/nouveau_vga.c | 71 +++- drivers/gpu/drm/nouveau/nouveau_vga.h | 3 +- drivers/gpu/drm/nouveau/nvkm/device/acpi.c| 83 ++- 9 files changed, 104 insertions(+), 81 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvif/driverif.h b/drivers/gpu/drm/nouveau/include/nvif/driverif.h index e1d3ccc2128c..49db239f1156 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/driverif.h +++ b/drivers/gpu/drm/nouveau/include/nvif/driverif.h @@ -2,6 +2,7 @@ #ifndef __NVIF_DRIVERIF_H__ #define __NVIF_DRIVERIF_H__ #include +#include struct nvif_event_priv; struct nvif_client_priv; @@ -36,6 +37,12 @@ struct nvif_event_impl { struct nvif_driver_func { enum nvif_event_stat (*event)(u64 token, void *repv, u32 repc); + + struct nvif_driver_func_switcheroo { + bool (*can_switch)(const struct nvif_driver_func *); + void (*set_state)(const struct nvif_driver_func *, enum vga_switcheroo_state); + void (*reprobe)(const struct nvif_driver_func *); + } switcheroo; }; struct nvif_driver { diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h b/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h index 7444c4d59e09..a1e9ee6da44e 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h @@ -7,6 +7,8 @@ struct nvkm_device_pci { struct nvkm_device device; struct pci_dev *pdev; bool suspend; + + struct dev_pm_domain vga_pm_domain; }; int nvkm_device_pci_new(struct pci_dev *, const char *cfg, const char *dbg, diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index b9c43fe552c0..da3120258527 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -8,14 +8,6 @@ #include "nouveau_drv.h" #include "nouveau_acpi.h" -bool nouveau_is_optimus(void) { - return nouveau_dsm_priv.optimus_detected; -} - -bool nouveau_is_v1_dsm(void) { - return nouveau_dsm_priv.dsm_detected; -} - void * nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.h b/drivers/gpu/drm/nouveau/nouveau_acpi.h index a7fac1f7a73d..be1b218cb921 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.h +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.h @@ -5,16 +5,12 @@ #define ROM_BIOS_PAGE 4096 #if defined(CONFIG_ACPI) && defined(CONFIG_X86) -bool nouveau_is_optimus(void); -bool nouveau_is_v1_dsm(void); #include 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 bool nouveau_is_optimus(void) { return false; }; -static inline bool nouveau_is_v1_dsm(void) { return false; }; 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; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 52c4c3f58799..580849b78231 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -505,7 +505,6 @@ nouveau_drm_device_fini(struct nouveau_drm *drm) nouveau_bios_takedown(dev); nouveau_ttm_fini(drm); - nouveau_vga_fini(drm); /* * There may be existing clients from as-yet unclosed files. For now, @@ -556,8 +555,6 @@ nouveau_drm_device_init(struct nouveau_drm *drm) if (drm->device.impl->chipset == 0xc1) nvif_mask(&drm->device, 0x00088080, 0x0800, 0x); - nouveau_vga_init(drm); - ret = nouveau_ttm_init(drm); if (ret) goto fail_ttm; @@ -608,7 +605,6 @@ nouveau_drm_device_init(struct nouveau_drm *drm) fail_bios: nouveau_ttm_fini(drm); fail_ttm: - nouveau_vga_fini(drm); nouveau_cli_fini(&drm->cli); fail_wq:
[PATCH 20/21] drm/nouveau: probe() against nvkm-provided auxiliary devices
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." 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 --- 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 #include #include -#include -#include #include #include @@ -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"
[PATCH 12/21] drm/nouveau/nvkm: prepare pci/tegra probe()/remove() functions
Rename, and modify the signatures of nvkm_device_{pci,tegra}_new() to be consistent with pci/platform driver probe() functions. The DRM driver is still calling the functions as it did before, just via the new pci/platform driver structs in NVKM that will eventually be used for driver registration. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/include/nvkm/core/pci.h | 3 +- .../gpu/drm/nouveau/include/nvkm/core/tegra.h | 5 +-- drivers/gpu/drm/nouveau/nouveau_drm.c | 13 --- drivers/gpu/drm/nouveau/nouveau_platform.c| 2 + drivers/gpu/drm/nouveau/nvkm/device/pci.c | 24 ++-- drivers/gpu/drm/nouveau/nvkm/device/tegra.c | 37 --- 6 files changed, 55 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h b/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h index a1e9ee6da44e..b9e10dad6ee9 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/pci.h @@ -11,6 +11,5 @@ struct nvkm_device_pci { struct dev_pm_domain vga_pm_domain; }; -int nvkm_device_pci_new(struct pci_dev *, const char *cfg, const char *dbg, - struct nvkm_device **); +extern struct pci_driver nvkm_device_pci_driver; #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h b/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h index 22f74fc88cd7..e641f387fa3e 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h @@ -48,8 +48,5 @@ struct nvkm_device_tegra_func { bool require_vdd; }; -int nvkm_device_tegra_new(const struct nvkm_device_tegra_func *, - struct platform_device *, - const char *cfg, const char *dbg, - struct nvkm_device **); +extern struct platform_driver nvkm_device_tegra; #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 580849b78231..632635c16b88 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -801,10 +801,12 @@ static int nouveau_drm_probe(struct pci_dev *pdev, /* 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_new(pdev, nouveau_config, nouveau_debug, &device); + ret = nvkm_device_pci_driver.probe(pdev, NULL); if (ret) return ret; + device = pci_get_drvdata(pdev); + /* Remove conflicting drivers (vesafb, efifb etc). */ ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver_pci); if (ret) @@ -849,13 +851,10 @@ static int nouveau_drm_probe(struct pci_dev *pdev, void nouveau_drm_device_remove(struct nouveau_drm *drm) { - struct nvkm_device *device = drm->nvkm; - drm_dev_unplug(drm->dev); nouveau_drm_device_fini(drm); nouveau_drm_device_del(drm); - nvkm_device_del(&device); } static void @@ -868,6 +867,8 @@ nouveau_drm_remove(struct pci_dev *pdev) pdev->pm_cap = drm->old_pm_cap; nouveau_drm_device_remove(drm); pci_disable_device(pdev); + + nvkm_device_pci_driver.remove(pdev); } static int @@ -1349,10 +1350,12 @@ nouveau_platform_device_create(const struct nvkm_device_tegra_func *func, struct nouveau_drm *drm; int err; - err = nvkm_device_tegra_new(func, pdev, nouveau_config, nouveau_debug, pdevice); + 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); diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.c b/drivers/gpu/drm/nouveau/nouveau_platform.c index 3194b110eff8..23beac1f96f1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_platform.c +++ b/drivers/gpu/drm/nouveau/nouveau_platform.c @@ -42,6 +42,8 @@ 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) diff --git a/drivers/gpu/drm/nouveau/nvkm/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/device/pci.c index 16e059866168..be6433eab814 100644 --- a/drivers/gpu/drm/nouveau/nvkm/device/pci.c +++ b/drivers/gpu/drm/nouveau/nvkm/device/pci.c @@ -1626,9 +1626,19 @@ nvkm_device_pci_func = { .cpu_coherent = !IS_ENABLED(CONFIG_ARM), }; -int -nvkm_device_pci_new(struct pci_dev *pci_dev, const char *cfg, const char *dbg, - struct nvkm_device **pdevice) +#include "nouveau_drv.h" + +static void +nvkm_device_pci_remove(struct p
[PATCH 01/21] drm/nouveau: fix a couple of KBuild comments
The NVIF/NVKM comments were backwards. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Kbuild | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/nouveau/Kbuild b/drivers/gpu/drm/nouveau/Kbuild index f99b7b227947..61eeef83847a 100644 --- a/drivers/gpu/drm/nouveau/Kbuild +++ b/drivers/gpu/drm/nouveau/Kbuild @@ -7,14 +7,12 @@ ccflags-y += -I $(NOUVEAU_PATH)/$(src)/nvkm ccflags-y += -I $(NOUVEAU_PATH)/$(src) # NVKM - HW resource manager -#- code also used by various userspace tools/tests -include $(src)/nvif/Kbuild -nouveau-y := $(nvif-y) +include $(src)/nvkm/Kbuild +nouveau-y := $(nvkm-y) # NVIF - NVKM interface library (NVKM user interface also defined here) -#- code also used by various userspace tools/tests -include $(src)/nvkm/Kbuild -nouveau-y += $(nvkm-y) +include $(src)/nvif/Kbuild +nouveau-y += $(nvif-y) # DRM - general ifdef CONFIG_X86 -- 2.44.0
[PATCH 18/21] drm/nouveau/nvkm: add device to auxiliary bus for each nvkm_device
This commit registers a device on the aux bus after core NVKM init has finished, which will be used by a later commit to have the DRM driver probe() against an aux device instead of a PCI or platform device (in the case of Tegra). Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Kconfig | 1 + .../drm/nouveau/include/nvkm/core/device.h| 3 ++ drivers/gpu/drm/nouveau/nvkm/device/base.c| 33 +++ 3 files changed, 37 insertions(+) diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index 4c10b400658c..6d0d46a0e66f 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -7,6 +7,7 @@ config DRM_NOUVEAU depends on DRM_DISPLAY_HELPER depends on PCI depends on MMU + select AUXILIARY_BUS select IOMMU_API select FW_LOADER select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index d8596fe0adea..855d1b20820d 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h @@ -5,6 +5,8 @@ #include enum nvkm_subdev_type; +#include + enum nvkm_device_type { NVKM_DEVICE_PCI, NVKM_DEVICE_AGP, @@ -78,6 +80,7 @@ struct nvkm_device { bool legacy_done; } intr; + struct auxiliary_device auxdev; const struct nvif_driver_func *driver; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/device/base.c b/drivers/gpu/drm/nouveau/nvkm/device/base.c index 4f8298bf71ee..fbb6e20bc1f2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/device/base.c @@ -3029,6 +3029,9 @@ nvkm_device_del(struct nvkm_device **pdevice) struct nvkm_device *device = *pdevice; struct nvkm_subdev *subdev, *subtmp; if (device) { + auxiliary_device_delete(&device->auxdev); + auxiliary_device_uninit(&device->auxdev); + nvkm_intr_dtor(device); list_for_each_entry_safe_reverse(subdev, subtmp, &device->subdev, head) @@ -3076,6 +3079,16 @@ nvkm_device_endianness(struct nvkm_device *device) return true; } +static DEFINE_IDA(nvkm_device_id); + +static void +nvkm_device_release(struct device *dev) +{ + struct nvkm_device *device = container_of(dev, typeof(*device), auxdev.dev); + + ida_free(&nvkm_device_id, device->auxdev.id); +} + int nvkm_device_ctor(const struct nvkm_device_func *func, const struct nvkm_device_quirk *quirk, @@ -3335,5 +3348,25 @@ nvkm_device_ctor(const struct nvkm_device_func *func, iounmap(device->pri); device->pri = NULL; } + + if (ret == 0) { + ret = ida_alloc(&nvkm_device_id, GFP_KERNEL); + if (ret < 0) + return ret; + + device->auxdev.dev.parent = device->dev; + device->auxdev.dev.release = nvkm_device_release; + device->auxdev.name = "device"; + device->auxdev.id = ret; + + ret = auxiliary_device_init(&device->auxdev); + if (ret) + return ret; + + ret = auxiliary_device_add(&device->auxdev); + if (ret) + auxiliary_device_uninit(&device->auxdev); + } + return ret; } -- 2.44.0
[PATCH 06/21] drm/nouveau/nvkm: add init()/exit()
Add stub init()/exit() functions that subsequent patches will use as they move the pci/platform-specific code out of the DRM driver. Signed-off-by: Ben Skeggs --- .../drm/nouveau/include/nvkm/core/module.h| 8 + drivers/gpu/drm/nouveau/nouveau_drm.c | 9 + drivers/gpu/drm/nouveau/nvkm/Kbuild | 3 ++ drivers/gpu/drm/nouveau/nvkm/core/Kbuild | 2 +- drivers/gpu/drm/nouveau/nvkm/module.c | 33 +++ 5 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/module.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/module.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/module.h b/drivers/gpu/drm/nouveau/include/nvkm/core/module.h new file mode 100644 index ..5cf80e4deb90 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/module.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_MODULE_H__ +#define __NVKM_MODULE_H__ +#include + +int __init nvkm_init(void); +void __exit nvkm_exit(void); +#endif diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 09947790f677..0bf39b05926f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -1375,6 +1376,8 @@ nouveau_platform_device_create(const struct nvkm_device_tegra_func *func, static int __init nouveau_drm_init(void) { + int ret; + driver_pci = driver_stub; driver_platform = driver_stub; @@ -1388,6 +1391,10 @@ nouveau_drm_init(void) if (!nouveau_modeset) return 0; + ret = nvkm_init(); + if (ret) + return ret; + #ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER platform_driver_register(&nouveau_platform_driver); #endif @@ -1419,6 +1426,8 @@ nouveau_drm_exit(void) #endif if (IS_ENABLED(CONFIG_DRM_NOUVEAU_SVM)) mmu_notifier_synchronize(); + + nvkm_exit(); } module_init(nouveau_drm_init); diff --git a/drivers/gpu/drm/nouveau/nvkm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/Kbuild index f68c19586b53..9e1a6ab937e1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/Kbuild @@ -1,4 +1,7 @@ # SPDX-License-Identifier: MIT + +nvkm-y := nvkm/module.o + include $(src)/nvkm/core/Kbuild include $(src)/nvkm/nvfw/Kbuild include $(src)/nvkm/device/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/core/Kbuild b/drivers/gpu/drm/nouveau/nvkm/core/Kbuild index 50ff041ecdf0..70cec7bbb018 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/core/Kbuild @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MIT -nvkm-y := nvkm/core/client.o +nvkm-y += nvkm/core/client.o nvkm-y += nvkm/core/driver.o nvkm-y += nvkm/core/engine.o nvkm-y += nvkm/core/enum.o diff --git a/drivers/gpu/drm/nouveau/nvkm/module.c b/drivers/gpu/drm/nouveau/nvkm/module.c new file mode 100644 index ..66d28465514b --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/module.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024, 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 + +void __exit +nvkm_exit(void) +{ +} + +int __init +nvkm_init(void) +{ + return 0; +} -- 2.44.0
[PATCH 03/21] drm/nouveau/nvkm: add nvkm_client_event()
A later patch in this series moves the nvif_event callback function, but all the callers directly dereference object->client->event(). Add a helper function so this only has to be changed in one place. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/client.h | 1 + drivers/gpu/drm/nouveau/nvkm/core/client.c | 6 ++ drivers/gpu/drm/nouveau/nvkm/core/uevent.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c | 6 +++--- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h index 2da9dfbf0d56..5c9a54d4bd64 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h @@ -19,6 +19,7 @@ struct nvkm_client { int nvkm_client_new(const char *name, struct nvkm_device *, int (*event)(u64, void *, u32), const struct nvif_client_impl **, struct nvif_client_priv **); +int nvkm_client_event(struct nvkm_client *client, u64 token, void *repv, u32 repc); /* logging for client-facing objects */ #define nvif_printk(o,l,p,f,a...) do { \ diff --git a/drivers/gpu/drm/nouveau/nvkm/core/client.c b/drivers/gpu/drm/nouveau/nvkm/core/client.c index 6471edda8a96..beb966d65daf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/client.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/client.c @@ -31,6 +31,12 @@ #include #include +int +nvkm_client_event(struct nvkm_client *client, u64 token, void *repv, u32 repc) +{ + return client->event(token, repv, repc); +} + static int nvkm_client_new_device(struct nvif_client_priv *client, const struct nvif_device_impl **pimpl, struct nvif_device_priv **ppriv) diff --git a/drivers/gpu/drm/nouveau/nvkm/core/uevent.c b/drivers/gpu/drm/nouveau/nvkm/core/uevent.c index 365e41134f3d..fccf6477d3d1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/uevent.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/uevent.c @@ -111,7 +111,7 @@ nvkm_uevent_ntfy(struct nvkm_event_ntfy *ntfy, u32 bits) if (uevent->func) return uevent->func(uevent->parent, uevent->object.object, bits); - return client->event(uevent->object.object, NULL, 0); + return nvkm_client_event(client, uevent->object.object, NULL, 0); } int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c index 9c7b83c99b80..4284e7b924fc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c @@ -50,7 +50,7 @@ nvkm_uconn_uevent_gsp(struct nvkm_object *object, u64 token, u32 bits) if (bits & NVKM_DPYID_IRQ) args.v0.types |= NVIF_CONN_EVENT_V0_IRQ; - return object->client->event(token, &args, sizeof(args.v0)); + return nvkm_client_event(object->client, token, &args, sizeof(args.v0)); } static int @@ -67,7 +67,7 @@ nvkm_uconn_uevent_aux(struct nvkm_object *object, u64 token, u32 bits) if (bits & NVKM_I2C_IRQ) args.v0.types |= NVIF_CONN_EVENT_V0_IRQ; - return object->client->event(token, &args, sizeof(args.v0)); + return nvkm_client_event(object->client, token, &args, sizeof(args.v0)); } static int @@ -82,7 +82,7 @@ nvkm_uconn_uevent_gpio(struct nvkm_object *object, u64 token, u32 bits) if (bits & NVKM_GPIO_LO) args.v0.types |= NVIF_CONN_EVENT_V0_UNPLUG; - return object->client->event(token, &args, sizeof(args.v0)); + return nvkm_client_event(object->client, token, &args, sizeof(args.v0)); } static bool -- 2.44.0
[PATCH 02/21] drm/nouveau/nvkm: delay calling subdev ctor()'s until device oneinit()
A later patch in the series converts nvkm_device_{pci_tegra}_new into PCI/platform device probe functions, as a step towards moving all the PCI/Tegra-specific handling into NVKM. nouveau.ko has two module options (nouveau.config/nouveau.debug) that affect the behaviour of NVKM, however, and the probe() functions will not have access to these, which would break a user's configuration if they depend on any of the options to workaround a problem, etc. To avoid this, we delay calling constructors for each subdev (which could depend on module parameters) until allocation of the first nvif_device, which will allow the DRM driver a chance to override device.{cfg,dbg}opt before they're needed. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drm.c | 3 + drivers/gpu/drm/nouveau/nvkm/device/base.c | 112 drivers/gpu/drm/nouveau/nvkm/device/pci.c | 2 +- drivers/gpu/drm/nouveau/nvkm/device/priv.h | 3 +- drivers/gpu/drm/nouveau/nvkm/device/tegra.c | 2 +- 5 files changed, 71 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 965331e65fda..18990d21dc48 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -644,6 +644,9 @@ nouveau_drm_device_new(const struct drm_driver *drm_driver, struct device *paren drm->nvkm = device; + device->cfgopt = nouveau_config; + device->dbgopt = nouveau_debug; + nvif_parent_ctor(&nouveau_parent, &drm->parent); ret = nvkm_driver_ctor(device, &driver, &impl, &priv); diff --git a/drivers/gpu/drm/nouveau/nvkm/device/base.c b/drivers/gpu/drm/nouveau/nvkm/device/base.c index 20609571793e..1b76c2a60799 100644 --- a/drivers/gpu/drm/nouveau/nvkm/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/device/base.c @@ -2908,6 +2908,62 @@ nvkm_device_preinit(struct nvkm_device *device) return ret; } +static int +nvkm_device_oneinit(struct nvkm_device *device) +{ + struct nvkm_subdev *subdev, *subtmp; + int ret, j; + +#define NVKM_LAYOUT_ONCE(type,data,ptr) \ + if (device->chip->ptr.inst) { \ + WARN_ON(device->chip->ptr.inst != 0x0001); \ + ret = device->chip->ptr.ctor(device, (type), -1, &device->ptr); \ + subdev = nvkm_device_subdev(device, (type), 0); \ + if (ret) { \ + nvkm_subdev_del(&subdev); \ + device->ptr = NULL; \ + if (ret != -ENODEV) { \ + nvdev_error(device, "%s ctor failed: %d\n", \ + nvkm_subdev_type[(type)], ret); \ + goto done; \ + } \ + } else { \ + subdev->pself = (void **)&device->ptr; \ + } \ + } +#define NVKM_LAYOUT_INST(type,data,ptr,cnt) \ + WARN_ON(device->chip->ptr.inst & ~((1 << ARRAY_SIZE(device->ptr)) - 1)); \ + for (j = 0; device->chip->ptr.inst && j < ARRAY_SIZE(device->ptr); j++) {\ + if (device->chip->ptr.inst & BIT(j)) { \ + ret = device->chip->ptr.ctor(device, (type), (j), &device->ptr[j]); \ + subdev = nvkm_device_subdev(device, (type), (j)); \ + if (ret) { \ + nvkm_subdev_del(&subdev); \ + device->ptr[j] = NULL; \ + if (ret != -ENODEV) { \ + nvdev_error(device, "%s%d ctor fa
[PATCH 00/21] drm/nouveau: insert auxiliary device between nvkm and drm
This series was originally part of an RFC demonstrating NVKM and the DRM driver split into separate kernel modules, but it became apparent whilst working on this series that there's some benefit to making these changes regardless of a module split, so I'm sending them out separately. The bulk of the series moves the remaining bus-specific handling (PCI/ platform driver registation, power management, ACPI, etc) out of the DRM driver and into NVKM. As NVKM finishes probe() for a PCI or Tegra device, it will now register a device on the auxiliary bus, which the DRM driver will probe() against instead of devices from the PCI and platform buses directly. The result of this is a cleaner integration of support for Tegra GPUs in a codebase that originally assumed a PCI device everywhere. As the DRM driver mostly just operates on objects allocated from NVKM, support for Tegra wasn't *too* bad to integrate, but with NVKM handling some pieces, and the DRM driver handling others, the driver init paths were somewhat convoluted. With the bus-level device handling now entirely living within NVKM, the DRM driver's init paths for PCI and Tegra GPUs has been unified, which cleans up the remaining messy bits there. One unanticipated benefit that comes from utilising the auxiliary bus is that, on Optimus systems, it's no longer necessary to fully reinitialise the entire GPU (including time-consuming steps such as booting firmware, or restoring page tables to VRAM) in order to respond to simple queries of the underlying PCI device (ie. running lspci). Now, NVKM will only wake the PCI device itself when asked by the kernel, and because the remainder of GPU (re)initialisation is tied to clients' object trees, *and* the DRM device is still asleep, no other steps need to be taken, greatly reducing resume latency. A link to a tree containing the patches is below. [1] https://gitlab.freedesktop.org/bskeggs/nouveau/-/tree/00.02-auxdev Ben Skeggs (21): drm/nouveau: fix a couple of KBuild comments drm/nouveau/nvkm: delay calling subdev ctor()'s until device oneinit() drm/nouveau/nvkm: add nvkm_client_event() drm/nouveau/nvif: add nvif_event_stat drm/nouveau/nvif: add nvif_driver_func for nvkm->drm callbacks drm/nouveau/nvkm: add init()/exit() drm/nouveau/nvkm: cleanup in nvkm_device_{pci,tegra}_new() on failure drm/nouveau/nvkm: move vgaarb code from drm drm/nouveau/nvkm: move switcheroo init from drm drm/nouveau/nvif: add runpm supported flag to device impl drm/nouveau/nvkm: move switcheroo from drm drm/nouveau/nvkm: prepare pci/tegra probe()/remove() functions drm/nouveau/nvkm: move pci probe() defer from drm drm/nouveau/nvkm: move pci probe() fb handoff from drm drm/nouveau/nvkm: move pci probe() enable/disable handling from drm drm/nouveau/nvkm: move pci probe() runpm quirk from drm drm/nouveau/nvkm: move pci pm ops from drm drm/nouveau/nvkm: add device to auxiliary bus for each nvkm_device drm/nouveau: wrap pm_runtime_* calls with nouveau_runpm drm/nouveau: probe() against nvkm-provided auxiliary devices drm/nouveau/nvkm: s/nouveau/nvkm/ over code moved from drm drivers/gpu/drm/nouveau/Kbuild| 11 +- drivers/gpu/drm/nouveau/Kconfig | 1 + drivers/gpu/drm/nouveau/dispnv04/crtc.c | 4 +- drivers/gpu/drm/nouveau/dispnv04/disp.h | 2 +- drivers/gpu/drm/nouveau/dispnv50/disp.c | 40 +- drivers/gpu/drm/nouveau/dispnv50/head.c | 2 +- .../gpu/drm/nouveau/include/nvif/driverif.h | 18 + drivers/gpu/drm/nouveau/include/nvif/event.h | 7 +- .../drm/nouveau/include/nvkm/core/client.h| 4 +- .../drm/nouveau/include/nvkm/core/device.h| 12 + .../drm/nouveau/include/nvkm/core/module.h| 10 + .../gpu/drm/nouveau/include/nvkm/core/pci.h | 8 +- .../gpu/drm/nouveau/include/nvkm/core/tegra.h | 5 +- drivers/gpu/drm/nouveau/nouveau_acpi.c| 352 --- drivers/gpu/drm/nouveau/nouveau_acpi.h| 10 - drivers/gpu/drm/nouveau/nouveau_chan.c| 2 +- drivers/gpu/drm/nouveau/nouveau_connector.c | 16 +- drivers/gpu/drm/nouveau/nouveau_connector.h | 1 + drivers/gpu/drm/nouveau/nouveau_debugfs.c | 24 +- drivers/gpu/drm/nouveau/nouveau_display.c | 19 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 347 --- drivers/gpu/drm/nouveau/nouveau_drv.h | 24 +- drivers/gpu/drm/nouveau/nouveau_fence.c | 2 +- drivers/gpu/drm/nouveau/nouveau_gem.c | 30 +- drivers/gpu/drm/nouveau/nouveau_platform.c| 91 drivers/gpu/drm/nouveau/nouveau_runpm.h | 89 drivers/gpu/drm/nouveau/nouveau_svm.c | 2 +- drivers/gpu/drm/nouveau/nouveau_vga.c | 98 + drivers/gpu/drm/nouveau/nouveau_vga.h | 3 +- drivers/gpu/drm/nouveau/nvif/event.c | 9 + drivers/gpu/drm/nouveau/nvkm/Kbuild | 3 + drivers/gpu/drm/nouveau/nvkm/core/Kbuild | 2
Re: [PATCH v2] drm/nouveau: don't attempt to schedule hpd_work on headless cards
On 8/6/24 08:09, Vasily Khoruzhick wrote: If the card doesn't have display hardware, hpd_work and hpd_lock are left uninitialized which causes BUG when attempting to schedule hpd_work on runtime PM resume. Fix it by adding headless flag to DRM and skip any hpd if it's set. Fixes: ae1aadb1eb8d ("nouveau: don't fail driver load if no display hw present.") Link: https://gitlab.freedesktop.org/drm/nouveau/-/issues/337 Signed-off-by: Vasily Khoruzhick Reviewed-by: Ben Skeggs --- v2: drop extra checks in nouveau_display_hpd_work() and nouveau_connector_hpd() drivers/gpu/drm/nouveau/dispnv04/disp.c | 2 +- drivers/gpu/drm/nouveau/dispnv50/disp.c | 2 +- drivers/gpu/drm/nouveau/nouveau_display.c | 6 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.c b/drivers/gpu/drm/nouveau/dispnv04/disp.c index 13705c5f1497..4b7497a8755c 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/disp.c @@ -68,7 +68,7 @@ nv04_display_fini(struct drm_device *dev, bool runtime, bool suspend) if (nv_two_heads(dev)) NVWriteCRTC(dev, 1, NV_PCRTC_INTR_EN_0, 0); - if (!runtime) + if (!runtime && !drm->headless) cancel_work_sync(&drm->hpd_work); if (!suspend) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 88728a0b2c25..674dc567e179 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -2680,7 +2680,7 @@ nv50_display_fini(struct drm_device *dev, bool runtime, bool suspend) nv50_mstm_fini(nouveau_encoder(encoder)); } - if (!runtime) + if (!runtime && !drm->headless) cancel_work_sync(&drm->hpd_work); } diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index aed5d5b51b43..d4725a968827 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -450,6 +450,9 @@ nouveau_display_hpd_resume(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); + if (drm->headless) + return; + spin_lock_irq(&drm->hpd_lock); drm->hpd_pending = ~0; spin_unlock_irq(&drm->hpd_lock); @@ -635,7 +638,7 @@ nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime) } drm_connector_list_iter_end(&conn_iter); - if (!runtime) + if (!runtime && !drm->headless) cancel_work_sync(&drm->hpd_work); drm_kms_helper_poll_disable(dev); @@ -729,6 +732,7 @@ nouveau_display_create(struct drm_device *dev) /* no display hw */ if (ret == -ENODEV) { ret = 0; + drm->headless = true; goto disp_create_err; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index e239c6bf4afa..25fca98a20bc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -276,6 +276,7 @@ struct nouveau_drm { /* modesetting */ struct nvbios vbios; struct nouveau_display *display; + bool headless; struct work_struct hpd_work; spinlock_t hpd_lock; u32 hpd_pending;
Re: [PATCH] drm/nouveau/i2c: rename aux.c and aux.h to nvkm_i2c_aux.c and nvkm_i2c_aux.h
On 3/6/24 09:27, Szőke Benjamin wrote: 2024. 06. 03. 0:08 keltezéssel, Ben Skeggs írta: On 2/6/24 07:22, egyszer...@freemail.hu wrote: From: Benjamin Szőke The goal is to clean-up Linux repository from AUX file names, because the use of such file names is prohibited on other operating systems such as Windows, so the Linux repository cannot be cloned and edited on them. Signed-off-by: Benjamin Szőke --- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/i2c/{aux.c => nvkm_i2c_aux.c} | 2 +- .../gpu/drm/nouveau/nvkm/subdev/i2c/{aux.h => nvkm_i2c_aux.h} | 0 drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padg94.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgf119.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgm200.c | 2 +- 11 files changed, 10 insertions(+), 10 deletions(-) rename drivers/gpu/drm/nouveau/nvkm/subdev/i2c/{aux.c => nvkm_i2c_aux.c} (99%) rename drivers/gpu/drm/nouveau/nvkm/subdev/i2c/{aux.h => nvkm_i2c_aux.h} (100%) NACK on this rename. No other part of NVKM uses filenames like this. If anything, auxch.[ch] would be a better choice. Ben. Do you mean it would be better to rename them in the following way? rename drivers/gpu/drm/nouveau/nvkm/subdev/i2c/{aux.c => auxc.c} rename drivers/gpu/drm/nouveau/nvkm/subdev/i2c/{aux.h => auxh.h} Not quite. "aux" refers to DP "AUX CHannels", so, auxch.c and auxch.h are OK names. diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild index 819703913a00..c488dfce4392 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild @@ -25,7 +25,7 @@ nvkm-y += nvkm/subdev/i2c/busnv50.o nvkm-y += nvkm/subdev/i2c/busgf119.o nvkm-y += nvkm/subdev/i2c/bit.o -nvkm-y += nvkm/subdev/i2c/aux.o +nvkm-y += nvkm/subdev/i2c/nvkm_i2c_aux.o nvkm-y += nvkm/subdev/i2c/auxg94.o nvkm-y += nvkm/subdev/i2c/auxgf119.o nvkm-y += nvkm/subdev/i2c/auxgm200.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c index dd391809fef7..30bf84e77db9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c @@ -24,7 +24,7 @@ #define anx9805_pad(p) container_of((p), struct anx9805_pad, base) #define anx9805_bus(p) container_of((p), struct anx9805_bus, base) #define anx9805_aux(p) container_of((p), struct anx9805_aux, base) -#include "aux.h" +#include "nvkm_i2c_aux.h" #include "bus.h" struct anx9805_pad { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c index 47068f6f9c55..9e07ba444ca8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #define g94_i2c_aux(p) container_of((p), struct g94_i2c_aux, base) -#include "aux.h" +#include "nvkm_i2c_aux.h" struct g94_i2c_aux { struct nvkm_i2c_aux base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c index dab40cd8fe3a..8709b728c38b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c @@ -19,7 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "aux.h" +#include "nvkm_i2c_aux.h" static const struct nvkm_i2c_aux_func gf119_i2c_aux = { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c index 8bd1d442e465..f40c5709d217 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #define gm200_i2c_aux(p) container_of((p), struct gm200_i2c_aux, base) -#include "aux.h" +#include "nvkm_i2c_aux.h" struct gm200_i2c_aux { struct nvkm_i2c_aux base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c index 976539de4220..736275f0c774 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #include "priv.h" -#include "aux.h" +#include "nvkm_i2c_aux.h" #include "bus.h" #include "pad.h" diff --git a/drivers/gpu/drm/nouveau
Re: [PATCH] drm/nouveau/i2c: rename aux.c and aux.h to nvkm_i2c_aux.c and nvkm_i2c_aux.h
On 2/6/24 07:22, egyszer...@freemail.hu wrote: From: Benjamin Szőke The goal is to clean-up Linux repository from AUX file names, because the use of such file names is prohibited on other operating systems such as Windows, so the Linux repository cannot be cloned and edited on them. Signed-off-by: Benjamin Szőke --- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c| 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/i2c/{aux.c => nvkm_i2c_aux.c} | 2 +- .../gpu/drm/nouveau/nvkm/subdev/i2c/{aux.h => nvkm_i2c_aux.h} | 0 drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padg94.c| 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgf119.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgm200.c | 2 +- 11 files changed, 10 insertions(+), 10 deletions(-) rename drivers/gpu/drm/nouveau/nvkm/subdev/i2c/{aux.c => nvkm_i2c_aux.c} (99%) rename drivers/gpu/drm/nouveau/nvkm/subdev/i2c/{aux.h => nvkm_i2c_aux.h} (100%) NACK on this rename. No other part of NVKM uses filenames like this. If anything, auxch.[ch] would be a better choice. Ben. diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild index 819703913a00..c488dfce4392 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild @@ -25,7 +25,7 @@ nvkm-y += nvkm/subdev/i2c/busnv50.o nvkm-y += nvkm/subdev/i2c/busgf119.o nvkm-y += nvkm/subdev/i2c/bit.o -nvkm-y += nvkm/subdev/i2c/aux.o +nvkm-y += nvkm/subdev/i2c/nvkm_i2c_aux.o nvkm-y += nvkm/subdev/i2c/auxg94.o nvkm-y += nvkm/subdev/i2c/auxgf119.o nvkm-y += nvkm/subdev/i2c/auxgm200.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c index dd391809fef7..30bf84e77db9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c @@ -24,7 +24,7 @@ #define anx9805_pad(p) container_of((p), struct anx9805_pad, base) #define anx9805_bus(p) container_of((p), struct anx9805_bus, base) #define anx9805_aux(p) container_of((p), struct anx9805_aux, base) -#include "aux.h" +#include "nvkm_i2c_aux.h" #include "bus.h" struct anx9805_pad { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c index 47068f6f9c55..9e07ba444ca8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #define g94_i2c_aux(p) container_of((p), struct g94_i2c_aux, base) -#include "aux.h" +#include "nvkm_i2c_aux.h" struct g94_i2c_aux { struct nvkm_i2c_aux base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c index dab40cd8fe3a..8709b728c38b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c @@ -19,7 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "aux.h" +#include "nvkm_i2c_aux.h" static const struct nvkm_i2c_aux_func gf119_i2c_aux = { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c index 8bd1d442e465..f40c5709d217 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #define gm200_i2c_aux(p) container_of((p), struct gm200_i2c_aux, base) -#include "aux.h" +#include "nvkm_i2c_aux.h" struct gm200_i2c_aux { struct nvkm_i2c_aux base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c index 976539de4220..736275f0c774 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #include "priv.h" -#include "aux.h" +#include "nvkm_i2c_aux.h" #include "bus.h" #include "pad.h" diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/nvkm_i2c_aux.c similarity index 99% rename from drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c rename to drivers/gpu/drm/nouveau/nvkm/subdev/i2c/nvkm_i2c_aux.c index d063d0dc1
Re: [PATCH] drm/nouveau: don't attempt to schedule hpd_work on headless cards
On 29/5/24 07:52, Vasily Khoruzhick wrote: If the card doesn't have display hardware, hpd_work and hpd_lock are left uninitialized which causes BUG when attempting to schedule hpd_work on runtime PM resume. Hi, Good catch, thank you for looking at this. A couple of initial comments below: Ben. Fix it by adding headless flag to DRM and skip any hpd if it's set. Fixes: ae1aadb1eb8d ("nouveau: don't fail driver load if no display hw present.") Link: https://gitlab.freedesktop.org/drm/nouveau/-/issues/337 Signed-off-by: Vasily Khoruzhick --- drivers/gpu/drm/nouveau/dispnv04/disp.c | 2 +- drivers/gpu/drm/nouveau/dispnv50/disp.c | 2 +- drivers/gpu/drm/nouveau/nouveau_connector.c | 3 +++ drivers/gpu/drm/nouveau/nouveau_display.c | 11 ++- drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.c b/drivers/gpu/drm/nouveau/dispnv04/disp.c index 13705c5f1497..4b7497a8755c 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/disp.c @@ -68,7 +68,7 @@ nv04_display_fini(struct drm_device *dev, bool runtime, bool suspend) if (nv_two_heads(dev)) NVWriteCRTC(dev, 1, NV_PCRTC_INTR_EN_0, 0); - if (!runtime) + if (!runtime && !drm->headless) cancel_work_sync(&drm->hpd_work); if (!suspend) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 88728a0b2c25..674dc567e179 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -2680,7 +2680,7 @@ nv50_display_fini(struct drm_device *dev, bool runtime, bool suspend) nv50_mstm_fini(nouveau_encoder(encoder)); } - if (!runtime) + if (!runtime && !drm->headless) cancel_work_sync(&drm->hpd_work); } diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 856b3ef5edb8..b315a2ef5b28 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -1190,6 +1190,9 @@ nouveau_connector_hpd(struct nouveau_connector *nv_connector, u64 bits) u32 mask = drm_connector_mask(&nv_connector->base); unsigned long flags; + if (drm->headless) + return; + You shouldn't need this change, the function can't be called if there's no display. spin_lock_irqsave(&drm->hpd_lock, flags); if (!(drm->hpd_pending & mask)) { nv_connector->hpd_pending |= bits; diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index aed5d5b51b43..1961ef665e97 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -450,6 +450,9 @@ nouveau_display_hpd_resume(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); + if (drm->headless) + return; + spin_lock_irq(&drm->hpd_lock); drm->hpd_pending = ~0; spin_unlock_irq(&drm->hpd_lock); @@ -468,6 +471,11 @@ nouveau_display_hpd_work(struct work_struct *work) int changed = 0; struct drm_connector *first_changed_connector = NULL; + WARN_ON_ONCE(drm->headless); + + if (drm->headless) + return; + Same here. pm_runtime_get_sync(dev->dev); spin_lock_irq(&drm->hpd_lock); @@ -635,7 +643,7 @@ nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime) } drm_connector_list_iter_end(&conn_iter); - if (!runtime) + if (!runtime && !drm->headless) cancel_work_sync(&drm->hpd_work); drm_kms_helper_poll_disable(dev); @@ -729,6 +737,7 @@ nouveau_display_create(struct drm_device *dev) /* no display hw */ if (ret == -ENODEV) { ret = 0; + drm->headless = true; goto disp_create_err; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index e239c6bf4afa..25fca98a20bc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -276,6 +276,7 @@ struct nouveau_drm { /* modesetting */ struct nvbios vbios; struct nouveau_display *display; + bool headless; struct work_struct hpd_work; spinlock_t hpd_lock; u32 hpd_pending;
Re: [PATCH] drm/nouveau/nvkm/dp: Add hack to fix DP 1.3+ DPCD issues
On Sat, 8 Jul 2023 at 07:59, Lyude Paul wrote: > > Currently we use the drm_dp_dpcd_read_caps() helper in the DRM side of > nouveau in order to read the DPCD of a DP connector, which makes sure we do > the right thing and also check for extended DPCD caps. However, it turns > out we're not currently doing this on the nvkm side since we don't have > access to the drm_dp_aux structure there - which means that the DRM side of > the driver and the NVKM side can end up with different DPCD capabilities > for the same connector. > > Ideally to fix this, we want to start setting up the drm_dp_aux device in > NVKM before we've made contact with the DRM side - which should be pretty > easy to accomplish (I'm already working on it!). Until then however, let's > workaround this problem by porting a copy of drm_dp_read_dpcd_caps() into > NVKM - which should fix this issue. I wouldn't worry about this. I'm moving basically everything to the DRM side of the driver for the GSP work anyway. Ben. > > Issue: https://gitlab.freedesktop.org/drm/nouveau/-/issues/211 > Signed-off-by: Lyude Paul > --- > drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 48 ++- > 1 file changed, 47 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c > b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c > index 40c8ea43c42f..b8ac66b4a2c4 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c > @@ -26,6 +26,8 @@ > #include "head.h" > #include "ior.h" > > +#include > + > #include > #include > #include > @@ -634,6 +636,50 @@ nvkm_dp_enable_supported_link_rates(struct nvkm_outp > *outp) > return outp->dp.rates != 0; > } > > +/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps() > + * converted to work inside nvkm. This is a temporary holdover until we start > + * passing the drm_dp_aux device through NVKM > + */ > +static int > +nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp) > +{ > + struct nvkm_i2c_aux *aux = outp->dp.aux; > + u8 dpcd_ext[DP_RECEIVER_CAP_SIZE]; > + int ret; > + > + ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, > DP_RECEIVER_CAP_SIZE); > + if (ret < 0) > + return ret; > + > + /* > +* Prior to DP1.3 the bit represented by > +* DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved. > +* If it is set DP_DPCD_REV at h could be at a value less than > +* the true capability of the panel. The only way to check is to > +* then compare h and 2200h. > +*/ > + if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] & > + DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT)) > + return 0; > + > + ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext)); > + if (ret < 0) > + return ret; > + > + if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) { > + OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > > %d)\n", > +outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]); > + return 0; > + } > + > + if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext))) > + return 0; > + > + memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)); > + > + return 0; > +} > + > void > nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr) > { > @@ -689,7 +735,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr) > memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr)); > } > > - if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, > sizeof(outp->dp.dpcd))) { > + if (!nvkm_dp_read_dpcd_caps(outp)) { > const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 }; > const u8 *rate; > int rate_max; > -- > 2.40.1 >
Re: [Nouveau] [PATCH v2] drm/nouveau: bring back blit subchannel for pre nv50 GPUs
On Fri, 26 May 2023 at 19:11, Karol Herbst wrote: > > 1ba6113a90a0 removed a lot of the kernel GPU channel, but method 0x128 > was important as otherwise the GPU spams us with `CACHE_ERROR` messages. > > We use the blit subchannel inside our vblank handling, so we should keep > at least this part. > > v2: Only do it for NV11+ GPUs > > Closes: https://gitlab.freedesktop.org/drm/nouveau/-/issues/201 > Fixes: 4a16dd9d18a0 ("drm/nouveau/kms: switch to drm fbdev helpers") > Signed-off-by: Karol Herbst Reviewed-by: Ben Skeggs > --- > drivers/gpu/drm/nouveau/nouveau_chan.c | 1 + > drivers/gpu/drm/nouveau/nouveau_chan.h | 1 + > drivers/gpu/drm/nouveau/nouveau_drm.c | 20 +--- > 3 files changed, 19 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c > b/drivers/gpu/drm/nouveau/nouveau_chan.c > index e648ecd0c1a0..3dfbc374478e 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_chan.c > +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c > @@ -90,6 +90,7 @@ nouveau_channel_del(struct nouveau_channel **pchan) > if (cli) > nouveau_svmm_part(chan->vmm->svmm, chan->inst); > > + nvif_object_dtor(&chan->blit); > nvif_object_dtor(&chan->nvsw); > nvif_object_dtor(&chan->gart); > nvif_object_dtor(&chan->vram); > diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.h > b/drivers/gpu/drm/nouveau/nouveau_chan.h > index e06a8ffed31a..bad7466bd0d5 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_chan.h > +++ b/drivers/gpu/drm/nouveau/nouveau_chan.h > @@ -53,6 +53,7 @@ struct nouveau_channel { > u32 user_put; > > struct nvif_object user; > + struct nvif_object blit; > > struct nvif_event kill; > atomic_t killed; > diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c > b/drivers/gpu/drm/nouveau/nouveau_drm.c > index cc7c5b4a05fd..9512f1c2f871 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_drm.c > +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c > @@ -369,15 +369,29 @@ nouveau_accel_gr_init(struct nouveau_drm *drm) > ret = nvif_object_ctor(&drm->channel->user, "drmNvsw", >NVDRM_NVSW, nouveau_abi16_swclass(drm), >NULL, 0, &drm->channel->nvsw); > + > + if (ret == 0 && device->info.chipset >= 0x11) { > + ret = nvif_object_ctor(&drm->channel->user, "drmBlit", > + 0x005f, 0x009f, > + NULL, 0, &drm->channel->blit); > + } > + > if (ret == 0) { > struct nvif_push *push = drm->channel->chan.push; > - ret = PUSH_WAIT(push, 2); > - if (ret == 0) > + ret = PUSH_WAIT(push, 8); > + if (ret == 0) { > + if (device->info.chipset >= 0x11) { > + PUSH_NVSQ(push, NV05F, 0x, > drm->channel->blit.handle); > + PUSH_NVSQ(push, NV09F, 0x0120, 0, > + 0x0124, 1, > + 0x0128, 2); > + } > PUSH_NVSQ(push, NV_SW, 0x, > drm->channel->nvsw.handle); > + } > } > > if (ret) { > - NV_ERROR(drm, "failed to allocate sw class, %d\n", > ret); > + NV_ERROR(drm, "failed to allocate sw or blit class, > %d\n", ret); > nouveau_accel_gr_fini(drm); > return; > } > -- > 2.40.1 >
Re: [Nouveau] [PATCH] drm/nouveau/acr: Abort loading ACR if no firmware was found
On Thu, 13 Jul 2023 at 05:31, Dave Airlie wrote: > > On Tue, 23 May 2023 at 19:37, Karol Herbst wrote: > > > > On Mon, May 22, 2023 at 10:18 PM Karol Herbst wrote: > > > > > > This fixes a NULL pointer access inside nvkm_acr_oneinit in case necessary > > > firmware files couldn't be loaded. > > > > > > Closes: https://gitlab.freedesktop.org/drm/nouveau/-/issues/212 > > > Fixes: 4b569ded09fd ("drm/nouveau/acr/ga102: initial support") > > > Signed-off-by: Karol Herbst > > > --- > > > drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c | 2 +- > > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > > > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c > > > b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c > > > index 795f3a649b12..6388234c352c 100644 > > > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c > > > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c > > > @@ -224,7 +224,7 @@ nvkm_acr_oneinit(struct nvkm_subdev *subdev) > > > u64 falcons; > > > int ret, i; > > > > > > - if (list_empty(&acr->hsfw)) { > > > + if (list_empty(&acr->hsfw) || !acr->func->wpr_layout) { > > > > Now thinking about this, it should probably also check acr->func... > > with that fixed if you think you need it, I don't *think* you do. I believe modprobe will fail for any case it can be NULL. > > Reviewed-by: Dave Airlie > > > > > > nvkm_debug(subdev, "No HSFW(s)\n"); > > > nvkm_acr_cleanup(acr); > > > return 0; > > > -- > > > 2.40.1 > > > > >
Re: [PATCH] drm/nouveau/fb: add missing sysmen flush callbacks
On Wed, 5 Apr 2023 at 21:05, Karol Herbst wrote: > > Closes: https://gitlab.freedesktop.org/drm/nouveau/-/issues/203 > Fixes: 5728d064190e1 ("drm/nouveau/fb: handle sysmem flush page from common > code") > Signed-off-by: Karol Herbst Oops, that must've gotten lost in a rebase somehow. Reviewed-by: Ben Skeggs > --- > drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf108.c | 1 + > drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c | 1 + > drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk110.c | 1 + > drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c | 1 + > 4 files changed, 4 insertions(+) > > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf108.c > b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf108.c > index 76678dd60f93f..c4c6f67af7ccc 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf108.c > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf108.c > @@ -31,6 +31,7 @@ gf108_fb = { > .init = gf100_fb_init, > .init_page = gf100_fb_init_page, > .intr = gf100_fb_intr, > + .sysmem.flush_page_init = gf100_fb_sysmem_flush_page_init, > .ram_new = gf108_ram_new, > .default_bigpage = 17, > }; > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c > b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c > index f73442ccb424b..433fa966ba231 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c > @@ -77,6 +77,7 @@ gk104_fb = { > .init = gf100_fb_init, > .init_page = gf100_fb_init_page, > .intr = gf100_fb_intr, > + .sysmem.flush_page_init = gf100_fb_sysmem_flush_page_init, > .ram_new = gk104_ram_new, > .default_bigpage = 17, > .clkgate_pack = gk104_fb_clkgate_pack, > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk110.c > b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk110.c > index 45d6cdffafeed..4dc283dedf8b5 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk110.c > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk110.c > @@ -59,6 +59,7 @@ gk110_fb = { > .init = gf100_fb_init, > .init_page = gf100_fb_init_page, > .intr = gf100_fb_intr, > + .sysmem.flush_page_init = gf100_fb_sysmem_flush_page_init, > .ram_new = gk104_ram_new, > .default_bigpage = 17, > .clkgate_pack = gk110_fb_clkgate_pack, > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c > b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c > index de52462a92bf0..90bfff616d35b 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c > @@ -31,6 +31,7 @@ gm107_fb = { > .init = gf100_fb_init, > .init_page = gf100_fb_init_page, > .intr = gf100_fb_intr, > + .sysmem.flush_page_init = gf100_fb_sysmem_flush_page_init, > .ram_new = gm107_ram_new, > .default_bigpage = 17, > }; > -- > 2.39.2 >
Re: linux-6.2-rc4+ hangs on poweroff/reboot: Bisected
On Mon, 20 Feb 2023 at 21:27, Karol Herbst wrote: > > On Mon, Feb 20, 2023 at 11:51 AM Chris Clayton > wrote: > > > > > > > > On 20/02/2023 05:35, Ben Skeggs wrote: > > > On Sun, 19 Feb 2023 at 04:55, Chris Clayton > > > wrote: > > >> > > >> > > >> > > >> On 18/02/2023 15:19, Chris Clayton wrote: > > >>> > > >>> > > >>> On 18/02/2023 12:25, Karol Herbst wrote: > > >>>> On Sat, Feb 18, 2023 at 1:22 PM Chris Clayton > > >>>> wrote: > > >>>>> > > >>>>> > > >>>>> > > >>>>> On 15/02/2023 11:09, Karol Herbst wrote: > > >>>>>> On Wed, Feb 15, 2023 at 11:36 AM Linux regression tracking #update > > >>>>>> (Thorsten Leemhuis) wrote: > > >>>>>>> > > >>>>>>> On 13.02.23 10:14, Chris Clayton wrote: > > >>>>>>>> On 13/02/2023 02:57, Dave Airlie wrote: > > >>>>>>>>> On Sun, 12 Feb 2023 at 00:43, Chris Clayton > > >>>>>>>>> wrote: > > >>>>>>>>>> > > >>>>>>>>>> > > >>>>>>>>>> > > >>>>>>>>>> On 10/02/2023 19:33, Linux regression tracking (Thorsten > > >>>>>>>>>> Leemhuis) wrote: > > >>>>>>>>>>> On 10.02.23 20:01, Karol Herbst wrote: > > >>>>>>>>>>>> On Fri, Feb 10, 2023 at 7:35 PM Linux regression tracking > > >>>>>>>>>>>> (Thorsten > > >>>>>>>>>>>> Leemhuis) wrote: > > >>>>>>>>>>>>> > > >>>>>>>>>>>>> On 08.02.23 09:48, Chris Clayton wrote: > > >>>>>>>>>>>>>> > > >>>>>>>>>>>>>> I'm assuming that we are not going to see a fix for this > > >>>>>>>>>>>>>> regression before 6.2 is released. > > >>>>>>>>>>>>> > > >>>>>>>>>>>>> Yeah, looks like it. That's unfortunate, but happens. But > > >>>>>>>>>>>>> there is still > > >>>>>>>>>>>>> time to fix it and there is one thing I wonder: > > >>>>>>>>>>>>> > > >>>>>>>>>>>>> Did any of the nouveau developers look at the netconsole > > >>>>>>>>>>>>> captures Chris > > >>>>>>>>>>>>> posted more than a week ago to check if they somehow help to > > >>>>>>>>>>>>> track down > > >>>>>>>>>>>>> the root of this problem? > > >>>>>>>>>>>> > > >>>>>>>>>>>> I did now and I can't spot anything. I think at this point it > > >>>>>>>>>>>> would > > >>>>>>>>>>>> make sense to dump the active tasks/threads via sqsrq keys to > > >>>>>>>>>>>> see if > > >>>>>>>>>>>> any is in a weird state preventing the machine from shutting > > >>>>>>>>>>>> down. > > >>>>>>>>>>> > > >>>>>>>>>>> Many thx for looking into it! > > >>>>>>>>>> > > >>>>>>>>>> Yes, thanks Karol. > > >>>>>>>>>> > > >>>>>>>>>> Attached is the output from dmesg when this block of code: > > >>>>>>>>>> > > >>>>>>>>>> /bin/mount /dev/sda7 /mnt/sda7 > > >>>>>>>>>> /bin/mountpoint /proc || /bin/mount /proc > > >>>>>>>>>> /bin/dmesg -w > /mnt/sda7/sysrq.dmesg.log & > > >>>>>>>>>> /bin/echo t > /proc/sysrq-trigger > > >>>>>>>>>> /bin/sleep 1 > > >>>>>>>>&g
Re: linux-6.2-rc4+ hangs on poweroff/reboot: Bisected
h further to a solution. :-/ I don't > >>>>> really like it, but for regression tracking I'm now putting this on the > >>>>> back-burner, as a fix is not in sight. > >>>>> > >>>>> #regzbot monitor: > >>>>> https://lore.kernel.org/lkml/e0b80506-b3cf-315b-4327-1b988d860...@googlemail.com/ > >>>>> #regzbot backburner: hard to debug and apparently rare > >>>>> #regzbot ignore-activity > >>>>> > >>>> > >>>> yeah.. this bug looks a little annoying. Sadly the only Turing based > >>>> laptop I got doesn't work on Nouveau because of firmware related > >>>> issues and we probably need to get updated ones from Nvidia here :( > >>>> > >>>> But it's a bit weird that the kernel doesn't shutdown, because I don't > >>>> see anything in the logs which would prevent that from happening. > >>>> Unless it's waiting on one of the tasks to complete, but none of them > >>>> looked in any way nouveau related. > >>>> > >>>> If somebody else has any fancy kernel debugging tips here to figure > >>>> out why it hangs, that would be very helpful... > >>>> > >>> > >>> I think I've figured this out. It's to do with how my system is > >>> configured. I do have an initrd, but the only thing on > >>> it is the cpu microcode which, it is recommended, should be loaded early. > >>> The absence of the NVidia firmare from an > >>> initrd doesn't matter because the drivers for the hardware that need to > >>> load firmware are all built as modules, So, by > >>> the time the devices are configured via udev, the root partition is > >>> mounted and the drivers can get at the firmware. > >>> > >>> I've found, by turning on nouveau debug and taking a video of the screen > >>> as the system shuts down, that nouveau seems to > >>> be trying to run the scrubber very very late in the shutdown process. The > >>> problem is that by this time, I think the root > >>> partition, and thus the scrubber binary, have become inaccessible. > >>> > >>> I seem to have two choices - either make the firmware accessible on an > >>> initrd or unload the module in a shutdown script > >>> before the scrubber binary becomes inaccessible. The latter of these is > >>> the workaround I have implemented whilst the > >>> problem I reported has been under investigation. For simplicity, I think > >>> I'll promote my workaround to being the > >>> permanent solution. > >>> > >>> So, apologies (and thanks) to everyone whose time I have taken up with > >>> this non-bug. > >>> > >> > >> Well.. nouveau shouldn't prevent the system from shutting down if the > >> firmware file isn't available. Or at least it should print a > >> warning/error. Mind messing with the code a little to see if skipping > >> it kind of works? I probably can also come up with a patch by next > >> week. > >> > > Well, I'd love to but a quick glance at the code caused me to bump into > > this obscenity: > > > > int > > gm200_flcn_reset_wait_mem_scrubbing(struct nvkm_falcon *falcon) > > { > > nvkm_falcon_mask(falcon, 0x040, 0x, 0x); > > > > if (nvkm_msec(falcon->owner->device, 10, > > if (!(nvkm_falcon_rd32(falcon, 0x10c) & 0x0006)) > > break; > > ) < 0) > > return -ETIMEDOUT; > > > > return 0; > > } > > > > nvkm_msec is #defined to nvkm_usec which in turn is #defined to nvkm_nsec > > where the loop that the break is related to > > appears > > I think someone who knows the code needs to look at this. What I can confirm > is that after a freeze, I waited for 90 > seconds for a timeout to occur, but it didn't. Hey, Are you able to try the attached patch for me please? Thanks, Ben. > > > .> Chris > >>> > >>>>> Ciao, Thorsten (wearing his 'the Linux kernel's regression tracker' hat) > >>>>> -- > >>>>> Everything you wanna know about Linux kernel regression tracking: > >>>>> https://linux-regtracking.leemhuis.info/about/#tldr > >>>>> That
Re: linux-6.2-rc4+ hangs on poweroff/reboot: Bisected
On Tue, 31 Jan 2023 at 09:09, Chris Clayton wrote: > > Hi again. > > On 30/01/2023 20:19, Chris Clayton wrote: > > Thanks, Ben. > > > > >> Hey, > >> > >> This is a complete shot-in-the-dark, as I don't see this behaviour on > >> *any* of my boards. Could you try the attached patch please? > > > > Unfortunately, the patch made no difference. > > > > I've been looking at how the graphics on my laptop is set up, and have a > > bit of a worry about whether the firmware might > > be playing a part in this problem. In order to offload video decoding to > > the NVidia TU117 GPU, it seems the scrubber > > firmware must be available, but as far as I know,that has not been released > > by NVidia. To get it to work, I followed > > what ubuntu have done and the scrubber in /lib/firmware/nvidia/tu117/nvdec/ > > is a symlink to > > ../../tu116/nvdev/scrubber.bin. That, of course, means that some of the > > firmware loaded is for a different card is being > > loaded. I note that processing related to firmware is being changed in the > > patch. Might my set up be at the root of my > > problem? > > > > I'll have a fiddle an see what I can work out. > > > > Chris > > > >> > >> Thanks, > >> Ben. > >> > >>> > > Well, my fiddling has got my system rebooting and shutting down successfully > again. I found that if I delete the symlink > to the scrubber firmware, reboot and shutdown work again. There are however, > a number of other files in the tu117 > firmware directory tree that that are symlinks to actual files in its tu116 > counterpart. So I deleted all of those too. > Unfortunately, the absence of one or more of those symlinks causes Xorg to > fail to start. I've reinstated all the links > except scrubber and I now have a system that works as it did until I tried to > run a kernel that includes the bad commit > I identified in my bisection. That includes offloading video decoding to the > NVidia card, so what ever I read that said > the scrubber firmware was needed seems to have been wrong. I get a new > message that (nouveau :01:00.0: fb: VPR > locked, but no scrubber binary!), but, hey, we can't have everything. > > If you still want to get to the bottom of this, let me know what you need me > to provide and I'll do my best. I suspect > you might want to because there will a n awful lot of Ubuntu-based systems > out there with that scrubber.bin symlink in > place. On the other hand,m it could but quite a while before ubuntu are > deploying 6.2 or later kernels. The symlinks are correct - whole groups of GPUs share the same FW, and we use symlinks in linux-firmware to represent this. I don't really have any ideas how/why this patch causes issues with shutdown - it's a path that only gets executed during initialisation. Can you try and capture the kernel log during shutdown ("dmesg -w" over ssh? netconsole?), and see if there's any relevant messages providing a hint at what's going on? Alternatively, you could try unloading the module (you will have to stop X/wayland/gdm/etc/etc first) and seeing if that hangs too. Ben. > > Thanks, > > Chris > >
Re: [PATCH 1/3] drm/nouveau/devinit/tu102-: wait for GFW_BOOT_PROGRESS == COMPLETED
On Tue, 31 Jan 2023 at 09:19, Lyude Paul wrote: > > For the whole series: > > Reviewed-by: Lyude Paul > > Will push to drm-misc-fixes in just a moment Thank you Lyude! Much appreciated. Ben. > > On Tue, 2023-01-31 at 08:37 +1000, Ben Skeggs wrote: > > Starting from Turing, the driver is no longer responsible for initiating > > DEVINIT when required as the GPU started loading a FW image from ROM and > > executing DEVINIT itself after power-on. > > > > However - we apparently still need to wait for it to complete. > > > > This should correct some issues with runpm on some systems, where we get > > control of the HW before it's been fully reinitialised after resume from > > suspend. > > > > Signed-off-by: Ben Skeggs > > --- > > .../drm/nouveau/nvkm/subdev/devinit/tu102.c | 23 +++ > > 1 file changed, 23 insertions(+) > > > > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c > > b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c > > index 634f64f88fc8..81a1ad2c88a7 100644 > > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c > > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c > > @@ -65,10 +65,33 @@ tu102_devinit_pll_set(struct nvkm_devinit *init, u32 > > type, u32 freq) > > return ret; > > } > > > > +static int > > +tu102_devinit_wait(struct nvkm_device *device) > > +{ > > + unsigned timeout = 50 + 2000; > > + > > + do { > > + if (nvkm_rd32(device, 0x118128) & 0x0001) { > > + if ((nvkm_rd32(device, 0x118234) & 0x00ff) == > > 0xff) > > + return 0; > > + } > > + > > + usleep_range(1000, 2000); > > + } while (timeout--); > > + > > + return -ETIMEDOUT; > > +} > > + > > int > > tu102_devinit_post(struct nvkm_devinit *base, bool post) > > { > > struct nv50_devinit *init = nv50_devinit(base); > > + int ret; > > + > > + ret = tu102_devinit_wait(init->base.subdev.device); > > + if (ret) > > + return ret; > > + > > gm200_devinit_preos(init, post); > > return 0; > > } > > -- > Cheers, > Lyude Paul (she/her) > Software Engineer at Red Hat >
[PATCH 3/3] drm/nouveau/acr/gm20b: regression fixes
Missed some Tegra-specific quirks when reworking ACR to support Ampere. Fixes: 2541626cfb79 ("drm/nouveau/acr: use common falcon HS FW code for ACR FWs") Signed-off-by: Ben Skeggs Tested-by: Diogo Ivo Tested-By: Nicolas Chauvet --- drivers/gpu/drm/nouveau/nvkm/core/firmware.c| 3 +++ drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c | 14 +- drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/core/firmware.c b/drivers/gpu/drm/nouveau/nvkm/core/firmware.c index fcf2a002f6cb..91fb494d4009 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/firmware.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/firmware.c @@ -151,6 +151,9 @@ nvkm_firmware_mem_page(struct nvkm_memory *memory) static enum nvkm_memory_target nvkm_firmware_mem_target(struct nvkm_memory *memory) { + if (nvkm_firmware_mem(memory)->device->func->tegra) + return NVKM_MEM_TARGET_NCOH; + return NVKM_MEM_TARGET_HOST; } diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c index 393ade9f7e6c..b7da3ab44c27 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c @@ -48,6 +48,16 @@ gm200_flcn_pio_dmem_rd(struct nvkm_falcon *falcon, u8 port, const u8 *img, int l img += 4; len -= 4; } + + /* Sigh. Tegra PMU FW's init message... */ + if (len) { + u32 data = nvkm_falcon_rd32(falcon, 0x1c4 + (port * 8)); + + while (len--) { + *(u8 *)img++ = data & 0xff; + data >>= 8; + } + } } static void @@ -64,6 +74,8 @@ gm200_flcn_pio_dmem_wr(struct nvkm_falcon *falcon, u8 port, const u8 *img, int l img += 4; len -= 4; } + + WARN_ON(len); } static void @@ -74,7 +86,7 @@ gm200_flcn_pio_dmem_wr_init(struct nvkm_falcon *falcon, u8 port, bool sec, u32 d const struct nvkm_falcon_func_pio gm200_flcn_dmem_pio = { - .min = 4, + .min = 1, .max = 0x100, .wr_init = gm200_flcn_pio_dmem_wr_init, .wr = gm200_flcn_pio_dmem_wr, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c index a72403777329..2ed04da3621d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c @@ -225,7 +225,7 @@ gm20b_pmu_init(struct nvkm_pmu *pmu) pmu->initmsg_received = false; - nvkm_falcon_load_dmem(falcon, &args, addr_args, sizeof(args), 0); + nvkm_falcon_pio_wr(falcon, (u8 *)&args, 0, 0, DMEM, addr_args, sizeof(args), 0, false); nvkm_falcon_start(falcon); return 0; } -- 2.35.1
[PATCH 2/3] drm/nouveau/fb/tu102-: fix register used to determine scrub status
Turing apparently needs to use the same register we use on Ampere. Not executing the scrubber ucode when required would result in large areas of VRAM being inaccessible to the driver. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/include/nvkm/subdev/fb.h | 1 + .../gpu/drm/nouveau/nvkm/engine/device/base.c | 10 ++-- drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/fb/ga102.c| 8 +-- .../gpu/drm/nouveau/nvkm/subdev/fb/gv100.c| 5 -- drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h | 2 + .../gpu/drm/nouveau/nvkm/subdev/fb/tu102.c| 55 +++ 7 files changed, 65 insertions(+), 17 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fb/tu102.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index 40768373cdd9..c5a4f49ee206 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h @@ -97,6 +97,7 @@ int gp100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct n int gp102_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); int gp10b_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); int gv100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); +int tu102_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); int ga100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); int ga102_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 364fea320cb3..1c81e5b34d29 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2405,7 +2405,7 @@ nv162_chipset = { .bus = { 0x0001, gf100_bus_new }, .devinit = { 0x0001, tu102_devinit_new }, .fault= { 0x0001, tu102_fault_new }, - .fb = { 0x0001, gv100_fb_new }, + .fb = { 0x0001, tu102_fb_new }, .fuse = { 0x0001, gm107_fuse_new }, .gpio = { 0x0001, gk104_gpio_new }, .gsp = { 0x0001, gv100_gsp_new }, @@ -2440,7 +2440,7 @@ nv164_chipset = { .bus = { 0x0001, gf100_bus_new }, .devinit = { 0x0001, tu102_devinit_new }, .fault= { 0x0001, tu102_fault_new }, - .fb = { 0x0001, gv100_fb_new }, + .fb = { 0x0001, tu102_fb_new }, .fuse = { 0x0001, gm107_fuse_new }, .gpio = { 0x0001, gk104_gpio_new }, .gsp = { 0x0001, gv100_gsp_new }, @@ -2475,7 +2475,7 @@ nv166_chipset = { .bus = { 0x0001, gf100_bus_new }, .devinit = { 0x0001, tu102_devinit_new }, .fault= { 0x0001, tu102_fault_new }, - .fb = { 0x0001, gv100_fb_new }, + .fb = { 0x0001, tu102_fb_new }, .fuse = { 0x0001, gm107_fuse_new }, .gpio = { 0x0001, gk104_gpio_new }, .gsp = { 0x0001, gv100_gsp_new }, @@ -2510,7 +2510,7 @@ nv167_chipset = { .bus = { 0x0001, gf100_bus_new }, .devinit = { 0x0001, tu102_devinit_new }, .fault= { 0x0001, tu102_fault_new }, - .fb = { 0x0001, gv100_fb_new }, + .fb = { 0x0001, tu102_fb_new }, .fuse = { 0x0001, gm107_fuse_new }, .gpio = { 0x0001, gk104_gpio_new }, .gsp = { 0x0001, gv100_gsp_new }, @@ -2545,7 +2545,7 @@ nv168_chipset = { .bus = { 0x0001, gf100_bus_new }, .devinit = { 0x0001, tu102_devinit_new }, .fault= { 0x0001, tu102_fault_new }, - .fb = { 0x0001, gv100_fb_new }, + .fb = { 0x0001, tu102_fb_new }, .fuse = { 0x0001, gm107_fuse_new }, .gpio = { 0x0001, gk104_gpio_new }, .gsp = { 0x0001, gv100_gsp_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild index 5d0bab8ecb43..6ba5120a2ebe 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild @@ -32,6 +32,7 @@ nvkm-y += nvkm/subdev/fb/gp100.o nvkm-y += nvkm/subdev/fb/gp102.o nvkm-y += nvkm/subdev/fb/gp10b.o nvkm-y += nvkm/subdev/fb/gv100.o +nvkm-y += nvkm/subdev/fb/tu102.o nvkm-y += nvkm/subdev/fb/ga100.o nvkm-y += nvkm/subdev/fb/ga102.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c index 8b7c8ea5e8a5..5a21b0ae4595 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c @@ -40,12 +40,6
[PATCH 1/3] drm/nouveau/devinit/tu102-: wait for GFW_BOOT_PROGRESS == COMPLETED
Starting from Turing, the driver is no longer responsible for initiating DEVINIT when required as the GPU started loading a FW image from ROM and executing DEVINIT itself after power-on. However - we apparently still need to wait for it to complete. This should correct some issues with runpm on some systems, where we get control of the HW before it's been fully reinitialised after resume from suspend. Signed-off-by: Ben Skeggs --- .../drm/nouveau/nvkm/subdev/devinit/tu102.c | 23 +++ 1 file changed, 23 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c index 634f64f88fc8..81a1ad2c88a7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c @@ -65,10 +65,33 @@ tu102_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq) return ret; } +static int +tu102_devinit_wait(struct nvkm_device *device) +{ + unsigned timeout = 50 + 2000; + + do { + if (nvkm_rd32(device, 0x118128) & 0x0001) { + if ((nvkm_rd32(device, 0x118234) & 0x00ff) == 0xff) + return 0; + } + + usleep_range(1000, 2000); + } while (timeout--); + + return -ETIMEDOUT; +} + int tu102_devinit_post(struct nvkm_devinit *base, bool post) { struct nv50_devinit *init = nv50_devinit(base); + int ret; + + ret = tu102_devinit_wait(init->base.subdev.device); + if (ret) + return ret; + gm200_devinit_preos(init, post); return 0; } -- 2.35.1
Re: linux-6.2-rc4+ hangs on poweroff/reboot: Bisected
On Sat, 28 Jan 2023 at 21:29, Chris Clayton wrote: > > > > On 28/01/2023 05:42, Linux kernel regression tracking (Thorsten Leemhuis) > wrote: > > On 27.01.23 20:46, Chris Clayton wrote: > >> [Resend because the mail client on my phone decided to turn HTML on behind > >> my back, so my reply got bounced.] > >> > >> Thanks Thorsten. > >> > >> I did try to revert but it didnt revert cleanly and I don't have the > >> knowledge to fix it up. > >> > >> The patch was part of a merge that included a number of related patches. > >> Tomorrow, I'll try to revert the lot and report > >> back. > > > > You are free to do so, but there is no need for that from my side. I > > only wanted to know if a simple revert would do the trick; if it > > doesn't, it in my experience often is best to leave things to the > > developers of the code in question, > > Sound advice, Thorsten. Way to many conflicts for me to resolve. Hey, This is a complete shot-in-the-dark, as I don't see this behaviour on *any* of my boards. Could you try the attached patch please? Thanks, Ben. > > as they know it best and thus have a > > better idea which hidden side effect a more complex revert might have. > > > > Ciao, Thorsten > > > >> On 27/01/2023 11:20, Linux kernel regression tracking (Thorsten Leemhuis) > >> wrote: > >>> Hi, this is your Linux kernel regression tracker. Top-posting for once, > >>> to make this easily accessible to everyone. > >>> > >>> @nouveau-maintainers, did anyone take a look at this? The report is > >>> already 8 days old and I don't see a single reply. Sure, we'll likely > >>> get a -rc8, but still it would be good to not fix this on the finish line. > >>> > >>> Chris, btw, did you try if you can revert the commit on top of latest > >>> mainline? And if so, does it fix the problem? > >>> > >>> Ciao, Thorsten (wearing his 'the Linux kernel's regression tracker' hat) > >>> -- > >>> Everything you wanna know about Linux kernel regression tracking: > >>> https://linux-regtracking.leemhuis.info/about/#tldr > >>> If I did something stupid, please tell me, as explained on that page. > >>> > >>> #regzbot poke > >>> > >>> On 19.01.23 15:33, Linux kernel regression tracking (Thorsten Leemhuis) > >>> wrote: > [adding various lists and the two other nouveau maintainers to the list > of recipients] > >>> > On 18.01.23 21:59, Chris Clayton wrote: > > Hi. > > > > I build and installed the lastest development kernel earlier this week. > > I've found that when I try the laptop down (or > > reboot it), it hangs right at the end of closing the current session. > > The last line I see on the screen when rebooting is: > > > > sd 4:0:0:0: [sda] Synchronising SCSI cache > > > > when closing down I see one additional line: > > > > sd 4:0:0:0 [sda]Stopping disk > > > > In both cases the machine then hangs and I have to hold down the power > > button fot a few seconds to switch it off. > > > > Linux 6.1 is OK but 6.2-rc1 hangs, so I bisected between this two and > > landed on: > > > > # first bad commit: [0e44c21708761977dcbea9b846b51a6fb684907a] > > drm/nouveau/flcn: new code to load+boot simple HS FWs > > (VPR scrubber) > > > > I built and installed a kernel with > > f15cde64b66161bfa74fb58f4e5697d8265b802e (the parent of the bad commit) > > checked out > > and that shuts down and reboots fine. It the did the same with the bad > > commit checked out and that does indeed hang, so > > I'm confident the bisect outcome is OK. > > > > Kernels 6.1.6 and 5.15.88 are also OK. > > > > My system had dual GPUs - one intel and one NVidia. Related extracts > > from 'lscpi -v' is: > > > > 00:02.0 VGA compatible controller: Intel Corporation CometLake-H GT2 > > [UHD Graphics] (rev 05) (prog-if 00 [VGA controller]) > > Subsystem: CLEVO/KAPOK Computer CometLake-H GT2 [UHD Graphics] > > > > Flags: bus master, fast devsel, latency 0, IRQ 142 > > > > Memory at c200 (64-bit, non-prefetchable) [size=16M] > > > > Memory at a000 (64-bit, prefetchable) [size=256M] > > > > I/O ports at 5000 [size=64] > > > > Expansion ROM at 000c [virtual] [disabled] [size=128K] > > > > Capabilities: [40] Vendor Specific Information: Len=0c > > > > Capabilities: [70] Express Root Complex Integrated Endpoint, > > MSI 00 > > > > Capabilities: [ac] MSI: Enable+ Count=1/1 Maskable- 64bit- > > > > Capabilities: [d0] Power Management version 2 > > > > Kernel driver in use: i915 > > > > Kernel modules: i915 > > > > > > 01:00.0 VGA compatible controller: NVIDIA Corporation TU117M [GeForce > > GTX 1650 Ti Mobile] (rev a1) (prog-if 00 [VGA > > controller]) > > Subsystem: CLEVO/K
Re: [REGRESSION] GM20B probe fails after commit 2541626cfb79
On Fri, 27 Jan 2023 at 20:42, Diogo Ivo wrote: > > On Fri, Jan 27, 2023 at 04:00:59PM +1000, Ben Skeggs wrote: > > On Fri, 20 Jan 2023 at 21:37, Diogo Ivo > > wrote: > > > > > > On Wed, Jan 18, 2023 at 11:28:49AM +1000, Ben Skeggs wrote: > > > > On Mon, 16 Jan 2023 at 22:27, Diogo Ivo > > > > wrote: > > > > > On Mon, Jan 16, 2023 at 07:45:05AM +1000, David Airlie wrote: > > > > > > As a quick check can you try changing > > > > > > > > > > > > drivers/gpu/drm/nouveau/nvkm/core/firmware.c:nvkm_firmware_mem_target > > > > > > from NVKM_MEM_TARGET_HOST to NVKM_MEM_TARGET_NCOH ? > > > > > > > In addition to Dave's change, can you try changing the > > > > nvkm_falcon_load_dmem() call in gm20b_pmu_init() to: > > > > > > > > nvkm_falcon_pio_wr(falcon, (u8 *)&args, 0, 0, DMEM, addr_args, > > > > sizeof(args), 0, false); > > > > > > Chiming in just to say that with this change I see the same as Nicolas > > > except that the init message size is 255 instead of 0: > > > > > > [2.196934] nouveau 5700.gpu: pmu: unexpected init message size > > > 255 vs 42 > > I've attached an entirely untested patch (to go on top of the other > > hacks/fixes so far), that will hopefully get us a little further. > > Hello, > > Thank you for the patch! I can confirm that it fixes the problem > on the Pixel C, and everything works as before the regression. > With this, for the combination of patches > > Tested-by: Diogo Ivo > > which I can resend after testing the final patch version. Thank you (both!) for testing! I've attached a "final" version of a patch that I'll send (assuming it still works ;)) after re-testing. There's only a minor change to avoid breaking the non-Tegra path, so I expect it should be fine. Ben. > > Thanks, > Diogo From bfc1b84d26ca28f78a07d494b0813fe642e80bbe Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 27 Jan 2023 15:42:27 +1000 Subject: [PATCH] drm/nouveau/acr/gm20b: regression fixes Missed some Tegra-specific quirks when reworking ACR to support Ampere. Fixes: 2541626cfb79 ("drm/nouveau/acr: use common falcon HS FW code for ACR FWs") Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/core/firmware.c| 3 +++ drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c | 14 +- drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/core/firmware.c b/drivers/gpu/drm/nouveau/nvkm/core/firmware.c index fcf2a002f6cb..91fb494d4009 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/firmware.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/firmware.c @@ -151,6 +151,9 @@ nvkm_firmware_mem_page(struct nvkm_memory *memory) static enum nvkm_memory_target nvkm_firmware_mem_target(struct nvkm_memory *memory) { + if (nvkm_firmware_mem(memory)->device->func->tegra) + return NVKM_MEM_TARGET_NCOH; + return NVKM_MEM_TARGET_HOST; } diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c index 393ade9f7e6c..b7da3ab44c27 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c @@ -48,6 +48,16 @@ gm200_flcn_pio_dmem_rd(struct nvkm_falcon *falcon, u8 port, const u8 *img, int l img += 4; len -= 4; } + + /* Sigh. Tegra PMU FW's init message... */ + if (len) { + u32 data = nvkm_falcon_rd32(falcon, 0x1c4 + (port * 8)); + + while (len--) { + *(u8 *)img++ = data & 0xff; + data >>= 8; + } + } } static void @@ -64,6 +74,8 @@ gm200_flcn_pio_dmem_wr(struct nvkm_falcon *falcon, u8 port, const u8 *img, int l img += 4; len -= 4; } + + WARN_ON(len); } static void @@ -74,7 +86,7 @@ gm200_flcn_pio_dmem_wr_init(struct nvkm_falcon *falcon, u8 port, bool sec, u32 d const struct nvkm_falcon_func_pio gm200_flcn_dmem_pio = { - .min = 4, + .min = 1, .max = 0x100, .wr_init = gm200_flcn_pio_dmem_wr_init, .wr = gm200_flcn_pio_dmem_wr, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c index a72403777329..2ed04da3621d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c @@ -225,7 +225,7 @@ gm20b_pmu_init(struct nvkm_pmu *pmu) pmu->initmsg_received = false; - nvkm_falcon_load_dmem(falcon, &args, addr_args, sizeof(args), 0); + nvkm_falcon_pio_wr(falcon, (u8 *)&args, 0, 0, DMEM, addr_args, sizeof(args), 0, false); nvkm_falcon_start(falcon); return 0; } -- 2.35.1
Re: [REGRESSION] GM20B probe fails after commit 2541626cfb79
On Fri, 20 Jan 2023 at 21:37, Diogo Ivo wrote: > > On Wed, Jan 18, 2023 at 11:28:49AM +1000, Ben Skeggs wrote: > > On Mon, 16 Jan 2023 at 22:27, Diogo Ivo > > wrote: > > > On Mon, Jan 16, 2023 at 07:45:05AM +1000, David Airlie wrote: > > > > As a quick check can you try changing > > > > > > > > drivers/gpu/drm/nouveau/nvkm/core/firmware.c:nvkm_firmware_mem_target > > > > from NVKM_MEM_TARGET_HOST to NVKM_MEM_TARGET_NCOH ? > > > In addition to Dave's change, can you try changing the > > nvkm_falcon_load_dmem() call in gm20b_pmu_init() to: > > > > nvkm_falcon_pio_wr(falcon, (u8 *)&args, 0, 0, DMEM, addr_args, > > sizeof(args), 0, false); > > Hello! > > Chiming in just to say that with this change I see the same as Nicolas > except that the init message size is 255 instead of 0: > > [2.196934] nouveau 5700.gpu: pmu: unexpected init message size 255 vs > 42 I've attached an entirely untested patch (to go on top of the other hacks/fixes so far), that will hopefully get us a little further. Would be great if you guys could test it out for me. Thanks, Ben. diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c index 393ade9f7e6c..b7da3ab44c27 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c @@ -48,6 +48,16 @@ gm200_flcn_pio_dmem_rd(struct nvkm_falcon *falcon, u8 port, const u8 *img, int l img += 4; len -= 4; } + + /* Sigh. Tegra PMU FW's init message... */ + if (len) { + u32 data = nvkm_falcon_rd32(falcon, 0x1c4 + (port * 8)); + + while (len--) { + *(u8 *)img++ = data & 0xff; + data >>= 8; + } + } } static void @@ -64,6 +74,8 @@ gm200_flcn_pio_dmem_wr(struct nvkm_falcon *falcon, u8 port, const u8 *img, int l img += 4; len -= 4; } + + WARN_ON(len); } static void @@ -74,7 +86,7 @@ gm200_flcn_pio_dmem_wr_init(struct nvkm_falcon *falcon, u8 port, bool sec, u32 d const struct nvkm_falcon_func_pio gm200_flcn_dmem_pio = { - .min = 4, + .min = 1, .max = 0x100, .wr_init = gm200_flcn_pio_dmem_wr_init, .wr = gm200_flcn_pio_dmem_wr,
Re: [REGRESSION] GM20B probe fails after commit 2541626cfb79
On Mon, 16 Jan 2023 at 22:27, Diogo Ivo wrote: > > On Mon, Jan 16, 2023 at 07:45:05AM +1000, David Airlie wrote: > > On Thu, Dec 29, 2022 at 12:58 AM Diogo Ivo > > wrote: > > As a quick check can you try changing > > > > drivers/gpu/drm/nouveau/nvkm/core/firmware.c:nvkm_firmware_mem_target > > from NVKM_MEM_TARGET_HOST to NVKM_MEM_TARGET_NCOH ? > > Hello! > > Applying this change breaks probing in a different way, with a > bad PC=0x0. From a quick look at nvkm_falcon_load_dmem it looks like this > could happen due to the .load_dmem() callback not being properly > initialized. This is the kernel log I got: In addition to Dave's change, can you try changing the nvkm_falcon_load_dmem() call in gm20b_pmu_init() to: nvkm_falcon_pio_wr(falcon, (u8 *)&args, 0, 0, DMEM, addr_args, sizeof(args), 0, false); Ben. > > [2.010601] Unable to handle kernel NULL pointer dereference at virtual > address > [2.019436] Mem abort info: > [2.022273] ESR = 0x8605 > [2.026066] EC = 0x21: IABT (current EL), IL = 32 bits > [2.031429] SET = 0, FnV = 0 > [2.034528] EA = 0, S1PTW = 0 > [2.037694] FSC = 0x05: level 1 translation fault > [2.042572] [] user address but active_mm is swapper > [2.048961] Internal error: Oops: 8605 [#1] SMP > [2.054529] Modules linked in: > [2.057582] CPU: 0 PID: 36 Comm: kworker/u8:1 Not tainted 6.2.0-rc3+ #2 > [2.064190] Hardware name: Google Pixel C (DT) > [2.068628] Workqueue: events_unbound deferred_probe_work_func > [2.074463] pstate: 4005 (nZcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) > [2.081417] pc : 0x0 > [2.083600] lr : nvkm_falcon_load_dmem+0x58/0x80 > [2.088218] sp : ffc009ddb6f0 > [2.091526] x29: ffc009ddb6f0 x28: ff808028a008 x27: > ff8081e43c38 > [2.098658] x26: 00ff x25: ff808028a0a0 x24: > > [2.105788] x23: ff8080c328f8 x22: 002c x21: > 5fd4 > [2.112917] x20: ffc009ddb76c x19: ff8080c328b8 x18: > > [2.120047] x17: 2e74696e695f646f x16: 6874656d5f77732f x15: > > [2.127176] x14: 02f546c2 x13: x12: > 01ce > [2.134306] x11: 0001 x10: 0a90 x9 : > ffc009ddb600 > [2.141436] x8 : ff80803d19f0 x7 : ff80bf971180 x6 : > 01b9 > [2.148565] x5 : x4 : x3 : > 002c > [2.155693] x2 : 5fd4 x1 : ffc009ddb76c x0 : > ff8080c328b8 > [2.162822] Call trace: > [2.165264] 0x0 > [2.167099] gm20b_pmu_init+0x78/0xb4 > [2.170762] nvkm_pmu_init+0x20/0x34 > [2.174334] nvkm_subdev_init_+0x60/0x12c > [2.178339] nvkm_subdev_init+0x60/0xa0 > [2.182171] nvkm_device_init+0x14c/0x2a0 > [2.186178] nvkm_udevice_init+0x60/0x9c > [2.190097] nvkm_object_init+0x48/0x1b0 > [2.194013] nvkm_ioctl_new+0x168/0x254 > [2.197843] nvkm_ioctl+0xd0/0x220 > [2.201239] nvkm_client_ioctl+0x10/0x1c > [2.205160] nvif_object_ctor+0xf4/0x22c > [2.209079] nvif_device_ctor+0x28/0x70 > [2.212910] nouveau_cli_init+0x150/0x590 > [2.216916] nouveau_drm_device_init+0x60/0x2a0 > [2.221442] nouveau_platform_device_create+0x90/0xd0 > [2.226489] nouveau_platform_probe+0x3c/0x9c > [2.230841] platform_probe+0x68/0xc0 > [2.234500] really_probe+0xbc/0x2dc > [2.238070] __driver_probe_device+0x78/0xe0 > [2.242334] driver_probe_device+0xd8/0x160 > [2.246511] __device_attach_driver+0xb8/0x134 > [2.250948] bus_for_each_drv+0x78/0xd0 > [2.254782] __device_attach+0x9c/0x1a0 > [2.258612] device_initial_probe+0x14/0x20 > [2.262789] bus_probe_device+0x98/0xa0 > [2.266619] deferred_probe_work_func+0x88/0xc0 > [2.271142] process_one_work+0x204/0x40c > [2.275150] worker_thread+0x230/0x450 > [2.278894] kthread+0xc8/0xcc > [2.281946] ret_from_fork+0x10/0x20 > [2.285525] Code: bad PC value > [2.288576] ---[ end trace ]--- > > Diogo
[PULL] nouveau-next
Hey Dave, This is the pull request for a whole bunch of fixes and prep-work that was done to support Ampere acceleration prior to GSP-RM being available. It uses the ACR firmware released by NVIDIA in linux-firmware, as we do on earlier GPUs. The work to support running on top of GSP-RM also heavily depends on various pieces of this series. In addition to the new HW support, general stability of the driver should be improved, especially around recovering HW from bugs that can be generated by userspace driver components. Thanks, Ben. The following changes since commit 60ba8c5bd94e17ab4b024f5cecf8b48e2cf36412: Merge tag 'drm-intel-gt-next-2022-11-03' of git://anongit.freedesktop.org/drm/drm-intel into drm-next (2022-11-04 17:33:34 +1000) are available in the Git repository at: https://gitlab.freedesktop.org/skeggsb/nouveau.git 00.06-gr-ampere for you to fetch changes up to 6dd08133e9f705f6565e18f114cfeca3f3a6970a: drm/nouveau/gr/ga102: initial support (2022-11-08 15:46:01 +1000) -------- Ben Skeggs (124): drm/nouveau/disp: move and extend the role of outp acquire/release methods drm/nouveau/disp: move LVDS protocol information into acquire drm/nouveau/disp: move HDMI config into acquire + infoframe methods drm/nouveau/disp: move HDA ELD method drm/nouveau/disp: move DP link config into acquire drm/nouveau/disp: add method to control DPAUX pad power drm/nouveau/kms: switch hpd_lock from mutex to spinlock drm/nouveau/kms: pass event mask to hpd handler drm/nouveau/disp: add method to trigger DP link retrain drm/nouveau/disp: move DP MST payload config method drm/nouveau/disp: add head class drm/nouveau/disp: move head scanoutpos method drm/nouveau/nvkm: add a replacement for nvkm_notify drm/nouveau/fault: switch non-replayable faults to nvkm_event_ntfy drm/nouveau/fault: expose replayable fault buffer event class drm/nouveau/disp: switch vblank semaphore release to nvkm_event_ntfy drm/nouveau/disp: expose head event class drm/nouveau/disp: expose conn event class drm/nouveau/disp: expose page flip event class drm/nouveau/fifo: expose non-stall intr in host channel event class drm/nouveau/fifo: expose channel killed in host channel event class drm/nouveau/nvkm: rip out old notify drm/nouveau/kms: switch to drm fbdev helpers drm/nouveau/nvkm: give each nvkm_event its own lockdep class drm/nouveau/top: parse device topology right after devinit drm/nouveau/intr: add shared interrupt plumbing between pci/tegra drm/nouveau/intr: support multiple trees, and explicit interfaces drm/nouveau/intr: add nvkm_subdev_intr() compatibility drm/nouveau/vfn: add stub subdev for dev_func drm/nouveau/vfn: move NV_USERMODE class from host drm/nouveau/vfn/tu102-: support new-style interrupt tree drm/nouveau/fault/tu102: switch to explicit intr handlers drm/nouveau/fault/ga100: initial support drm/nouveau/mc: implement intr handling on top of nvkm_intr drm/nouveau/mc: move NV_PMC_ENABLE bashing to chipset-specific code drm/nouveau/mc/ga100: switch to using NV_PMC_DEVICE_ENABLE drm/nouveau/nvkm: add locking to subdev/engine init paths drm/nouveau/flcn: show falcon user in debug output drm/nouveau/imem: allow bar2 mapping of user allocations drm/nouveau/fifo: add chid_nr() drm/nouveau/fifo: unify handling of channel classes drm/nouveau/fifo: pre-move some blocks of code around drm/nouveau/fifo: merge gk104_fifo_func into nvkm_host_func drm/nouveau/fifo: add chid allocator drm/nouveau/fifo: add runq drm/nouveau/fifo: add common runlist/engine topology drm/nouveau/fifo: expose runlist topology info on all chipsets drm/nouveau/fifo: expose per-runlist CHID information drm/nouveau/fifo: add cgrp, have all channels be part of one drm/nouveau/fifo: use runlist engine info to lookup engine classes drm/nouveau/fifo: use explicit intr interfaces drm/nouveau/fifo: tidy up non-stall intr handling drm/nouveau/fifo: tidy global PBDMA init drm/nouveau/fifo: program NV_PFIFO_FB_TIMEOUT on init drm/nouveau/fifo: move PBDMA init to runq drm/nouveau/fifo: move PBDMA intr to runq drm/nouveau/fifo: merge mmu fault handlers together drm/nouveau/fifo: add new channel lookup interfaces drm/nouveau/fifo: add new engine context tracking drm/nouveau/fifo: add runlist wait() drm/nouveau/fifo: add runlist block()/allow() drm/nouveau/fifo: add chan bind()/unbind() drm/nouveau/fifo: add chan start()/stop() drm/nouveau/fifo: add chan/cgrp preempt() drm/nouveau/fifo: kill channel on a selection of PBDMA errors drm/nouveau/fifo: kill channel on NV_PPBDMA_INTR_1_CTXNOTVALID drm/nouveau
Re: [PATCH] drm/nouveau/bios: Rename prom_init() and friends functions
On Sat, 19 Mar 2022 at 04:11, Lyude Paul wrote: > > Whoops, sorry! I was unsure of the preference in name we should go with so I > poked Ben on the side to ask them, but I can see they haven't yet responded. > I'll poke thme again and see if I can get a response. Yeah, please keep _prom as opposed to _rom. It's a reference to the NV_PROM device. Ben. > > On Fri, 2022-03-18 at 10:55 +0100, Christophe Leroy wrote: > > Hi Paul, > > > > Le 05/03/2022 à 10:51, Christophe Leroy a écrit : > > > > > > > > > Le 05/03/2022 à 08:38, Christophe Leroy a écrit : > > > > > > > > > > > > Le 04/03/2022 à 21:24, Lyude Paul a écrit : > > > > > This mostly looks good to me. Just one question (and one comment down > > > > > below > > > > > that needs addressing). Is this with ppc32? (I ask because ppc64le > > > > > doesn't > > > > > seem to hit this compilation error). > > > > > > > > That's with PPC64, see > > > > http://kisskb.ellerman.id.au/kisskb/branch/chleroy/head/252ba609bea83234d2e35841c19ae84c67b43ec7/ > > > > > > > > > > > > > > > > But that's not (yet) with the mainline tree. That's work I'm doing to > > > > cleanup our asm/asm-protoypes.h header. > > > > > > > > Since commit 4efca4ed05cb ("kbuild: modversions for EXPORT_SYMBOL() > > > > for asm") that file is dedicated to prototypes of functions defined in > > > > assembly. Therefore I'm trying to dispatch C functions prototypes in > > > > other headers. I wanted to move prom_init() prototype into asm/prom.h > > > > and then I hit the problem. > > > > > > > > In the beginning I was thinking about just changing the name of the > > > > function in powerpc, but as I see that M68K, MIPS and SPARC also have > > > > a prom_init() function, I thought it would be better to change the > > > > name in shadowrom.c to avoid any future conflict like the one I got > > > > while reworking the headers. > > > > > > > > > > > > > > @@ -57,8 +57,8 @@ prom_init(struct nvkm_bios *bios, const char > > > > > > *name) > > > > > > const struct nvbios_source > > > > > > nvbios_rom = { > > > > > > .name = "PROM", > > > > > > - .init = prom_init, > > > > > > - .fini = prom_fini, > > > > > > - .read = prom_read, > > > > > > + .init = nvbios_rom_init, > > > > > > + .fini = nvbios_rom_fini, > > > > > > + .read = nvbios_rom_read, > > > > > > > > > > Seeing as the source name is prom, I think using the naming convention > > > > > nvbios_prom_* would be better then nvbios_rom_*. > > > > > > > > > > > > > Yes I wasn't sure about the best naming as the file name is > > > > shadowrom.c and not shadowprom.c. > > > > > > > > I will send v2 using nvbios_prom_* as a name. > > > > > > While preparing v2 I remembered that in fact, I called the functions > > > nvbios_rom_* because the name of the nvbios_source struct is nvbios_rom, > > > so for me it made sense to use the name of the struct as a prefix for > > > the functions. > > > > > > So I'm OK to change it to nvbios_prom_* but it looks less logical to me. > > > > > > Please confirm you still prefer nvbios_prom as prefix to the function > > > names. > > > > > > > Are you still expecting a v2 for this patch ? > > > > As the name of the structure is nvbios_rom, do you really prefer the > > functions to be called nvbios_prom_* as you mentionned in your comment ? > > > > In that case, do you also expect the structure name to be changed to > > nvbios_prom ? > > > > Thanks > > Christophe > > > > -- > Cheers, > Lyude Paul (she/her) > Software Engineer at Red Hat >
Re: [Nouveau] [PATCH] drm/nouveau: wait for the exclusive fence after the shared ones v2
On Tue, 14 Dec 2021 at 19:19, Christian König wrote: > > Am 11.12.21 um 10:59 schrieb Stefan Fritsch: > > On 09.12.21 11:23, Christian König wrote: > >> Always waiting for the exclusive fence resulted on some performance > >> regressions. So try to wait for the shared fences first, then the > >> exclusive fence should always be signaled already. > >> > >> v2: fix incorrectly placed "(", add some comment why we do this. > >> > >> Signed-off-by: Christian König > > > > Tested-by: Stefan Fritsch > > Thanks. > > > > > Please also add a cc for linux-stable, so that this is fixed in 5.15.x > > Sure, but I still need some acked-by or rb from one of the Nouveau guys. > So gentle ping on that. Acked-by: Ben Skeggs > > Regards, > Christian. > > > > > Cheers, > > Stefan > > > >> --- > >> drivers/gpu/drm/nouveau/nouveau_fence.c | 28 + > >> 1 file changed, 15 insertions(+), 13 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c > >> b/drivers/gpu/drm/nouveau/nouveau_fence.c > >> index 05d0b3eb3690..0ae416aa76dc 100644 > >> --- a/drivers/gpu/drm/nouveau/nouveau_fence.c > >> +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c > >> @@ -353,15 +353,22 @@ nouveau_fence_sync(struct nouveau_bo *nvbo, > >> struct nouveau_channel *chan, bool e > >> if (ret) > >> return ret; > >> -} > >> -fobj = dma_resv_shared_list(resv); > >> -fence = dma_resv_excl_fence(resv); > >> +fobj = NULL; > >> +} else { > >> +fobj = dma_resv_shared_list(resv); > >> +} > >> -if (fence) { > >> +/* Waiting for the exclusive fence first causes performance > >> regressions > >> + * under some circumstances. So manually wait for the shared > >> ones first. > >> + */ > >> +for (i = 0; i < (fobj ? fobj->shared_count : 0) && !ret; ++i) { > >> struct nouveau_channel *prev = NULL; > >> bool must_wait = true; > >> +fence = rcu_dereference_protected(fobj->shared[i], > >> +dma_resv_held(resv)); > >> + > >> f = nouveau_local_fence(fence, chan->drm); > >> if (f) { > >> rcu_read_lock(); > >> @@ -373,20 +380,13 @@ nouveau_fence_sync(struct nouveau_bo *nvbo, > >> struct nouveau_channel *chan, bool e > >> if (must_wait) > >> ret = dma_fence_wait(fence, intr); > >> - > >> -return ret; > >> } > >> -if (!exclusive || !fobj) > >> -return ret; > >> - > >> -for (i = 0; i < fobj->shared_count && !ret; ++i) { > >> +fence = dma_resv_excl_fence(resv); > >> +if (fence) { > >> struct nouveau_channel *prev = NULL; > >> bool must_wait = true; > >> -fence = rcu_dereference_protected(fobj->shared[i], > >> -dma_resv_held(resv)); > >> - > >> f = nouveau_local_fence(fence, chan->drm); > >> if (f) { > >> rcu_read_lock(); > >> @@ -398,6 +398,8 @@ nouveau_fence_sync(struct nouveau_bo *nvbo, > >> struct nouveau_channel *chan, bool e > >> if (must_wait) > >> ret = dma_fence_wait(fence, intr); > >> + > >> +return ret; > >> } > >> return ret; >
Re: [Nouveau] [PATCH] drm/nouveau/acr: fix a couple NULL vs IS_ERR() checks
On Thu, 18 Nov 2021 at 21:13, Dan Carpenter wrote: > > The nvkm_acr_lsfw_add() function never returns NULL. It returns error > pointers on error. > > Fixes: 22dcda45a3d1 ("drm/nouveau/acr: implement new subdev to replace > "secure boot"") > Signed-off-by: Dan Carpenter Reviewed-by: Ben Skeggs > --- > drivers/gpu/drm/nouveau/nvkm/subdev/acr/gm200.c | 6 -- > drivers/gpu/drm/nouveau/nvkm/subdev/acr/gp102.c | 6 -- > 2 files changed, 8 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/gm200.c > b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/gm200.c > index cdb1ead26d84..82b4c8e1457c 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/gm200.c > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/gm200.c > @@ -207,11 +207,13 @@ int > gm200_acr_wpr_parse(struct nvkm_acr *acr) > { > const struct wpr_header *hdr = (void *)acr->wpr_fw->data; > + struct nvkm_acr_lsfw *lsfw; > > while (hdr->falcon_id != WPR_HEADER_V0_FALCON_ID_INVALID) { > wpr_header_dump(&acr->subdev, hdr); > - if (!nvkm_acr_lsfw_add(NULL, acr, NULL, (hdr++)->falcon_id)) > - return -ENOMEM; > + lsfw = nvkm_acr_lsfw_add(NULL, acr, NULL, (hdr++)->falcon_id); > + if (IS_ERR(lsfw)) > + return PTR_ERR(lsfw); > } > > return 0; > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/gp102.c > b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/gp102.c > index fb9132a39bb1..fd97a935a380 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/gp102.c > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/gp102.c > @@ -161,11 +161,13 @@ int > gp102_acr_wpr_parse(struct nvkm_acr *acr) > { > const struct wpr_header_v1 *hdr = (void *)acr->wpr_fw->data; > + struct nvkm_acr_lsfw *lsfw; > > while (hdr->falcon_id != WPR_HEADER_V1_FALCON_ID_INVALID) { > wpr_header_v1_dump(&acr->subdev, hdr); > - if (!nvkm_acr_lsfw_add(NULL, acr, NULL, (hdr++)->falcon_id)) > - return -ENOMEM; > + lsfw = nvkm_acr_lsfw_add(NULL, acr, NULL, (hdr++)->falcon_id); > + if (IS_ERR(lsfw)) > + return PTR_ERR(lsfw); > } > > return 0; > -- > 2.20.1 >
Re: [Nouveau] [PATCH] MAINTAINERS: update information for nouveau
On Wed, 10 Nov 2021 at 23:32, Karol Herbst wrote: > > Some side notes on this. Atm we do want to use gitlab for bug tracking and > merge requests. But due to the nature of the current linux kernel > development, we can only do so for nouveau internal changes. > > Everything else still needs to be sent as emails and this is also includes > changes to UAPI etc. > > Anyway, if somebody wants to submit patches via gitlab, they are free to > do so and this should just make this more official and documented. > > People listed as maintainers are such that have push access to drm-misc > (where changes are pushed to after landing in gitlab) and are known > nouveau developers. > We did this already for some trivial changes and critical bug fixes > already, we just weren't thinking about updating the MAINTAINERS file. > > Cc: Ben Skeggs > Cc: Lyude Paul > Cc: David Airlie > Cc: Daniel Vetter > Cc: dri-devel@lists.freedesktop.org > Cc: nouv...@lists.freedesktop.org > Signed-off-by: Karol Herbst Signed-off-by: Ben Skeggs > --- > MAINTAINERS | 9 - > 1 file changed, 8 insertions(+), 1 deletion(-) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 8805df335326..270dc9c0a427 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -5961,10 +5961,17 @@ F: drivers/gpu/drm/panel/panel-novatek-nt36672a.c > > DRM DRIVER FOR NVIDIA GEFORCE/QUADRO GPUS > M: Ben Skeggs > +M: Karol Herbst > +M: Lyude Paul > L: dri-devel@lists.freedesktop.org > L: nouv...@lists.freedesktop.org > S: Supported > -T: git git://github.com/skeggsb/linux > +W: https://nouveau.freedesktop.org/ > +Q: https://patchwork.freedesktop.org/project/nouveau/ > +Q: https://gitlab.freedesktop.org/drm/nouveau/-/merge_requests > +B: https://gitlab.freedesktop.org/drm/nouveau/-/issues > +C: irc://irc.oftc.net/nouveau > +T: git https://gitlab.freedesktop.org/drm/nouveau.git > F: drivers/gpu/drm/nouveau/ > F: include/uapi/drm/nouveau_drm.h > > -- > 2.33.1 >
Re: [Nouveau] [PATCH] drm/nouveau: set RGB quantization range to FULL
On Thu, 11 Nov 2021 at 01:58, Hans Verkuil wrote: > > The nouveau driver outputs full range RGB, but the AVI InfoFrame just says > 'Default' instead of 'Full'. > > Call drm_hdmi_avi_infoframe_quant_range to fill in the quantization field of > the AVI InfoFrame correctly. Now displays that advertise RGB Selectable > Quantization Range in their EDID will understand that full range is > transmitted > by the HDMI output. This is consistent to how the Nvidia's driver behaves. > > Signed-off-by: Hans Verkuil Reviewed-by: Ben Skeggs > --- > diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c > b/drivers/gpu/drm/nouveau/dispnv50/disp.c > index d7b9f7f8c9e3..b05c01927fe6 100644 > --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c > +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c > @@ -852,6 +852,9 @@ nv50_hdmi_enable(struct drm_encoder *encoder, struct > nouveau_crtc *nv_crtc, > ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame.avi, >&nv_connector->base, > mode); > if (!ret) { > + drm_hdmi_avi_infoframe_quant_range(&avi_frame.avi, > + &nv_connector->base, mode, > + > HDMI_QUANTIZATION_RANGE_FULL); > /* We have an AVI InfoFrame, populate it to the display */ > args.pwr.avi_infoframe_length > = hdmi_infoframe_pack(&avi_frame, args.infoframes, > 17);
Re: [Nouveau] [PATCH] drm/nouveau: hdmigv100.c: fix corrupted HDMI Vendor InfoFrame
On Thu, 11 Nov 2021 at 01:43, Hans Verkuil wrote: > > gv100_hdmi_ctrl() writes vendor_infoframe.subpack0_high to 0x6f0110, and > then overwrites it with 0. Just drop the overwrite with 0, that's clearly > a mistake. > > Because of this issue the HDMI VIC is 0 instead of 1 in the HDMI Vendor > InfoFrame when transmitting 4kp30. > > Signed-off-by: Hans Verkuil > Fixes: 290ffeafcc1a (drm/nouveau/disp/gv100: initial support) Reviewed-by: Ben Skeggs > --- > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c > b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c > index 6e3c450eaace..3ff49344abc7 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c > @@ -62,7 +62,6 @@ gv100_hdmi_ctrl(struct nvkm_ior *ior, int head, bool > enable, u8 max_ac_packet, > nvkm_wr32(device, 0x6f0108 + hdmi, vendor_infoframe.header); > nvkm_wr32(device, 0x6f010c + hdmi, > vendor_infoframe.subpack0_low); > nvkm_wr32(device, 0x6f0110 + hdmi, > vendor_infoframe.subpack0_high); > - nvkm_wr32(device, 0x6f0110 + hdmi, 0x); > nvkm_wr32(device, 0x6f0114 + hdmi, 0x); > nvkm_wr32(device, 0x6f0118 + hdmi, 0x); > nvkm_wr32(device, 0x6f011c + hdmi, 0x); >
Re: [PATCH v1 2/7] nouveau: ACPI: Use the ACPI_COMPANION() macro directly
On Wed, 13 Oct 2021 at 03:58, Rafael J. Wysocki wrote: > > From: Rafael J. Wysocki > > The ACPI_HANDLE() macro is a wrapper arond the ACPI_COMPANION() > macro and the ACPI handle produced by the former comes from the > ACPI device object produced by the latter, so it is way more > straightforward to evaluate the latter directly instead of passing > the handle produced by the former to acpi_bus_get_device(). > > Modify nouveau_acpi_edid() accordingly (no intentional functional > impact). > > Signed-off-by: Rafael J. Wysocki Reviewed-by: Ben Skeggs > --- > drivers/gpu/drm/nouveau/nouveau_acpi.c |9 ++--- > 1 file changed, 2 insertions(+), 7 deletions(-) > > Index: linux-pm/drivers/gpu/drm/nouveau/nouveau_acpi.c > === > --- linux-pm.orig/drivers/gpu/drm/nouveau/nouveau_acpi.c > +++ linux-pm/drivers/gpu/drm/nouveau/nouveau_acpi.c > @@ -364,7 +364,6 @@ void * > nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) > { > struct acpi_device *acpidev; > - acpi_handle handle; > int type, ret; > void *edid; > > @@ -377,12 +376,8 @@ nouveau_acpi_edid(struct drm_device *dev > return NULL; > } > > - handle = ACPI_HANDLE(dev->dev); > - if (!handle) > - return NULL; > - > - ret = acpi_bus_get_device(handle, &acpidev); > - if (ret) > + acpidev = ACPI_COMPANION(dev->dev); > + if (!acpidev) > return NULL; > > ret = acpi_video_get_edid(acpidev, type, -1, &edid); > > >
Re: [Nouveau] [PATCH] drm/nouveau/mmu/gp100: remove unused variable
On Tue, 12 Oct 2021 at 23:33, Karol Herbst wrote: > > Fixes a compilation issue introduced because I forgot to test with WERROR > enabled. > > Cc: Stephen Rothwell > Cc: DRI > Cc: nouv...@lists.freedesktop.org > Fixes: 404046cf4805 ("drm/nouveau/mmu/gp100-: drop unneeded assignment in the > if condition.") > Signed-off-by: Karol Herbst Reviewed-by: Ben Skeggs > --- > drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c > b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c > index 2b21f43069aa..17899fc95b2d 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c > @@ -488,7 +488,7 @@ gp100_vmm_fault_cancel(struct nvkm_vmm *vmm, void *argv, > u32 argc) > struct gp100_vmm_fault_cancel_v0 v0; > } *args = argv; > int ret = -ENOSYS; > - u32 inst, aper; > + u32 aper; > > if ((ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) > return ret; > -- > 2.31.1 >
Re: [PATCH] drm/nouveau/fifo: Reinstate the correct engine bit programming
On Fri, 8 Oct 2021 at 07:46, Karol Herbst wrote: > > Reviewed-by: Karol Herbst Reviewed-by: Ben Skeggs > > I haven't checked if other places need fixing up yet, and I still want > to test this patch, but I won't get to it until Monday. But if > everything is in place we can get this pushed next week so we can > finally fix this annoying issue :) I was also seeing some minor > graphical corruptions which would be cool if this patch fixes it as > well. > > Thanks for the patch and poking us about the bug again. > > On Thu, Oct 7, 2021 at 11:41 PM Marek Vasut wrote: > > > > Commit 64f7c698bea9 ("drm/nouveau/fifo: add engine_id hook") replaced > > fifo/chang84.c g84_fifo_chan_engine() call with an indirect call of > > fifo/g84.c g84_fifo_engine_id(). The G84_FIFO_ENGN_* values returned > > from the later g84_fifo_engine_id() are incremented by 1 compared to > > the previous g84_fifo_chan_engine() return values. > > > > This is fine either way for most of the code, except this one line > > where an engine bit programmed into the hardware is derived from the > > return value. Decrement the return value accordingly, otherwise the > > wrong engine bit is programmed into the hardware and that leads to > > the following failure: > > nouveau :01:00.0: gr: 0030 [ILLEGAL_MTHD ILLEGAL_CLASS] ch 1 > > [003fbce000 DRM] subc 3 class mthd 085c data 0420 > > > > On the following hardware: > > lspci -s 01:00.0 > > 01:00.0 VGA compatible controller: NVIDIA Corporation GT216GLM [Quadro FX > > 880M] (rev a2) > > lspci -ns 01:00.0 > > 01:00.0 0300: 10de:0a3c (rev a2) > > > > Fixes: 64f7c698bea9 ("drm/nouveau/fifo: add engine_id hook") > > Signed-off-by: Marek Vasut > > Cc: # 5.12+ > > Cc: Ben Skeggs > > Cc: Karol Herbst > > Cc: Lyude Paul > > --- > > drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c > > b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c > > index 353b77d9b3dc..3492c561f2cf 100644 > > --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c > > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c > > @@ -82,7 +82,7 @@ g84_fifo_chan_engine_fini(struct nvkm_fifo_chan *base, > > if (offset < 0) > > return 0; > > > > - engn = fifo->base.func->engine_id(&fifo->base, engine); > > + engn = fifo->base.func->engine_id(&fifo->base, engine) - 1; > > save = nvkm_mask(device, 0x002520, 0x003f, 1 << engn); > > nvkm_wr32(device, 0x0032fc, chan->base.inst->addr >> 12); > > done = nvkm_msec(device, 2000, > > -- > > 2.33.0 > > >
[PATCH] drm/nouveau/fifo/ga102: initialise chid on return from channel creation
From: Ben Skeggs Turns out caller isn't zero-initialised after-all. Fixes: 6b457230bfa1 ("drm/nouveau/ga102-: support ttm buffer moves via copy engine") Reported-by: Karol Herbst Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c index f897bef13acf..c630dbd2911a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c @@ -179,6 +179,9 @@ ga102_chan_new(struct nvkm_device *device, return -ENODEV; chan->ctrl.chan = nvkm_rd32(device, chan->ctrl.runl + 0x004) & 0xfff0; + + args->chid = 0; + args->inst = 0; args->token = nvkm_rd32(device, chan->ctrl.runl + 0x008) & 0x; ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->mthd); -- 2.31.1
[PATCH v2] drm/nouveau/ga102-: support ttm buffer moves via copy engine
From: Ben Skeggs We don't currently have any kind of real acceleration on Ampere GPUs, but the TTM memcpy() fallback paths aren't really designed to handle copies between different devices, such as on Optimus systems, and result in a kernel OOPS. A few options were investigated to try and fix this, but didn't work out, and likely would have resulted in a very unpleasant experience for users anyway. This commit adds just enough support for setting up a single channel connected to a copy engine, which the kernel can use to accelerate the buffer copies between devices. Userspace has no access to this incomplete channel support, but it's suitable for TTM's needs. A more complete implementation of host(fifo) for Ampere GPUs is in the works, but the required changes are far too invasive that they would be unsuitable to backport to fix this issue on current kernels. v2: fix GPFIFO length in RAMFC (reported by Karol) Signed-off-by: Ben Skeggs Cc: Lyude Paul Cc: Karol Herbst Cc: # v5.12+ Reviewed-by: Karol Herbst Signed-off-by: Karol Herbst Link: https://patchwork.freedesktop.org/patch/msgid/20210906005628.11499-1-skeg...@gmail.com --- drivers/gpu/drm/nouveau/include/nvif/class.h | 2 + .../drm/nouveau/include/nvkm/engine/fifo.h| 1 + drivers/gpu/drm/nouveau/nouveau_bo.c | 1 + drivers/gpu/drm/nouveau/nouveau_chan.c| 6 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 4 + drivers/gpu/drm/nouveau/nv84_fence.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/device/base.c | 3 + .../gpu/drm/nouveau/nvkm/engine/fifo/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/ga102.c | 308 ++ .../gpu/drm/nouveau/nvkm/subdev/top/ga100.c | 7 +- 10 files changed, 329 insertions(+), 6 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index c68cc957248e..a582c0cb0cb0 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -71,6 +71,7 @@ #define PASCAL_CHANNEL_GPFIFO_A /* cla06f.h */ 0xc06f #define VOLTA_CHANNEL_GPFIFO_A/* clc36f.h */ 0xc36f #define TURING_CHANNEL_GPFIFO_A /* clc36f.h */ 0xc46f +#define AMPERE_CHANNEL_GPFIFO_B /* clc36f.h */ 0xc76f #define NV50_DISP /* cl5070.h */ 0x5070 #define G82_DISP /* cl5070.h */ 0x8270 @@ -200,6 +201,7 @@ #define PASCAL_DMA_COPY_B0xc1b5 #define VOLTA_DMA_COPY_A 0xc3b5 #define TURING_DMA_COPY_A0xc5b5 +#define AMPERE_DMA_COPY_B0xc7b5 #define FERMI_DECOMPRESS 0x90b8 diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h index 54fab7cc36c1..64ee82c7c1be 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h @@ -77,4 +77,5 @@ int gp100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct int gp10b_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **); int gv100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **); int tu102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **); +int ga102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **); #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 6d07e653f82d..c58bcdba2c7a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -844,6 +844,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm) struct ttm_resource *, struct ttm_resource *); int (*init)(struct nouveau_channel *, u32 handle); } _methods[] = { + { "COPY", 4, 0xc7b5, nve0_bo_move_copy, nve0_bo_move_init }, { "COPY", 4, 0xc5b5, nve0_bo_move_copy, nve0_bo_move_init }, { "GRCE", 0, 0xc5b5, nve0_bo_move_copy, nvc0_bo_move_init }, { "COPY", 4, 0xc3b5, nve0_bo_move_copy, nve0_bo_move_init }, diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 80099ef75702..ea7769135b0d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -250,7 +250,8 @@ static int nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, u64 runlist, b
Re: [PATCH 1/2] drm/nouveau/ga102-: support ttm buffer moves via copy engine
On Thu, 9 Sept 2021 at 04:19, Daniel Vetter wrote: > > On Mon, Sep 06, 2021 at 10:56:27AM +1000, Ben Skeggs wrote: > > From: Ben Skeggs > > > > We don't currently have any kind of real acceleration on Ampere GPUs, > > but the TTM memcpy() fallback paths aren't really designed to handle > > copies between different devices, such as on Optimus systems, and > > result in a kernel OOPS. > > Is this just for moving a buffer from vram to system memory when you pin > it for dma-buf? I'm kinda lost what you even use ttm bo moves for if > there's no one using the gpu. It occurs when we attempt to move the buffer into vram for scanout, through the modeset paths. > > Also I guess memcpy goes boom if you can't mmap it because it's outside > the gart? Or just that it's very slow. We're trying to use ttm memcyp as > fallback, so want to know how this can all go wrong :-) Neither ttm_kmap_iter_linear_io_init() nor ttm_kmap_iter_tt_init() are able to work with the imported dma-buf object, which can obviously be fixed. But. I then attempted to hack that up with a custom memcpy() for that situation to test it, using dma_buf_vmap(), and get stuck forever inside i915 waiting for the gem object lock. Ben. > -Daniel > > > > > A few options were investigated to try and fix this, but didn't work > > out, and likely would have resulted in a very unpleasant experience > > for users anyway. > > > > This commit adds just enough support for setting up a single channel > > connected to a copy engine, which the kernel can use to accelerate > > the buffer copies between devices. Userspace has no access to this > > incomplete channel support, but it's suitable for TTM's needs. > > > > A more complete implementation of host(fifo) for Ampere GPUs is in > > the works, but the required changes are far too invasive that they > > would be unsuitable to backport to fix this issue on current kernels. > > > > Signed-off-by: Ben Skeggs > > Cc: Lyude Paul > > Cc: Karol Herbst > > Cc: # v5.12+ > > --- > > drivers/gpu/drm/nouveau/include/nvif/class.h | 2 + > > .../drm/nouveau/include/nvkm/engine/fifo.h| 1 + > > drivers/gpu/drm/nouveau/nouveau_bo.c | 1 + > > drivers/gpu/drm/nouveau/nouveau_chan.c| 6 +- > > drivers/gpu/drm/nouveau/nouveau_drm.c | 4 + > > drivers/gpu/drm/nouveau/nv84_fence.c | 2 +- > > .../gpu/drm/nouveau/nvkm/engine/device/base.c | 3 + > > .../gpu/drm/nouveau/nvkm/engine/fifo/Kbuild | 1 + > > .../gpu/drm/nouveau/nvkm/engine/fifo/ga102.c | 308 ++ > > .../gpu/drm/nouveau/nvkm/subdev/top/ga100.c | 7 +- > > 10 files changed, 329 insertions(+), 6 deletions(-) > > create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c > > > > diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h > > b/drivers/gpu/drm/nouveau/include/nvif/class.h > > index c68cc957248e..a582c0cb0cb0 100644 > > --- a/drivers/gpu/drm/nouveau/include/nvif/class.h > > +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h > > @@ -71,6 +71,7 @@ > > #define PASCAL_CHANNEL_GPFIFO_A /* cla06f.h */ > > 0xc06f > > #define VOLTA_CHANNEL_GPFIFO_A/* clc36f.h */ > > 0xc36f > > #define TURING_CHANNEL_GPFIFO_A /* clc36f.h */ > > 0xc46f > > +#define AMPERE_CHANNEL_GPFIFO_B /* clc36f.h */ > > 0xc76f > > > > #define NV50_DISP /* cl5070.h */ > > 0x5070 > > #define G82_DISP /* cl5070.h */ > > 0x8270 > > @@ -200,6 +201,7 @@ > > #define PASCAL_DMA_COPY_B > > 0xc1b5 > > #define VOLTA_DMA_COPY_A > > 0xc3b5 > > #define TURING_DMA_COPY_A > > 0xc5b5 > > +#define AMPERE_DMA_COPY_B > > 0xc7b5 > > > > #define FERMI_DECOMPRESS > > 0x90b8 > > > > diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h > > b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h > > index 54fab7cc36c1..64ee82c7c1be 100644 > > --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h > > +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h > > @@ -77,4 +77,5 @@ int gp100_fifo_new(struct nvkm_device *, enum > > nvkm_subdev_typ
Re: [PATCH 1/2] drm/nouveau/ga102-: support ttm buffer moves via copy engine
On Tue, 7 Sept 2021 at 10:28, Karol Herbst wrote: > > On Tue, Sep 7, 2021 at 1:28 AM Ben Skeggs wrote: > > > > On Tue, 7 Sept 2021 at 09:17, Karol Herbst wrote: > > > > > > ." > > > > > > > > > On Mon, Sep 6, 2021 at 2:56 AM Ben Skeggs wrote: > > > > > > > > From: Ben Skeggs > > > > > > > > We don't currently have any kind of real acceleration on Ampere GPUs, > > > > but the TTM memcpy() fallback paths aren't really designed to handle > > > > copies between different devices, such as on Optimus systems, and > > > > result in a kernel OOPS. > > > > > > > > A few options were investigated to try and fix this, but didn't work > > > > out, and likely would have resulted in a very unpleasant experience > > > > for users anyway. > > > > > > > > This commit adds just enough support for setting up a single channel > > > > connected to a copy engine, which the kernel can use to accelerate > > > > the buffer copies between devices. Userspace has no access to this > > > > incomplete channel support, but it's suitable for TTM's needs. > > > > > > > > A more complete implementation of host(fifo) for Ampere GPUs is in > > > > the works, but the required changes are far too invasive that they > > > > would be unsuitable to backport to fix this issue on current kernels. > > > > > > > > Signed-off-by: Ben Skeggs > > > > Cc: Lyude Paul > > > > Cc: Karol Herbst > > > > Cc: # v5.12+ > > > > --- > > > > drivers/gpu/drm/nouveau/include/nvif/class.h | 2 + > > > > .../drm/nouveau/include/nvkm/engine/fifo.h| 1 + > > > > drivers/gpu/drm/nouveau/nouveau_bo.c | 1 + > > > > drivers/gpu/drm/nouveau/nouveau_chan.c| 6 +- > > > > drivers/gpu/drm/nouveau/nouveau_drm.c | 4 + > > > > drivers/gpu/drm/nouveau/nv84_fence.c | 2 +- > > > > .../gpu/drm/nouveau/nvkm/engine/device/base.c | 3 + > > > > .../gpu/drm/nouveau/nvkm/engine/fifo/Kbuild | 1 + > > > > .../gpu/drm/nouveau/nvkm/engine/fifo/ga102.c | 308 ++ > > > > .../gpu/drm/nouveau/nvkm/subdev/top/ga100.c | 7 +- > > > > 10 files changed, 329 insertions(+), 6 deletions(-) > > > > create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c > > > > > > > > diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h > > > > b/drivers/gpu/drm/nouveau/include/nvif/class.h > > > > index c68cc957248e..a582c0cb0cb0 100644 > > > > --- a/drivers/gpu/drm/nouveau/include/nvif/class.h > > > > +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h > > > > @@ -71,6 +71,7 @@ > > > > #define PASCAL_CHANNEL_GPFIFO_A /* cla06f.h */ > > > > 0xc06f > > > > #define VOLTA_CHANNEL_GPFIFO_A/* clc36f.h */ > > > > 0xc36f > > > > #define TURING_CHANNEL_GPFIFO_A /* clc36f.h */ > > > > 0xc46f > > > > +#define AMPERE_CHANNEL_GPFIFO_B /* clc36f.h */ > > > > 0xc76f > > > > > > > > #define NV50_DISP /* cl5070.h */ > > > > 0x5070 > > > > #define G82_DISP /* cl5070.h */ > > > > 0x8270 > > > > @@ -200,6 +201,7 @@ > > > > #define PASCAL_DMA_COPY_B > > > > 0xc1b5 > > > > #define VOLTA_DMA_COPY_A > > > > 0xc3b5 > > > > #define TURING_DMA_COPY_A > > > > 0xc5b5 > > > > +#define AMPERE_DMA_COPY_B > > > > 0xc7b5 > > > > > > > > #define FERMI_DECOMPRESS > > > > 0x90b8 > > > > > > > > diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h > > > > b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h > > > > index 54fab7cc36c1..64ee82c7c1be 100644 > > > > --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h > > > > +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h > > > > @@ -77,4 +77
Re: [PATCH 1/2] drm/nouveau/ga102-: support ttm buffer moves via copy engine
On Tue, 7 Sept 2021 at 09:17, Karol Herbst wrote: > > ." > > > On Mon, Sep 6, 2021 at 2:56 AM Ben Skeggs wrote: > > > > From: Ben Skeggs > > > > We don't currently have any kind of real acceleration on Ampere GPUs, > > but the TTM memcpy() fallback paths aren't really designed to handle > > copies between different devices, such as on Optimus systems, and > > result in a kernel OOPS. > > > > A few options were investigated to try and fix this, but didn't work > > out, and likely would have resulted in a very unpleasant experience > > for users anyway. > > > > This commit adds just enough support for setting up a single channel > > connected to a copy engine, which the kernel can use to accelerate > > the buffer copies between devices. Userspace has no access to this > > incomplete channel support, but it's suitable for TTM's needs. > > > > A more complete implementation of host(fifo) for Ampere GPUs is in > > the works, but the required changes are far too invasive that they > > would be unsuitable to backport to fix this issue on current kernels. > > > > Signed-off-by: Ben Skeggs > > Cc: Lyude Paul > > Cc: Karol Herbst > > Cc: # v5.12+ > > --- > > drivers/gpu/drm/nouveau/include/nvif/class.h | 2 + > > .../drm/nouveau/include/nvkm/engine/fifo.h| 1 + > > drivers/gpu/drm/nouveau/nouveau_bo.c | 1 + > > drivers/gpu/drm/nouveau/nouveau_chan.c| 6 +- > > drivers/gpu/drm/nouveau/nouveau_drm.c | 4 + > > drivers/gpu/drm/nouveau/nv84_fence.c | 2 +- > > .../gpu/drm/nouveau/nvkm/engine/device/base.c | 3 + > > .../gpu/drm/nouveau/nvkm/engine/fifo/Kbuild | 1 + > > .../gpu/drm/nouveau/nvkm/engine/fifo/ga102.c | 308 ++ > > .../gpu/drm/nouveau/nvkm/subdev/top/ga100.c | 7 +- > > 10 files changed, 329 insertions(+), 6 deletions(-) > > create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c > > > > diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h > > b/drivers/gpu/drm/nouveau/include/nvif/class.h > > index c68cc957248e..a582c0cb0cb0 100644 > > --- a/drivers/gpu/drm/nouveau/include/nvif/class.h > > +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h > > @@ -71,6 +71,7 @@ > > #define PASCAL_CHANNEL_GPFIFO_A /* cla06f.h */ > > 0xc06f > > #define VOLTA_CHANNEL_GPFIFO_A/* clc36f.h */ > > 0xc36f > > #define TURING_CHANNEL_GPFIFO_A /* clc36f.h */ > > 0xc46f > > +#define AMPERE_CHANNEL_GPFIFO_B /* clc36f.h */ > > 0xc76f > > > > #define NV50_DISP /* cl5070.h */ > > 0x5070 > > #define G82_DISP /* cl5070.h */ > > 0x8270 > > @@ -200,6 +201,7 @@ > > #define PASCAL_DMA_COPY_B > > 0xc1b5 > > #define VOLTA_DMA_COPY_A > > 0xc3b5 > > #define TURING_DMA_COPY_A > > 0xc5b5 > > +#define AMPERE_DMA_COPY_B > > 0xc7b5 > > > > #define FERMI_DECOMPRESS > > 0x90b8 > > > > diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h > > b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h > > index 54fab7cc36c1..64ee82c7c1be 100644 > > --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h > > +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h > > @@ -77,4 +77,5 @@ int gp100_fifo_new(struct nvkm_device *, enum > > nvkm_subdev_type, int inst, struct > > int gp10b_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, > > struct nvkm_fifo **); > > int gv100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, > > struct nvkm_fifo **); > > int tu102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, > > struct nvkm_fifo **); > > +int ga102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, > > struct nvkm_fifo **); > > #endif > > diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c > > b/drivers/gpu/drm/nouveau/nouveau_bo.c > > index 4a7cebac8060..b3e4f555fa05 100644 > > --- a/drivers/gpu/drm/nouveau/nouveau_bo.c > > +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c > > @@ -844,6 +844,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm) > >
[PATCH 2/2] drm/nouveau/kms/tu102-: delay enabling cursor until after assign_windows
From: Ben Skeggs Prevent NVD core channel error code 67 occuring and hanging display, managed to reproduce on GA102 while testing suspend/resume scenarios. Required extension of earlier commit to fix interactions with EFI. Fixes: e78b1b545c6c ("drm/nouveau/kms/nv50: workaround EFI GOP window channel format differences"). Signed-off-by: Ben Skeggs Cc: Lyude Paul Cc: Karol Herbst Cc: # v5.12+ --- drivers/gpu/drm/nouveau/dispnv50/head.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c index f8438a886b64..c3c57be54e1c 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head.c @@ -52,6 +52,7 @@ nv50_head_flush_clr(struct nv50_head *head, void nv50_head_flush_set_wndw(struct nv50_head *head, struct nv50_head_atom *asyh) { + if (asyh->set.curs ) head->func->curs_set(head, asyh); if (asyh->set.olut ) { asyh->olut.offset = nv50_lut_load(&head->olut, asyh->olut.buffer, @@ -67,7 +68,6 @@ nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh) if (asyh->set.view ) head->func->view(head, asyh); if (asyh->set.mode ) head->func->mode(head, asyh); if (asyh->set.core ) head->func->core_set(head, asyh); - if (asyh->set.curs ) head->func->curs_set(head, asyh); if (asyh->set.base ) head->func->base(head, asyh); if (asyh->set.ovly ) head->func->ovly(head, asyh); if (asyh->set.dither ) head->func->dither (head, asyh); -- 2.31.1
[PATCH 1/2] drm/nouveau/ga102-: support ttm buffer moves via copy engine
From: Ben Skeggs We don't currently have any kind of real acceleration on Ampere GPUs, but the TTM memcpy() fallback paths aren't really designed to handle copies between different devices, such as on Optimus systems, and result in a kernel OOPS. A few options were investigated to try and fix this, but didn't work out, and likely would have resulted in a very unpleasant experience for users anyway. This commit adds just enough support for setting up a single channel connected to a copy engine, which the kernel can use to accelerate the buffer copies between devices. Userspace has no access to this incomplete channel support, but it's suitable for TTM's needs. A more complete implementation of host(fifo) for Ampere GPUs is in the works, but the required changes are far too invasive that they would be unsuitable to backport to fix this issue on current kernels. Signed-off-by: Ben Skeggs Cc: Lyude Paul Cc: Karol Herbst Cc: # v5.12+ --- drivers/gpu/drm/nouveau/include/nvif/class.h | 2 + .../drm/nouveau/include/nvkm/engine/fifo.h| 1 + drivers/gpu/drm/nouveau/nouveau_bo.c | 1 + drivers/gpu/drm/nouveau/nouveau_chan.c| 6 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 4 + drivers/gpu/drm/nouveau/nv84_fence.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/device/base.c | 3 + .../gpu/drm/nouveau/nvkm/engine/fifo/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/ga102.c | 308 ++ .../gpu/drm/nouveau/nvkm/subdev/top/ga100.c | 7 +- 10 files changed, 329 insertions(+), 6 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index c68cc957248e..a582c0cb0cb0 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -71,6 +71,7 @@ #define PASCAL_CHANNEL_GPFIFO_A /* cla06f.h */ 0xc06f #define VOLTA_CHANNEL_GPFIFO_A/* clc36f.h */ 0xc36f #define TURING_CHANNEL_GPFIFO_A /* clc36f.h */ 0xc46f +#define AMPERE_CHANNEL_GPFIFO_B /* clc36f.h */ 0xc76f #define NV50_DISP /* cl5070.h */ 0x5070 #define G82_DISP /* cl5070.h */ 0x8270 @@ -200,6 +201,7 @@ #define PASCAL_DMA_COPY_B0xc1b5 #define VOLTA_DMA_COPY_A 0xc3b5 #define TURING_DMA_COPY_A0xc5b5 +#define AMPERE_DMA_COPY_B0xc7b5 #define FERMI_DECOMPRESS 0x90b8 diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h index 54fab7cc36c1..64ee82c7c1be 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h @@ -77,4 +77,5 @@ int gp100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct int gp10b_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **); int gv100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **); int tu102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **); +int ga102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **); #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 4a7cebac8060..b3e4f555fa05 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -844,6 +844,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm) struct ttm_resource *, struct ttm_resource *); int (*init)(struct nouveau_channel *, u32 handle); } _methods[] = { + { "COPY", 4, 0xc7b5, nve0_bo_move_copy, nve0_bo_move_init }, { "COPY", 4, 0xc5b5, nve0_bo_move_copy, nve0_bo_move_init }, { "GRCE", 0, 0xc5b5, nve0_bo_move_copy, nvc0_bo_move_init }, { "COPY", 4, 0xc3b5, nve0_bo_move_copy, nve0_bo_move_init }, diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 80099ef75702..ea7769135b0d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -250,7 +250,8 @@ static int nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, u64 runlist, bool priv, struct nouveau_channel **pchan) { - static const u16 oclasses[] = { TURING_CHANNEL_GPFIFO_A, + static const u16 oclasses[] = { AMPERE_CHANNEL_GPFIFO_B
Re: [PATCH] drm/ttm: Fix ttm_bo_move_memcpy() for subclassed struct ttm_resource
On Mon, 30 Aug 2021 at 17:48, Thomas Hellström wrote: > > The code was making a copy of a struct ttm_resource. However, > recently the struct ttm_resources were allowed to be subclassed and > also were allowed to be malloced, hence the driver could end up assuming > the copy we handed it was subclassed and worse, the original could have > been freed at this point. > > Fix this by using the original struct ttm_resource before it is > potentially freed in ttm_bo_move_sync_cleanup() > > Reported-by: Ben Skeggs > Reported-by: Dave Airlie > Cc: Christian König > Fixes: 3bf3710e3718 ("drm/ttm: Add a generic TTM memcpy move for page-based > iomem") > Signed-off-by: Thomas Hellström That's basically identical to what I came up with locally, so: Reviewed-by: Ben Skeggs > --- > drivers/gpu/drm/ttm/ttm_bo_util.c | 6 ++ > 1 file changed, 2 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c > b/drivers/gpu/drm/ttm/ttm_bo_util.c > index 5c20d0541cc3..c893c3db2623 100644 > --- a/drivers/gpu/drm/ttm/ttm_bo_util.c > +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c > @@ -139,7 +139,6 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, > struct ttm_resource *src_mem = bo->resource; > struct ttm_resource_manager *src_man = > ttm_manager_type(bdev, src_mem->mem_type); > - struct ttm_resource src_copy = *src_mem; > union { > struct ttm_kmap_iter_tt tt; > struct ttm_kmap_iter_linear_io io; > @@ -173,11 +172,10 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, > if (!(clear && ttm && !(ttm->page_flags & TTM_PAGE_FLAG_ZERO_ALLOC))) > ttm_move_memcpy(clear, dst_mem->num_pages, dst_iter, > src_iter); > > - src_copy = *src_mem; > + if (!src_iter->ops->maps_tt) > + ttm_kmap_iter_linear_io_fini(&_src_iter.io, bdev, src_mem); > ttm_bo_move_sync_cleanup(bo, dst_mem); > > - if (!src_iter->ops->maps_tt) > - ttm_kmap_iter_linear_io_fini(&_src_iter.io, bdev, &src_copy); > out_src_iter: > if (!dst_iter->ops->maps_tt) > ttm_kmap_iter_linear_io_fini(&_dst_iter.io, bdev, dst_mem); > -- > 2.31.1 >
[PULL] nouveau-fixes 5.14
Hey, Just a couple fixes for Ampere display issues, and a long-standing race in MM paths. Ben. The following changes since commit 7c60610d476766e128cc4284bb6349732cbd6606: Linux 5.14-rc6 (2021-08-15 13:40:53 -1000) are available in the Git repository at: git://github.com/skeggsb/linux linux-5.14 for you to fetch changes up to 59f216cf04d973b4316761cbf3e7cb9556715b7a: drm/nouveau: rip out nvkm_client.super (2021-08-18 19:00:15 +1000) Ben Skeggs (6): drm/nouveau: recognise GA107 drm/nouveau/disp: power down unused DP links during init drm/nouveau/kms/nv50: workaround EFI GOP window channel format differences drm/nouveau/fifo/nv50-: rip out dma channels drm/nouveau: block a bunch of classes from userspace drm/nouveau: rip out nvkm_client.super drivers/gpu/drm/nouveau/dispnv50/disp.c| 27 +++ drivers/gpu/drm/nouveau/dispnv50/head.c| 13 -- drivers/gpu/drm/nouveau/dispnv50/head.h| 1 + drivers/gpu/drm/nouveau/include/nvif/cl0080.h | 3 +- drivers/gpu/drm/nouveau/include/nvif/class.h | 2 - drivers/gpu/drm/nouveau/include/nvif/client.h | 1 - drivers/gpu/drm/nouveau/include/nvif/driver.h | 2 +- drivers/gpu/drm/nouveau/include/nvkm/core/client.h | 1 - drivers/gpu/drm/nouveau/include/nvkm/core/ioctl.h | 2 +- drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 1 - drivers/gpu/drm/nouveau/nouveau_abi16.c| 2 - drivers/gpu/drm/nouveau/nouveau_chan.c | 19 +--- drivers/gpu/drm/nouveau/nouveau_drm.c | 3 +- drivers/gpu/drm/nouveau/nouveau_mem.c | 15 +- drivers/gpu/drm/nouveau/nouveau_nvif.c | 4 +- drivers/gpu/drm/nouveau/nouveau_svm.c | 9 drivers/gpu/drm/nouveau/nouveau_usif.c | 57 +-- drivers/gpu/drm/nouveau/nvif/client.c | 3 +- drivers/gpu/drm/nouveau/nvif/object.c | 3 +- drivers/gpu/drm/nouveau/nvkm/core/ioctl.c | 4 +- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 21 + drivers/gpu/drm/nouveau/nvkm/engine/device/user.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c| 9 drivers/gpu/drm/nouveau/nvkm/engine/dma/user.c | 15 -- drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild| 2 - drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h| 2 - drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmag84.c | 94 -- drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv50.c | 92 - drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c | 1 - drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c | 2 - drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c | 2 - drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifotu102.c | 2 - drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c| 1 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.c | 6 +-- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.h | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c | 27 +++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 6 +-- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c | 16 +++ 41 files changed, 144 insertions(+), 334 deletions(-) delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmag84.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv50.c
Re: [PATCH v8 8/8] nouveau/svm: Implement atomic SVM access
On Wed, 7 Apr 2021 at 18:43, Alistair Popple wrote: > > Some NVIDIA GPUs do not support direct atomic access to system memory > via PCIe. Instead this must be emulated by granting the GPU exclusive > access to the memory. This is achieved by replacing CPU page table > entries with special swap entries that fault on userspace access. > > The driver then grants the GPU permission to update the page undergoing > atomic access via the GPU page tables. When CPU access to the page is > required a CPU fault is raised which calls into the device driver via > MMU notifiers to revoke the atomic access. The original page table > entries are then restored allowing CPU access to proceed. > > Signed-off-by: Alistair Popple The Nouveau bits at least look good to me. For patches 7/8: Reviewed-by: Ben Skeggs > > --- > > v7: > * Removed magic values for fault access levels > * Improved readability of fault comparison code > > v4: > * Check that page table entries haven't changed before mapping on the > device > --- > drivers/gpu/drm/nouveau/include/nvif/if000c.h | 1 + > drivers/gpu/drm/nouveau/nouveau_svm.c | 126 -- > drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 1 + > .../drm/nouveau/nvkm/subdev/mmu/vmmgp100.c| 6 + > 4 files changed, 123 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/include/nvif/if000c.h > b/drivers/gpu/drm/nouveau/include/nvif/if000c.h > index d6dd40f21eed..9c7ff56831c5 100644 > --- a/drivers/gpu/drm/nouveau/include/nvif/if000c.h > +++ b/drivers/gpu/drm/nouveau/include/nvif/if000c.h > @@ -77,6 +77,7 @@ struct nvif_vmm_pfnmap_v0 { > #define NVIF_VMM_PFNMAP_V0_APER > 0x00f0ULL > #define NVIF_VMM_PFNMAP_V0_HOST > 0xULL > #define NVIF_VMM_PFNMAP_V0_VRAM > 0x0010ULL > +#define NVIF_VMM_PFNMAP_V0_A > 0x0004ULL > #define NVIF_VMM_PFNMAP_V0_W > 0x0002ULL > #define NVIF_VMM_PFNMAP_V0_V > 0x0001ULL > #define NVIF_VMM_PFNMAP_V0_NONE > 0xULL > diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.c > b/drivers/gpu/drm/nouveau/nouveau_svm.c > index a195e48c9aee..81526d65b4e2 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_svm.c > +++ b/drivers/gpu/drm/nouveau/nouveau_svm.c > @@ -35,6 +35,7 @@ > #include > #include > #include > +#include > > struct nouveau_svm { > struct nouveau_drm *drm; > @@ -67,6 +68,11 @@ struct nouveau_svm { > } buffer[1]; > }; > > +#define FAULT_ACCESS_READ 0 > +#define FAULT_ACCESS_WRITE 1 > +#define FAULT_ACCESS_ATOMIC 2 > +#define FAULT_ACCESS_PREFETCH 3 > + > #define SVM_DBG(s,f,a...) NV_DEBUG((s)->drm, "svm: "f"\n", ##a) > #define SVM_ERR(s,f,a...) NV_WARN((s)->drm, "svm: "f"\n", ##a) > > @@ -411,6 +417,24 @@ nouveau_svm_fault_cancel_fault(struct nouveau_svm *svm, > fault->client); > } > > +static int > +nouveau_svm_fault_priority(u8 fault) > +{ > + switch (fault) { > + case FAULT_ACCESS_PREFETCH: > + return 0; > + case FAULT_ACCESS_READ: > + return 1; > + case FAULT_ACCESS_WRITE: > + return 2; > + case FAULT_ACCESS_ATOMIC: > + return 3; > + default: > + WARN_ON_ONCE(1); > + return -1; > + } > +} > + > static int > nouveau_svm_fault_cmp(const void *a, const void *b) > { > @@ -421,9 +445,8 @@ nouveau_svm_fault_cmp(const void *a, const void *b) > return ret; > if ((ret = (s64)fa->addr - fb->addr)) > return ret; > - /*XXX: atomic? */ > - return (fa->access == 0 || fa->access == 3) - > - (fb->access == 0 || fb->access == 3); > + return nouveau_svm_fault_priority(fa->access) - > + nouveau_svm_fault_priority(fb->access); > } > > static void > @@ -487,6 +510,10 @@ static bool nouveau_svm_range_invalidate(struct > mmu_interval_notifier *mni, > struct svm_notifier *sn = > container_of(mni, struct svm_notifier, notifier); > > + if (range->event == MMU_NOTIFY_EXCLUSIVE && > + range->owner == sn->svmm->vmm->cli->drm->dev) > + return true; > + > /* > * serializes the update to mni->invalidate_seq done by caller and >
[PULL] nouveau-fixes 5.12
Single regression fix. Thanks, Ben. The following changes since commit d27ce83fa4baa5cb908a42e9878564cad6ea0eb3: Merge tag 'du-fixes-20210316' of git://linuxtv.org/pinchartl/media into drm-fixes (2021-03-22 13:49:55 +1000) are available in the Git repository at: git://github.com/skeggsb/linux linux-5.12 for you to fetch changes up to d3999c1f7bbbc100c167d7ad3cd79c1d10446ba2: drm/nouveau/kms/nve4-nv108: Limit cursors to 128x128 (2021-03-25 10:00:04 +1000) Lyude Paul (1): drm/nouveau/kms/nve4-nv108: Limit cursors to 128x128 drivers/gpu/drm/nouveau/dispnv50/disp.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Nouveau] [PATCH] drm/nouveau/kms/nv04: use vzalloc for nv04_display
On Mon, 8 Mar 2021 at 03:49, Ilia Mirkin wrote: > > The struct is giant, and triggers an order-7 allocation (512K). There is > no reason for this to be kmalloc-type memory, so switch to vmalloc. This > should help loading nouveau on low-memory and/or long-running systems. > > Reported-by: Nathan E. Egge > Signed-off-by: Ilia Mirkin > Cc: sta...@vger.kernel.org Thanks! > --- > drivers/gpu/drm/nouveau/dispnv04/disp.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.c > b/drivers/gpu/drm/nouveau/dispnv04/disp.c > index 7739f46470d3..99fee4d8cd31 100644 > --- a/drivers/gpu/drm/nouveau/dispnv04/disp.c > +++ b/drivers/gpu/drm/nouveau/dispnv04/disp.c > @@ -205,7 +205,7 @@ nv04_display_destroy(struct drm_device *dev) > nvif_notify_dtor(&disp->flip); > > nouveau_display(dev)->priv = NULL; > - kfree(disp); > + vfree(disp); > > nvif_object_unmap(&drm->client.device.object); > } > @@ -223,7 +223,7 @@ nv04_display_create(struct drm_device *dev) > struct nv04_display *disp; > int i, ret; > > - disp = kzalloc(sizeof(*disp), GFP_KERNEL); > + disp = vzalloc(sizeof(*disp)); > if (!disp) > return -ENOMEM; > > -- > 2.26.2 > > ___ > Nouveau mailing list > nouv...@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/nouveau ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] nouveau/nvkm/subdev/devinit/mcp89.c:Unneeded variable
On Wed, 17 Mar 2021 at 19:51, ChunyouTang wrote: > > From: tangchunyou > > disable,delete disable and return 0 > > Signed-off-by: tangchunyou Thanks! > --- > drivers/gpu/drm/nouveau/nvkm/subdev/devinit/mcp89.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/mcp89.c > b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/mcp89.c > index fb90d47..a9cdf24 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/mcp89.c > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/mcp89.c > @@ -32,7 +32,6 @@ > struct nvkm_device *device = init->subdev.device; > u32 r001540 = nvkm_rd32(device, 0x001540); > u32 r00154c = nvkm_rd32(device, 0x00154c); > - u64 disable = 0; > > if (!(r001540 & 0x4000)) { > nvkm_subdev_disable(device, NVKM_ENGINE_MSPDEC, 0); > @@ -48,7 +47,7 @@ > if (!(r00154c & 0x0200)) > nvkm_subdev_disable(device, NVKM_ENGINE_CE, 0); > > - return disable; > + return 0; > } > > static const struct nvkm_devinit_func > -- > 1.9.1 > > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2] drm/nouveau/kms/nv50-: Correct size checks for cursors
On Fri, 19 Mar 2021 at 09:04, Lyude Paul wrote: > > Found this while trying to make some changes to the kms_cursor_crc test. > curs507a_acquire checks that the width and height of the cursor framebuffer > are equal (asyw->image.{w,h}). This isn't entirely correct though, as the > height of the cursor can be larger than the size of the cursor, as long as > the width is the same as the cursor size and there's no framebuffer offset. > > Note that I'm not entirely sure why this wasn't previously breaking > kms_cursor_crc tests - they all set up cursors with the height being one > pixel larger than the actual size of the cursor. But this seems to fix > things, and the code before was definitely incorrect - so it's not really > worth looking into further imho. > > Changes since v1: > * Don't use crtc_w everywhere for determining cursor layout, just use fb > size again > * Change check so that we only check that the w/h of the cursor plane is > the same, the width of the scanout surface is the same as the framebuffer > width, and that there's no offset being used for the cursor surface. > > Signed-off-by: Lyude Paul > Cc: Martin Peres > Cc: Jeremy Cline Thanks Lyude! > --- > drivers/gpu/drm/nouveau/dispnv50/curs507a.c | 15 ++- > 1 file changed, 14 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c > b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c > index 54fbd6fe751d..00e19fd959ea 100644 > --- a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c > +++ b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c > @@ -98,6 +98,7 @@ static int > curs507a_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, > struct nv50_head_atom *asyh) > { > + struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev); > struct nv50_head *head = nv50_head(asyw->state.crtc); > int ret; > > @@ -109,8 +110,20 @@ curs507a_acquire(struct nv50_wndw *wndw, struct > nv50_wndw_atom *asyw, > if (ret || !asyh->curs.visible) > return ret; > > - if (asyw->image.w != asyw->image.h) > + if (asyw->state.crtc_w != asyw->state.crtc_h) { > + NV_ATOMIC(drm, "Plane width/height must be equal for > cursors\n"); > return -EINVAL; > + } > + > + if (asyw->image.w != asyw->state.crtc_w) { > + NV_ATOMIC(drm, "Plane width must be equal to fb width for > cursors (height can be larger though)\n"); > + return -EINVAL; > + } > + > + if (asyw->state.src_x || asyw->state.src_y) { > + NV_ATOMIC(drm, "Cursor planes do not support framebuffer > offsets\n"); > + return -EINVAL; > + } > > ret = head->func->curs_layout(head, asyw, asyh); > if (ret) > -- > 2.29.2 > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Nouveau] [PATCH -next] drm/nouveau/core/client: Mark nvkm_uclient_sclass with static keyword
On Tue, 23 Mar 2021 at 17:03, Zou Wei wrote: > > Fix the following sparse warning: > > drivers/gpu/drm/nouveau/nvkm/core/client.c:64:1: warning: symbol > 'nvkm_uclient_sclass' was not declared. Should it be static? > > Signed-off-by: Zou Wei Applied, thanks. > --- > drivers/gpu/drm/nouveau/nvkm/core/client.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/nouveau/nvkm/core/client.c > b/drivers/gpu/drm/nouveau/nvkm/core/client.c > index ac671202919e..0c8c55c73b12 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/core/client.c > +++ b/drivers/gpu/drm/nouveau/nvkm/core/client.c > @@ -60,7 +60,7 @@ nvkm_uclient_new(const struct nvkm_oclass *oclass, void > *argv, u32 argc, > return 0; > } > > -const struct nvkm_sclass > +static const struct nvkm_sclass > nvkm_uclient_sclass = { > .oclass = NVIF_CLASS_CLIENT, > .minver = 0, > -- > 2.17.1 > > ___ > Nouveau mailing list > nouv...@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/nouveau ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PULL] nouveau-fixes 5.12
Hey, A single regression fix here that I noticed while testing a bunch of boards for something else, not sure where this got lost! Prevents 3D driver from initialising on some GPUs. Ben. The following changes since commit f6df392dddbb9e637b785e7e3d9337a74923dc10: drm/nouveau/top/ga100: initial support (2021-02-11 11:50:04 +1000) are available in the Git repository at: git://github.com/skeggsb/linux 00.00-inst for you to fetch changes up to 78652ff69be439f7e925067c6a61b1839e531c01: drm/nouveau/fifo/gk104-gp1xx: fix creation of sw class (2021-03-02 21:48:42 +1000) Ben Skeggs (1): drm/nouveau/fifo/gk104-gp1xx: fix creation of sw class drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 3 +++ 1 file changed, 3 insertions(+) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2] drm/nouveau/pmu: fix timeout on GP108
On Wed, 17 Feb 2021 at 13:30, Alexandre Courbot wrote: > > On Wed, Feb 17, 2021 at 1:20 AM Diego Viola wrote: > > > > This code times out on GP108, probably because the BIOS puts it into a > > bad state. > > > > Since we reset the PMU on driver load anyway, we are at no risk from > > missing a response from it since we are not waiting for one to begin > > with. > > This looks safe to me, provided indeed that the PMU's reset is not > called outside of initialization (which for GP108 is shouldn't be > IIRC?). ISTR that the PMU FW we use prior to GM200 might depend on that being there. I've posted a proposed alternate fix here[1], as we probably shouldn't have been touching PMU there anyway on those GPUs. Ben. [1] https://github.com/skeggsb/linux/commit/90224a17437b1f39dbecbb385567c1fce958f992 > > > > > Signed-off-by: Diego Viola > > --- > > drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c | 6 +- > > 1 file changed, 1 insertion(+), 5 deletions(-) > > > > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c > > b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c > > index a0fe607c9c07..5c802f2d00cb 100644 > > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c > > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c > > @@ -102,12 +102,8 @@ nvkm_pmu_reset(struct nvkm_pmu *pmu) > > if (!pmu->func->enabled(pmu)) > > return 0; > > > > - /* Inhibit interrupts, and wait for idle. */ > > + /* Inhibit interrupts. */ > > nvkm_wr32(device, 0x10a014, 0x); > > - nvkm_msec(device, 2000, > > - if (!nvkm_rd32(device, 0x10a04c)) > > - break; > > - ); > > > > /* Reset. */ > > if (pmu->func->reset) > > -- > > 2.30.1 > > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PULL] nouveau-next 5.12
Hey, This is super late in the cycle, but after talking it over with Dave, it's probably best to get this in sooner rather than later. The vast majority of the changes are simple and repetitive, but invasive in that the constructor function signature of every sub-device module for every chipset is touched. The problem is that GA100 added enough new engine types and instances that we would have begun to overflow various u64 bitfields used to track the connections between various engines. A less-invasive solution that was considered would have been to begin to alias with engine types that no longer exist on newer hardware, but that'd have only gotten us so far for so long, and introduces the possibility of subtle and hard-to-detect bugs moving forward. Instead, rather than addressing subdevs by a unique index, we give each subdev a type and instance id, and replace the use of bitfields tied to subdev index with other methods. Notable changes: - replace subdev index with subdev type + instance id - engines that turn out to be fused-off (can't detect until later in init) no longer leave dangling pointers around - new subdev/instance additions no longer need to be made in multiple places - ampere engine topology is now being parsed Ben. The following changes since commit 4c3a3292730c56591472717d8c5c0faf74f6c6bb: drm/amd/display: fix unused variable warning (2021-02-05 09:49:44 +1000) are available in the Git repository at: git://github.com/skeggsb/linux 00.00-inst for you to fetch changes up to f6df392dddbb9e637b785e7e3d9337a74923dc10: drm/nouveau/top/ga100: initial support (2021-02-11 11:50:04 +1000) -------- Ben Skeggs (87): drm/nouveau/engine: use refcount_t + private mutex drm/nouveau/fb: protect comptags with private mutex drm/nouveau/fb: protect vram mm with private mutex drm/nouveau/instmem: protect mm/lru with private mutex drm/nouveau/ltc: serialise cbc operations with private mutex drm/nouveau/mmu: serialise mmu invalidations with private mutex drm/nouveau/pmu: serialise send() with private mutex drm/nouveau/disp: use private spinlock to control exclusive access to disp drm/nouveau/fifo: private mutex drm/nouveau/perfmon: use private spinlock to control exclusive access to perfmon drm/nouveau/subdev: remove nvkm_subdev.mutex drm/nouveau/subdev: store subdevs in list drm/nouveau/subdev: store full subdev name in struct drm/nouveau/subdev: track type+instance separately drm/nouveau/device: pass instance id when looking up a subdev/engine drm/nouveau/nvkm: add macros for subdev layout drm/nouveau/acr: switch to instanced constructor drm/nouveau/bar: switch to instanced constructor drm/nouveau/bios: switch to instanced constructor drm/nouveau/bus: switch to instanced constructor drm/nouveau/clk: switch to instanced constructor drm/nouveau/devinit: switch to instanced constructor drm/nouveau/fault: switch to instanced constructor drm/nouveau/fb: switch to instanced constructor drm/nouveau/fuse: switch to instanced constructor drm/nouveau/gpio: switch to instanced constructor drm/nouveau/gsp: switch to instanced constructor drm/nouveau/i2c: switch to instanced constructor drm/nouveau/ibus: switch to instanced constructor drm/nouveau/iccsense: switch to instanced constructor drm/nouveau/instmem: switch to instanced constructor drm/nouveau/ltc: switch to instanced constructor drm/nouveau/top: store device type and instance separately drm/nouveau/top: expose parsed device info more directly drm/nouveau/mc: switch to instanced constructor drm/nouveau/mc: lookup subdev interrupt handlers with split type+inst drm/nouveau/mc: use split type+inst in device reset APIs drm/nouveau/mc: use split type+inst in interrupt masking API drm/nouveau/mc: use split type+inst when handling dev_top interrupts drm/nouveau/mmu: switch to instanced constructor drm/nouveau/mmu: index engref by subdev type drm/nouveau/mxm: switch to instanced constructor drm/nouveau/pci: switch to instanced constructor drm/nouveau/pmu: switch to instanced constructor drm/nouveau/therm: switch to instanced constructor drm/nouveau/therm/gk104: use split subdev type+inst in cg engine lists drm/nouveau/tmr: switch to instanced constructor drm/nouveau/top: switch to instanced constructor drm/nouveau/volt: switch to instanced constructor drm/nouveau/bsp,vp: switch to instanced constructor drm/nouveau/falcon: use split type+inst when looking up PRI addr drm/nouveau/ce: switch to instanced constructor drm/nouveau/ce: make use of nvkm_subdev.inst drm/nouveau/cipher: switch to instanced constructor drm/nouveau/disp: switch to instanced constr
nouveau-next 5.12
Hey Dave, Nothing too major here, I actually thought I'd sent most of these right before the new year, but that apparently got lost in the bustle: - Turing MMU fault recovery fixes - Fix mDP connectors being reported as eDP to userspace - Fixes for audio locking, and other bit-rot from DRM changes since atomic support was written - Misc other minor fixes. Ben. The following changes since commit bc96ad6722f86a377ed2872c9a4854c90caf78ca: Merge tag 'v5.11-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux into drm-next (2021-01-25 14:35:44 +1000) are available in the Git repository at: git://github.com/skeggsb/linux linux-5.12 for you to fetch changes up to d1f5a3fc85566e9ddce9361ef180f070367e6eab: drm/nouveau/kms: handle mDP connectors (2021-01-29 16:49:15 +1000) Alistair Popple (5): drm/nouveau/mc/tu102: Fix MMU fault interrupts on Turing drm/nouveau/mc/tu102: Remove Turing interrupt hack drm/nouveau/fifo/tu102: Move Turing specific FIFO functions drm/nouveau/fifo/tu102: FIFO interrupt fixes for Turing drm/nouveau/fifo/tu102: Turing channel preemption fix Ben Skeggs (3): drm/nouveau/kms/nv50-gp1xx: wait for less EVO pushbuf space for core updates without notify drm/nouveau/kms/gv100-: wait for less NVD pushbuf space for core updates without notify drm/nouveau/kms/nv50-: add module option to select EVO/NVD push buffer location Frantisek Hrbata (1): drm/nouveau: bail out of nouveau_channel_new if channel init fails Karol Herbst (1): drm/nouveau/kms: handle mDP connectors Lyude Paul (9): drm/nouveau/kms/nv50-: Don't call HEAD_SET_CRC_CONTROL in head907d_mode() drm/nouveau/kms/nv50-: Log SOR/PIOR caps drm/nouveau/kms/nv50-: Remove (nv_encoder->crtc) checks in ->disable callbacks drm/nouveau/kms/nv50-: Rename encoder->atomic_(enable|disable) callbacks drm/nouveau/kms/nv50-: s/armh/asyh/ in nv50_msto_atomic_enable() drm/nouveau/kms/nv50-: Reverse args for nv50_outp_get_(old|new)_connector() drm/nouveau/kms/nv50-: Lookup current encoder/crtc from atomic state drm/nouveau/kms/nv50-: Use nouveau_encoder->crtc in get_eld callback drm/nouveau/kms/nv50-: Fix locking for audio callbacks drivers/gpu/drm/nouveau/dispnv50/core507d.c | 2 +- drivers/gpu/drm/nouveau/dispnv50/corec37d.c | 2 +- drivers/gpu/drm/nouveau/dispnv50/disp.c | 230 +-- drivers/gpu/drm/nouveau/dispnv50/head907d.c | 11 +- drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h | 1 + drivers/gpu/drm/nouveau/nouveau_chan.c | 1 + drivers/gpu/drm/nouveau/nouveau_connector.c | 1 + drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + drivers/gpu/drm/nouveau/nouveau_encoder.h | 13 +- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c| 46 ++--- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h| 32 drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c| 364 +++- drivers/gpu/drm/nouveau/nvkm/subdev/fault/tu102.c | 21 ++- drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c | 3 - drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h | 1 - drivers/gpu/drm/nouveau/nvkm/subdev/mc/tu102.c | 113 +-- 16 files changed, 675 insertions(+), 167 deletions(-) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PULL] nouveau-fixes 5.11
Hey Dave, Mostly a regression fixes here, a couple of which could lead to display hanging, and have been affecting a number of users. Ben. The following changes since commit 8ef23b6f6a79e6fa2a169081d2d76011fffa0482: drm/nouveau/disp/ga10[24]: initial support (2021-01-15 10:25:24 +1000) are available in the Git repository at: git://github.com/skeggsb/linux 04.01-ampere-lite for you to fetch changes up to d2be5ff9f287b8815c36e95ea34dc4b09f313c3b: drm/nouveau/kms/gk104-gp1xx: Fix > 64x64 cursors (2021-01-27 16:36:13 +1000) Bastian Beranek (1): drm/nouveau/dispnv50: Restore pushing of all data. Ben Skeggs (1): drm/nouveau/nvif: fix method count when pushing an array Karol Herbst (1): drm/nouveau/svm: fail NOUVEAU_SVM_INIT ioctl on unsupported devices Lyude Paul (3): drivers/nouveau/kms/nv50-: Reject format modifiers for cursor planes drm/nouveau/kms/nv50-: Report max cursor size to userspace drm/nouveau/kms/gk104-gp1xx: Fix > 64x64 cursors drivers/gpu/drm/nouveau/dispnv50/base507c.c | 6 ++- drivers/gpu/drm/nouveau/dispnv50/base827c.c | 6 ++- drivers/gpu/drm/nouveau/dispnv50/disp.c | 8 drivers/gpu/drm/nouveau/dispnv50/head917d.c | 28 ++- drivers/gpu/drm/nouveau/dispnv50/wndw.c | 17 +-- drivers/gpu/drm/nouveau/include/nvhw/class/cl917d.h | 4 ++ drivers/gpu/drm/nouveau/include/nvif/push.h | 216 ++-- drivers/gpu/drm/nouveau/nouveau_svm.c | 4 ++ 8 files changed, 174 insertions(+), 115 deletions(-) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PULL] nouveau: ampere modesetting
Hey Dave, This series of patches to add modesetting support for Ampere has been pulled out of a larger, more invasive series. As there's currently no firmware available for us to use, the rest of it isn't important right now, and it'd be nice to have something non-invasive to provide what support we currently can (and is possible to backport to earlier kernels). No other chipset should be impacted by these patches, as the changes are largely confined to adding Ampere versions of the code handling each IP block. I'd like to extend thanks to NVIDIA for providing hardware, and for their assistance with confirming/clarifying some of the changes. Ben. The following changes since commit caeb6ab899c3d36a74cda6e299c6e1c9c4e2a22e: drm/nouveau/kms/nv50-: fix case where notifier buffer is at offset 0 (2021-01-15 10:25:17 +1000) are available in the Git repository at: git://github.com/skeggsb/linux 04.01-ampere-lite for you to fetch changes up to 8ef23b6f6a79e6fa2a169081d2d76011fffa0482: drm/nouveau/disp/ga10[24]: initial support (2021-01-15 10:25:24 +1000) -------- Ben Skeggs (15): drm/nouveau/core: recognise GA10[024] drm/nouveau/pci/ga10[024]: initial support drm/nouveau/bios/ga10[024]: initial support drm/nouveau/devinit/ga10[024]: initial support drm/nouveau/mc/ga10[024]: initial support drm/nouveau/privring/ga10[024]: initial support drm/nouveau/imem/ga10[024]: initial support drm/nouveau/fb/ga10[024]: initial support drm/nouveau/timer/ga10[024]: initial support drm/nouveau/mmu/ga10[024]: initial support drm/nouveau/bar/ga10[024]: initial support drm/nouveau/gpio/ga10[024]: initial support drm/nouveau/i2c/ga10[024]: initial support drm/nouveau/dmaobj/ga10[24]: initial support drm/nouveau/disp/ga10[24]: initial support drivers/gpu/drm/nouveau/dispnv50/Kbuild| 1 + drivers/gpu/drm/nouveau/dispnv50/core.c| 1 + drivers/gpu/drm/nouveau/dispnv50/curs.c| 1 + drivers/gpu/drm/nouveau/dispnv50/wimm.c| 1 + drivers/gpu/drm/nouveau/dispnv50/wndw.c| 1 + drivers/gpu/drm/nouveau/dispnv50/wndw.h| 8 +++ drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c| 10 ++-- drivers/gpu/drm/nouveau/dispnv50/wndwc67e.c| 106 +++ drivers/gpu/drm/nouveau/include/nvif/cl0080.h | 1 + drivers/gpu/drm/nouveau/include/nvif/class.h | 5 ++ drivers/gpu/drm/nouveau/include/nvkm/core/device.h | 1 + drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h | 1 + drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h | 1 + drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h | 2 + drivers/gpu/drm/nouveau/include/nvkm/subdev/gpio.h | 1 + drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h | 1 + drivers/gpu/drm/nouveau/nouveau_backlight.c| 1 + drivers/gpu/drm/nouveau/nvif/disp.c| 1 + drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 75 ++-- drivers/gpu/drm/nouveau/nvkm/engine/device/user.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild| 3 ++ drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 33 ++--- drivers/gpu/drm/nouveau/nvkm/engine/disp/ga102.c | 46 + drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h | 4 ++ drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h| 2 + drivers/gpu/drm/nouveau/nvkm/engine/disp/rootga102.c | 52 +++ drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h| 1 + drivers/gpu/drm/nouveau/nvkm/engine/disp/sorga102.c| 140 drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c| 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/tu102.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c | 3 ++ drivers/gpu/drm/nouveau/nvkm/subdev/devinit/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/devinit/ga100.c| 76 drivers/gpu/drm/nouveau/nvkm/subdev/devinit/priv.h | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c| 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild | 3 ++ drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga100.c | 40 +++ drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c | 40 +++ drivers/gpu/drm/nouveau/nvkm/subdev/fb/gv100.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramga102.c | 40 +++ drivers/gpu/drm/nouveau/nvkm/subdev/gpio/Kbuild| 1 + drivers/gpu/drm/nouveau/nvkm/subdev/gpio
[PULL] nouveau-fixes 5.11
Hey Dave, As requested, here's a tree with the non-Ampere-specific fixes split out, as most of them are potentially relevant to already-supported GPUs. I'll send another pull request with bare-bones GA102/GA104 support shortly. Ben. The following changes since commit 7c53f6b671f4aba70ff15e1b05148b10d58c2837: Linux 5.11-rc3 (2021-01-10 14:34:50 -0800) are available in the Git repository at: git://github.com/skeggsb/linux 04.00-ampere-lite-fixes for you to fetch changes up to caeb6ab899c3d36a74cda6e299c6e1c9c4e2a22e: drm/nouveau/kms/nv50-: fix case where notifier buffer is at offset 0 (2021-01-15 10:25:17 +1000) -------- Ben Skeggs (7): drm/nouveau/bios: fix issue shadowing expansion ROMs drm/nouveau/privring: ack interrupts the same way as RM drm/nouveau/i2c/gk110: split out from i2c/gk104 drm/nouveau/i2c/gk110-: disable hw-initiated dpcd reads drm/nouveau/i2c/gm200: increase width of aux semaphore owner fields drm/nouveau/mmu: fix vram heap sizing drm/nouveau/kms/nv50-: fix case where notifier buffer is at offset 0 drivers/gpu/drm/nouveau/dispnv50/disp.c| 4 ++-- drivers/gpu/drm/nouveau/dispnv50/disp.h| 2 +- drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c| 2 +- drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 12 +-- drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h | 7 +++ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c | 10 +++--- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c | 17 ++-- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gk110.c| 45 ++ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gm200.c| 7 +++ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/pad.h | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/priv.h | 4 drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c | 10 +++--- drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c | 10 +++--- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 6 +++--- 17 files changed, 112 insertions(+), 30 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gk110.c ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Nouveau] [PATCH] drm/nouveau: bail out of nouveau_channel_new if channel init fails
On Mon, 16 Nov 2020 at 05:19, Karol Herbst wrote: > > On Sun, Nov 15, 2020 at 6:43 PM Salvatore Bonaccorso > wrote: > > > > Hi, > > > > On Fri, Aug 28, 2020 at 11:28:46AM +0200, Frantisek Hrbata wrote: > > > Unprivileged user can crash kernel by using > > > DRM_IOCTL_NOUVEAU_CHANNEL_ALLOC > > > ioctl. This was reported by trinity[1] fuzzer. > > > > > > [ 71.073906] nouveau :01:00.0: crashme[1329]: channel failed to > > > initialise, -17 > > > [ 71.081730] BUG: kernel NULL pointer dereference, address: > > > 00a0 > > > [ 71.088928] #PF: supervisor read access in kernel mode > > > [ 71.094059] #PF: error_code(0x) - not-present page > > > [ 71.099189] PGD 119590067 P4D 119590067 PUD 1054f5067 PMD 0 > > > [ 71.104842] Oops: [#1] SMP NOPTI > > > [ 71.108498] CPU: 2 PID: 1329 Comm: crashme Not tainted 5.8.0-rc6+ #2 > > > [ 71.114993] Hardware name: AMD Pike/Pike, BIOS RPK1506A 09/03/2014 > > > [ 71.121213] RIP: 0010:nouveau_abi16_ioctl_channel_alloc+0x108/0x380 > > > [nouveau] > > > [ 71.128339] Code: 48 89 9d f0 00 00 00 41 8b 4c 24 04 41 8b 14 24 45 > > > 31 c0 4c 8d 4b 10 48 89 ee 4c 89 f7 e8 10 11 00 00 85 c0 75 78 48 8b 43 > > > 10 <8b> 90 a0 00 00 00 41 89 54 24 08 80 7d 3d 05 0f 86 bb 01 00 00 41 > > > [ 71.147074] RSP: 0018:b4a1809cfd38 EFLAGS: 00010246 > > > [ 71.152526] RAX: RBX: 98cedbaa1d20 RCX: > > > 03bf > > > [ 71.159651] RDX: 03be RSI: RDI: > > > 00030160 > > > [ 71.166774] RBP: 98cee776de00 R08: dc0144198a08 R09: > > > 98ceeefd4000 > > > [ 71.173901] R10: 98cee7e81780 R11: 0001 R12: > > > b4a1809cfe08 > > > [ 71.181214] R13: 98cee776d000 R14: 98cec519e000 R15: > > > 98cee776def0 > > > [ 71.188339] FS: 7fd926250500() GS:98ceeac8() > > > knlGS: > > > [ 71.196418] CS: 0010 DS: ES: CR0: 80050033 > > > [ 71.202155] CR2: 00a0 CR3: 000106622000 CR4: > > > 000406e0 > > > [ 71.209297] Call Trace: > > > [ 71.211777] ? nouveau_abi16_ioctl_getparam+0x1f0/0x1f0 [nouveau] > > > [ 71.218053] drm_ioctl_kernel+0xac/0xf0 [drm] > > > [ 71.222421] drm_ioctl+0x211/0x3c0 [drm] > > > [ 71.226379] ? nouveau_abi16_ioctl_getparam+0x1f0/0x1f0 [nouveau] > > > [ 71.232500] nouveau_drm_ioctl+0x57/0xb0 [nouveau] > > > [ 71.237285] ksys_ioctl+0x86/0xc0 > > > [ 71.240595] __x64_sys_ioctl+0x16/0x20 > > > [ 71.244340] do_syscall_64+0x4c/0x90 > > > [ 71.248110] entry_SYSCALL_64_after_hwframe+0x44/0xa9 > > > [ 71.253162] RIP: 0033:0x7fd925d4b88b > > > [ 71.256731] Code: Bad RIP value. > > > [ 71.259955] RSP: 002b:7ffc743592d8 EFLAGS: 0206 ORIG_RAX: > > > 0010 > > > [ 71.267514] RAX: ffda RBX: RCX: > > > 7fd925d4b88b > > > [ 71.274637] RDX: 00601080 RSI: c0586442 RDI: > > > 0003 > > > [ 71.281986] RBP: 7ffc74359340 R08: 7fd926016ce0 R09: > > > 7fd926016ce0 > > > [ 71.289111] R10: 0003 R11: 0206 R12: > > > 00400620 > > > [ 71.296235] R13: 7ffc74359420 R14: R15: > > > > > > [ 71.303361] Modules linked in: rfkill sunrpc snd_hda_codec_realtek > > > snd_hda_codec_generic ledtrig_audio snd_hda_intel snd_intel_dspcfg > > > snd_hda_codec snd_hda_core edac_mce_amd snd_hwdep kvm_amd snd_seq ccp > > > snd_seq_device snd_pcm kvm snd_timer snd irqbypass soundcore sp5100_tco > > > pcspkr crct10dif_pclmul crc32_pclmul ghash_clmulni_intel wmi_bmof joydev > > > i2c_piix4 fam15h_power k10temp acpi_cpufreq ip_tables xfs libcrc32c > > > sd_mod t10_pi sg nouveau video mxm_wmi i2c_algo_bit drm_kms_helper > > > syscopyarea sysfillrect sysimgblt fb_sys_fops ttm broadcom bcm_phy_lib > > > ata_generic ahci drm e1000 crc32c_intel libahci serio_raw tg3 libata > > > firewire_ohci firewire_core wmi crc_itu_t dm_mirror dm_region_hash dm_log > > > dm_mod > > > [ 71.365269] CR2: 00a0 > > > > > > simplified reproducer > > > -8< > > > /* > > > * gcc -o crashme crashme.c > > > * ./crashme /dev/dri/renderD128 > > > */ > > > > > > struct drm_nouveau_channel_alloc { > > > uint32_t fb_ctxdma_handle; > > > uint32_t tt_ctxdma_handle; > > > > > > int channel; > > > uint32_t pushbuf_domains; > > > > > > /* Notifier memory */ > > > uint32_t notifier_handle; > > > > > > /* DRM-enforced subchannel assignments */ > > > struct { > > > uint32_t handle; > > > uint32_t grclass; > > > } subchan[8]; > > > uint32_t nr_subchan; > > > }; > > > > > > static struct drm_nouveau_channel_alloc channel; > > > > > > int main(int argc, char *argv[]) { > > > int fd; > > > int rv; > > > > > >
Re: [Nouveau] [PATCH 1/8] drm/nouveau/kms/nv50-: Use atomic encoder callbacks everywhere
I've merged all of these. Sent the first to 5.10-fixes for the regression there, the rest will go in with a later -next pull request. Thanks, Ben. On Sat, 14 Nov 2020 at 10:14, Lyude Paul wrote: > > It turns out that I forgot to go through and make sure that I converted all > encoder callbacks to use atomic_enable/atomic_disable(), so let's go and > actually do that. > > Signed-off-by: Lyude Paul > Cc: Kirill A. Shutemov > Fixes: 09838c4efe9a ("drm/nouveau/kms: Search for encoders' connectors > properly") > --- > drivers/gpu/drm/nouveau/dispnv50/disp.c | 29 - > 1 file changed, 14 insertions(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c > b/drivers/gpu/drm/nouveau/dispnv50/disp.c > index b111fe24a06b..36d6b6093d16 100644 > --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c > +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c > @@ -455,7 +455,7 @@ nv50_outp_get_old_connector(struct nouveau_encoder *outp, > * DAC > > */ > static void > -nv50_dac_disable(struct drm_encoder *encoder) > +nv50_dac_disable(struct drm_encoder *encoder, struct drm_atomic_state *state) > { > struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); > struct nv50_core *core = nv50_disp(encoder->dev)->core; > @@ -467,7 +467,7 @@ nv50_dac_disable(struct drm_encoder *encoder) > } > > static void > -nv50_dac_enable(struct drm_encoder *encoder) > +nv50_dac_enable(struct drm_encoder *encoder, struct drm_atomic_state *state) > { > struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); > struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); > @@ -525,8 +525,8 @@ nv50_dac_detect(struct drm_encoder *encoder, struct > drm_connector *connector) > static const struct drm_encoder_helper_funcs > nv50_dac_help = { > .atomic_check = nv50_outp_atomic_check, > - .enable = nv50_dac_enable, > - .disable = nv50_dac_disable, > + .atomic_enable = nv50_dac_enable, > + .atomic_disable = nv50_dac_disable, > .detect = nv50_dac_detect > }; > > @@ -1055,7 +1055,7 @@ nv50_dp_bpc_to_depth(unsigned int bpc) > } > > static void > -nv50_msto_enable(struct drm_encoder *encoder) > +nv50_msto_enable(struct drm_encoder *encoder, struct drm_atomic_state *state) > { > struct nv50_head *head = nv50_head(encoder->crtc); > struct nv50_head_atom *armh = nv50_head_atom(head->base.base.state); > @@ -1101,7 +1101,7 @@ nv50_msto_enable(struct drm_encoder *encoder) > } > > static void > -nv50_msto_disable(struct drm_encoder *encoder) > +nv50_msto_disable(struct drm_encoder *encoder, struct drm_atomic_state > *state) > { > struct nv50_msto *msto = nv50_msto(encoder); > struct nv50_mstc *mstc = msto->mstc; > @@ -1118,8 +1118,8 @@ nv50_msto_disable(struct drm_encoder *encoder) > > static const struct drm_encoder_helper_funcs > nv50_msto_help = { > - .disable = nv50_msto_disable, > - .enable = nv50_msto_enable, > + .atomic_disable = nv50_msto_disable, > + .atomic_enable = nv50_msto_enable, > .atomic_check = nv50_msto_atomic_check, > }; > > @@ -1645,8 +1645,7 @@ nv50_sor_disable(struct drm_encoder *encoder, > } > > static void > -nv50_sor_enable(struct drm_encoder *encoder, > - struct drm_atomic_state *state) > +nv50_sor_enable(struct drm_encoder *encoder, struct drm_atomic_state *state) > { > struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); > struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); > @@ -1873,7 +1872,7 @@ nv50_pior_atomic_check(struct drm_encoder *encoder, > } > > static void > -nv50_pior_disable(struct drm_encoder *encoder) > +nv50_pior_disable(struct drm_encoder *encoder, struct drm_atomic_state > *state) > { > struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); > struct nv50_core *core = nv50_disp(encoder->dev)->core; > @@ -1885,7 +1884,7 @@ nv50_pior_disable(struct drm_encoder *encoder) > } > > static void > -nv50_pior_enable(struct drm_encoder *encoder) > +nv50_pior_enable(struct drm_encoder *encoder, struct drm_atomic_state *state) > { > struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); > struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); > @@ -1921,14 +1920,14 @@ nv50_pior_enable(struct drm_encoder *encoder) > } > > core->func->pior->ctrl(core, nv_encoder->or, ctrl, asyh); > - nv_encoder->crtc = encoder->crtc; > + nv_encoder->crtc = &nv_crtc->base; > } > > static const struct drm_encoder_helper_funcs > nv50_pior_help = { > .atomic_check = nv50_pior_atomic_check, > - .enable = nv50_pior_enable, > - .disable = nv50_pior_disable, > + .atomic_enable = nv50_pior_enable, > + .atomic_disable = nv50_pior_disable, > }; > > static void > -- > 2.28.0 > > _
[PULL] nouveau-next 5.11
Just a single fix at the moment. An alternate version of a regression fix in 5.10, against additional changes from drm-next. Ben. The following changes since commit 512bce50a41c528fa15c4c014293e7bebf018658: Merge v5.10-rc3 into drm-next (2020-11-10 14:36:36 +0100) are available in the Git repository at: git://github.com/skeggsb/linux linux-5.11 for you to fetch changes up to be323a4cef022aa9685b08d5a94ddc841ccf617a: drm/nouveau/ttm: avoid using nouveau_drm.ttm.type_vram prior to nv50 (2020-11-14 14:35:57 +1000) Ben Skeggs (1): drm/nouveau/ttm: avoid using nouveau_drm.ttm.type_vram prior to nv50 drivers/gpu/drm/nouveau/nouveau_bo.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PULL] nouveau-fixes 5.10
The following changes since commit f8394f232b1eab649ce2df5c5f15b0e528c92091: Linux 5.10-rc3 (2020-11-08 16:10:16 -0800) are available in the Git repository at: git://github.com/skeggsb/linux linux-5.10 for you to fetch changes up to 5c6fb4b28b165887c42c66731c90eaca818b04c6: drm/nouveau/kms/nv50-: Use atomic encoder callbacks everywhere (2020-11-14 14:19:18 +1000) Alexander Kapshuk (1): drm/nouveau/kms: Fix NULL pointer dereference in nouveau_connector_detect_depth Ben Skeggs (1): drm/nouveau/ttm: avoid using nouveau_drm.ttm.type_vram prior to nv50 Lyude Paul (1): drm/nouveau/kms/nv50-: Use atomic encoder callbacks everywhere drivers/gpu/drm/nouveau/dispnv50/disp.c | 29 ++--- drivers/gpu/drm/nouveau/nouveau_bo.c| 3 +-- drivers/gpu/drm/nouveau/nouveau_connector.c | 14 +- 3 files changed, 24 insertions(+), 22 deletions(-) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PULL] nouveau-fixes 5.10
The following changes since commit 512bce50a41c528fa15c4c014293e7bebf018658: Merge v5.10-rc3 into drm-next (2020-11-10 14:36:36 +0100) are available in the Git repository at: git://github.com/skeggsb/linux linux-5.10 for you to fetch changes up to f67e5ecab785631cf7f776533432ba5aba06615a: drm/nouveau/ttm: avoid using nouveau_drm.ttm.type_vram prior to nv50 (2020-11-12 14:09:45 +1000) Alexander Kapshuk (1): drm/nouveau/kms: Fix NULL pointer dereference in nouveau_connector_detect_depth Ben Skeggs (1): drm/nouveau/ttm: avoid using nouveau_drm.ttm.type_vram prior to nv50 drivers/gpu/drm/nouveau/nouveau_bo.c| 3 +-- drivers/gpu/drm/nouveau/nouveau_connector.c | 14 +- 2 files changed, 10 insertions(+), 7 deletions(-) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/nouveau: Fix out-of-bounds access when deferencing MMU type
0x1b/0x40 > >>> [ 18.778890] __kasan_kmalloc.constprop.0+0xbf/0xd0 > >>> [ 18.785646] __kmalloc_track_caller+0x1be/0x390 > >>> [ 18.792165] kstrdup_const+0x46/0x70 > >>> [ 18.797686] kobject_set_name_vargs+0x2f/0xb0 > >>> [ 18.803992] kobject_init_and_add+0x9d/0xf0 > >>> [ 18.810117] ttm_mem_global_init+0x12c/0x210 [ttm] > >>> [ 18.816853] ttm_bo_global_init+0x4a/0x160 [ttm] > >>> [ 18.823420] ttm_bo_device_init+0x39/0x220 [ttm] > >>> [ 18.830046] nouveau_ttm_init+0x2c3/0x830 [nouveau] > >>> [ 18.836929] nouveau_drm_device_init+0x1b4/0x3f0 [nouveau] > >>> <...> > >>> [ 19.105336] > >>> > >=== > >>> === > >>> > >>> Fix this error, by not using type_vram as an index if it's negative. > >>> Assume default values instead. > >>> > >>> The error was seen on Nvidia G72 hardware. > >>> > >>> Signed-off-by: Thomas Zimmermann > >>> Fixes: 1cf65c45183a ("drm/ttm: add caching state to ttm_bus_placement") > >>> Cc: Christian König > >>> Cc: Michael J. Ruhl > >>> Cc: Maarten Lankhorst > >>> Cc: Maxime Ripard > >>> Cc: Thomas Zimmermann > >>> Cc: David Airlie > >>> Cc: Daniel Vetter > >>> Cc: Ben Skeggs > >>> Cc: Dave Airlie > >>> Cc: Gerd Hoffmann > >>> Cc: Alex Deucher > >>> Cc: "Christian König" > >>> Cc: VMware Graphics > >>> Cc: Roland Scheidegger > >>> Cc: Huang Rui > >>> Cc: Felix Kuehling > >>> Cc: Hawking Zhang > >>> Cc: Jason Gunthorpe > >>> Cc: Likun Gao > >>> Cc: dri-devel@lists.freedesktop.org > >>> Cc: nouv...@lists.freedesktop.org > >>> Cc: virtualizat...@lists.linux-foundation.org > >>> Cc: spice-de...@lists.freedesktop.org > >>> Cc: amd-...@lists.freedesktop.org > >>> --- > >>> drivers/gpu/drm/nouveau/nouveau_bo.c | 5 - > >>> 1 file changed, 4 insertions(+), 1 deletion(-) > >>> > >>> diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c > >>> b/drivers/gpu/drm/nouveau/nouveau_bo.c > >>> index 8133377d865d..fe15299d417e 100644 > >>> --- a/drivers/gpu/drm/nouveau/nouveau_bo.c > >>> +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c > >>> @@ -1142,9 +1142,12 @@ nouveau_ttm_io_mem_reserve(struct > >>> ttm_bo_device *bdev, struct ttm_resource *reg) > >>> struct nvkm_device *device = nvxx_device(&drm->client.device); > >>> struct nouveau_mem *mem = nouveau_mem(reg); > >>> struct nvif_mmu *mmu = &drm->client.mmu; > >>> - const u8 type = mmu->type[drm->ttm.type_vram].type; > >>> + u8 type = 0; > >>> int ret; > >>> > >>> + if (drm->ttm.type_vram >= 0) > >>> + type = mmu->type[drm->ttm.type_vram].type; > >>> + > >>> mutex_lock(&drm->ttm.io_reserve_mutex); > >>> retry: > >>> switch (reg->mem_type) { > >>> -- > >>> 2.29.2 > >> > > > >-- > >Thomas Zimmermann > >Graphics Driver Developer > >SUSE Software Solutions Germany GmbH > >Maxfeldstr. 5, 90409 Nürnberg, Germany > >(HRB 36809, AG Nürnberg) > >Geschäftsführer: Felix Imendörffer > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PULL] nouveau-fixes 5.10
The following changes since commit 3650b228f83adda7e5ee532e2b90429c03f7b9ec: Linux 5.10-rc1 (2020-10-25 15:14:11 -0700) are available in the Git repository at: git://github.com/skeggsb/linux linux-5.10 for you to fetch changes up to d7787cc04e0a1f2043264d1550465081096bd065: drm/nouveau/kms/nv50-: Fix clock checking algorithm in nv50_dp_mode_valid() (2020-10-30 09:34:13 +1000) Karol Herbst (2): drm/nouveau/gem: fix "refcount_t: underflow; use-after-free" drm/nouveau/device: fix changing endianess code to work on older GPUs Lyude Paul (3): drm/nouveau/kms/nv50-: Program notifier offset before requesting disp caps drm/nouveau/kms/nv50-: Get rid of bogus nouveau_conn_mode_valid() drm/nouveau/kms/nv50-: Fix clock checking algorithm in nv50_dp_mode_valid() Ralph Campbell (1): drm/nouveau/nouveau: fix the start/end range for migration drivers/gpu/drm/nouveau/dispnv50/core.h | 2 ++ drivers/gpu/drm/nouveau/dispnv50/core507d.c | 41 +++-- drivers/gpu/drm/nouveau/dispnv50/core907d.c | 36 +++- drivers/gpu/drm/nouveau/dispnv50/core917d.c | 2 +- drivers/gpu/drm/nouveau/include/nvhw/class/cl507d.h | 5 - drivers/gpu/drm/nouveau/include/nvhw/class/cl907d.h | 4 drivers/gpu/drm/nouveau/nouveau_connector.c | 36 ++-- drivers/gpu/drm/nouveau/nouveau_dp.c| 31 +++ drivers/gpu/drm/nouveau/nouveau_gem.c | 3 ++- drivers/gpu/drm/nouveau/nouveau_svm.c | 14 +++--- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 39 ++- 11 files changed, 145 insertions(+), 68 deletions(-) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Nouveau] [PATCH] drm/nouveau: Drop mutex_lock_nested for atomic
On Wed, 30 Sep 2020 at 19:37, Daniel Vetter wrote: > > On Wed, Sep 30, 2020 at 10:45:05AM +1000, Ben Skeggs wrote: > > On Wed, 30 Sep 2020 at 00:52, Daniel Vetter wrote: > > > > > > On Thu, Sep 17, 2020 at 3:15 PM Daniel Vetter > > > wrote: > > > > > > > > Ben, did you have a chance to look at this? > > > > > > Ping > > > -Daniel > > > > > > > On Mon, Aug 3, 2020 at 1:22 PM Maarten Lankhorst > > > > wrote: > > > > > > > > > > Op 02-08-2020 om 20:18 schreef Daniel Vetter: > > > > > > Purely conjecture, but I think the original locking inversion with > > > > > > the > > > > > > legacy page flip code between flipping and ttm's bo move function > > > > > > shoudn't exist anymore with atomic: With atomic the bo pinning and > > > > > > actual modeset commit is completely separated in the code patsh. > > > > > > > > > > > > This annotation was originally added in > > > > > > > > > > > > commit 060810d7abaabcab282e062c595871d661561400 > > > > > > Author: Ben Skeggs > > > > > > Date: Mon Jul 8 14:15:51 2013 +1000 > > > > > > > > > > > > drm/nouveau: fix locking issues in page flipping paths > > > > > > > > > > > > due to > > > > > > > > > > > > commit b580c9e2b7ba5030a795aa2fb73b796523d65a78 > > > > > > Author: Maarten Lankhorst > > > > > > Date: Thu Jun 27 13:48:18 2013 +0200 > > > > > > > > > > > > drm/nouveau: make flipping lockdep safe > > > > > > > > > > > > Signed-off-by: Daniel Vetter > > > > > > Cc: Maarten Lankhorst > > > > > > Cc: Ben Skeggs > > > > > > Cc: Dave Airlie > > > > > > Cc: nouv...@lists.freedesktop.org > > > > > > --- > > > > > > I might be totally wrong, so this definitely needs testing :-) > > > > > > > > > > > > Cheers, Daniel > > > > > > --- > > > > > > drivers/gpu/drm/nouveau/nouveau_bo.c | 6 +- > > > > > > 1 file changed, 5 insertions(+), 1 deletion(-) > > > > > > > > > > > > diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c > > > > > > b/drivers/gpu/drm/nouveau/nouveau_bo.c > > > > > > index 7806278dce57..a7b2a9bb0ffe 100644 > > > > > > --- a/drivers/gpu/drm/nouveau/nouveau_bo.c > > > > > > +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c > > > > > > @@ -776,7 +776,11 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object > > > > > > *bo, int evict, bool intr, > > > > > > return ret; > > > > > > } > > > > > > > > > > > > - mutex_lock_nested(&cli->mutex, SINGLE_DEPTH_NESTING); > > > > > > + if (drm_drv_uses_atomic_modeset(drm->dev)) > > > > > > + mutex_lock(&cli->mutex); > > > > > > + else > > > > > > + mutex_lock_nested(&cli->mutex, SINGLE_DEPTH_NESTING); > > > > > > + > > > > > > ret = nouveau_fence_sync(nouveau_bo(bo), chan, true, intr); > > > > > > if (ret == 0) { > > > > > > ret = drm->ttm.move(chan, bo, &bo->mem, new_reg); > > > > > > > > > > Well if you're certain it works now. :) > > > > > > > > > > Reviewed-by: Maarten Lankhorst > > Acked-by: Ben Skeggs > > Can you pull this in through your tree and maybe give it a spin just to > make sure? I don't really have nouveau hardware here. Yeah, I can do that easily enough. Ben. > > Also it's entirely stand-alone, I was simply reviewing all the > mutex_lock_nested we have in drm, and this one stuck out as probably not > necessary anymore, at least with atomic. > > I guess I can also just stuff it into drm-misc-next and if it blows up, > figure out what to do then :-) > -Daniel > > > > > > > > > > > > > > > > > > > > -- > > > > Daniel Vetter > > > > Software Engineer, Intel Corporation > > > > http://blog.ffwll.ch > > > > > > > > > > > > -- > > > Daniel Vetter > > > Software Engineer, Intel Corporation > > > http://blog.ffwll.ch > > > ___ > > > Nouveau mailing list > > > nouv...@lists.freedesktop.org > > > https://lists.freedesktop.org/mailman/listinfo/nouveau > > -- > Daniel Vetter > Software Engineer, Intel Corporation > http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 18/45] drm/nouveau: handle move notify inside move callback.
On Thu, 24 Sep 2020 at 15:20, Dave Airlie wrote: > > From: Dave Airlie > > Don't use explicit move notify for moves just do it in the driver side. > > Signed-off-by: Dave Airlie > --- > drivers/gpu/drm/nouveau/nouveau_bo.c | 62 > 1 file changed, 44 insertions(+), 18 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c > b/drivers/gpu/drm/nouveau/nouveau_bo.c > index 1e6c2561d692..144b82db16ac 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_bo.c > +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c > @@ -970,38 +970,42 @@ nouveau_bo_move_flips(struct ttm_buffer_object *bo, > bool evict, > } > > static void > -nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, bool evict, > -struct ttm_resource *new_reg) > +nouveau_bo_vma_map_update(struct nouveau_bo *nvbo, > + uint32_t mem_type, > + struct nouveau_mem *mem) > { > - struct nouveau_mem *mem = new_reg ? nouveau_mem(new_reg) : NULL; > - struct nouveau_bo *nvbo = nouveau_bo(bo); > struct nouveau_vma *vma; > > - /* ttm can now (stupidly) pass the driver bos it didn't create... */ > - if (bo->destroy != nouveau_bo_del_ttm) > - return; > - > - nouveau_bo_del_io_reserve_lru(bo); > - > - if (mem && new_reg->mem_type != TTM_PL_SYSTEM && > + if (mem && mem_type != TTM_PL_SYSTEM && > mem->mem.page == nvbo->page) { > list_for_each_entry(vma, &nvbo->vma_list, head) { > nouveau_vma_map(vma, mem); > } > } else { > list_for_each_entry(vma, &nvbo->vma_list, head) { > - WARN_ON(ttm_bo_wait(bo, false, false)); > + WARN_ON(ttm_bo_wait(&nvbo->bo, false, false)); I can look at this more closely myself a bit down the track, as I need to do a lot in this area in the near future anyway, but it'd be nice to pass the failure back here where possible to do so. The new invalidate_notify() hook still can't fail, but the other uses can and it'd be nice to do the right thing where it's possible. Ben. > nouveau_vma_unmap(vma); > } > } > +} > > - if (new_reg) { > - if (new_reg->mm_node) > - nvbo->offset = (new_reg->start << PAGE_SHIFT); > - else > - nvbo->offset = 0; > - } > +static void > +nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, bool evict, > +struct ttm_resource *new_reg) > +{ > + struct nouveau_bo *nvbo = nouveau_bo(bo); > + > + /* ttm can now (stupidly) pass the driver bos it didn't create... */ > + if (bo->destroy != nouveau_bo_del_ttm) > + return; > + > + /* handle new_reg path in move */ > + if (new_reg) > + return; > + > + nouveau_bo_del_io_reserve_lru(bo); > > + nouveau_bo_vma_map_update(nvbo, 0, NULL); > } > > static int > @@ -1038,6 +1042,20 @@ nouveau_bo_vm_cleanup(struct ttm_buffer_object *bo, > *old_tile = new_tile; > } > > + > +static void > +nouveau_bo_update_mem(struct nouveau_bo *nvbo, > + struct ttm_resource *new_reg) > +{ > + nouveau_bo_vma_map_update(nvbo, new_reg->mem_type, > nouveau_mem(new_reg)); > + if (new_reg) { > + if (new_reg->mm_node) > + nvbo->offset = (new_reg->start << PAGE_SHIFT); > + else > + nvbo->offset = 0; > + } > +} > + > static int > nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, > struct ttm_operation_ctx *ctx, > @@ -1053,6 +1071,9 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool > evict, > if (ret) > return ret; > > + nouveau_bo_del_io_reserve_lru(bo); > + nouveau_bo_update_mem(nvbo, new_reg); > + > if (nvbo->bo.pin_count) > NV_WARN(drm, "Moving pinned object %p!\n", nvbo); > > @@ -1108,6 +1129,11 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool > evict, > nouveau_bo_vm_cleanup(bo, new_tile, &nvbo->tile); > } > > + if (ret) { > + nouveau_bo_del_io_reserve_lru(bo); > + nouveau_bo_update_mem(nvbo, &bo->mem); > + } > + > return ret; > } > > -- > 2.27.0 > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 00/45] TTM move refactoring
On Thu, 24 Sep 2020 at 15:19, Dave Airlie wrote: > > This refactors how TTM moves get called between core and drivers. > > 1) puts the driver in charge of all moves, and enforces > drivers have a move callback. > 2) moves move_notify actions around moves to the driver side > 3) moves binding/unbinding completely into move and driver side > 4) add a new invalidate callback to replace the last use of move_notify > 5) add some helpers to cleanup the resulting move code > > There's a bit of internal churn to try and make each patch logical, so > don't get too caught up in each patches changes unless the end result > is a problem. I've looked over the nouveau-specific patches, and the ttm ones (mostly ignoring the changes to other drivers beyond a quick glance over). For all but 37/45 and the patches that depend on it: Reviewed-by: Ben Skeggs I'll add some more specific comments to one of the patches, but it's also fine as-is. Ben. > > Dave. > > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Nouveau] [PATCH] drm/nouveau: Drop mutex_lock_nested for atomic
On Wed, 30 Sep 2020 at 00:52, Daniel Vetter wrote: > > On Thu, Sep 17, 2020 at 3:15 PM Daniel Vetter wrote: > > > > Ben, did you have a chance to look at this? > > Ping > -Daniel > > > On Mon, Aug 3, 2020 at 1:22 PM Maarten Lankhorst > > wrote: > > > > > > Op 02-08-2020 om 20:18 schreef Daniel Vetter: > > > > Purely conjecture, but I think the original locking inversion with the > > > > legacy page flip code between flipping and ttm's bo move function > > > > shoudn't exist anymore with atomic: With atomic the bo pinning and > > > > actual modeset commit is completely separated in the code patsh. > > > > > > > > This annotation was originally added in > > > > > > > > commit 060810d7abaabcab282e062c595871d661561400 > > > > Author: Ben Skeggs > > > > Date: Mon Jul 8 14:15:51 2013 +1000 > > > > > > > > drm/nouveau: fix locking issues in page flipping paths > > > > > > > > due to > > > > > > > > commit b580c9e2b7ba5030a795aa2fb73b796523d65a78 > > > > Author: Maarten Lankhorst > > > > Date: Thu Jun 27 13:48:18 2013 +0200 > > > > > > > > drm/nouveau: make flipping lockdep safe > > > > > > > > Signed-off-by: Daniel Vetter > > > > Cc: Maarten Lankhorst > > > > Cc: Ben Skeggs > > > > Cc: Dave Airlie > > > > Cc: nouv...@lists.freedesktop.org > > > > --- > > > > I might be totally wrong, so this definitely needs testing :-) > > > > > > > > Cheers, Daniel > > > > --- > > > > drivers/gpu/drm/nouveau/nouveau_bo.c | 6 +- > > > > 1 file changed, 5 insertions(+), 1 deletion(-) > > > > > > > > diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c > > > > b/drivers/gpu/drm/nouveau/nouveau_bo.c > > > > index 7806278dce57..a7b2a9bb0ffe 100644 > > > > --- a/drivers/gpu/drm/nouveau/nouveau_bo.c > > > > +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c > > > > @@ -776,7 +776,11 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, > > > > int evict, bool intr, > > > > return ret; > > > > } > > > > > > > > - mutex_lock_nested(&cli->mutex, SINGLE_DEPTH_NESTING); > > > > + if (drm_drv_uses_atomic_modeset(drm->dev)) > > > > + mutex_lock(&cli->mutex); > > > > + else > > > > + mutex_lock_nested(&cli->mutex, SINGLE_DEPTH_NESTING); > > > > + > > > > ret = nouveau_fence_sync(nouveau_bo(bo), chan, true, intr); > > > > if (ret == 0) { > > > > ret = drm->ttm.move(chan, bo, &bo->mem, new_reg); > > > > > > Well if you're certain it works now. :) > > > > > > Reviewed-by: Maarten Lankhorst Acked-by: Ben Skeggs > > > > > > > > > -- > > Daniel Vetter > > Software Engineer, Intel Corporation > > http://blog.ffwll.ch > > > > -- > Daniel Vetter > Software Engineer, Intel Corporation > http://blog.ffwll.ch > ___ > Nouveau mailing list > nouv...@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/nouveau ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: Why is nouveau using a separate swap storage?
On Thu, 17 Sep 2020 at 20:06, Christian König wrote: > > Hi guys, > > just another TTM feature which is only used by nouveau. > > We have this bo->bo.persistent_swap_storage pointer which is only set by > nouveau to the GEM filp and used when a BO is swapped to a shmem file. > > As far as I can see this doesn't make any sense at all? What is the > background here. No specific reason I can remember, likely cargo-cult from very very early versions of TTM/GEM stuff. Ben. > > Thanks, > Christian. > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Nouveau] [PATCH] drm/nouveau: Add fine-grain temperature reporting
On Thu, 10 Sep 2020 at 00:07, Jeremy Cline wrote: > > On Wed, Sep 09, 2020 at 10:22:14AM +0200, Karol Herbst wrote: > > On Wed, Sep 9, 2020 at 6:06 AM Ben Skeggs wrote: > > > > > > On Thu, 13 Aug 2020 at 06:50, Jeremy Cline wrote: > > > > > > > > Commit d32656373857 ("drm/nouveau/therm/gp100: initial implementation of > > > > new gp1xx temperature sensor") added support for reading finer-grain > > > > temperatures, but continued to report temperatures in 1 degree Celsius > > > > increments via nvkm_therm_temp_get(). > > > > > > > > Rather than altering nvkm_therm_temp_get() to report finer-grain > > > > temperatures, which would be inconvenient for other users of the > > > > function, a second interface has been added to line up with hwmon's > > > > native unit of temperature. > > > Hey Jeremy, > > > > > > Sorry this slipped past me until now. I'm OK with adding support for > > > millidegree temperature reporting, but don't think we need to keep > > > both interfaces around and would rather see the existing code > > > converted to return millidegrees (even on GPUs that don't support it) > > > instead of degrees. > > > > > > Thanks! > > > Ben. > > > > > > > just a note as I was trying something like that in the past: we have a > > lot of code which fetches the temperature and there are a lot of > > places where we would then do a divide by 1000, so having a wrapper > > function at least makes sense. If we want to keep the func pointers? > > well.. I guess the increased CPU overhead wouldn't be as bad if all > > sub classes do this static * 1000 as well either. I just think we > > should have both interfaces in subdev/therm.h so we can just keep most > > of the current code as is. > > > > Indeed. My initial plan was to change the meaning of temp_get() and > adjust all the users, but there's around a dozen of them and based on my > understanding of the users none of them cared much about such accuracy. > > However, I do find having one way to do things appealing, so if there's > a strong preference for it, I'm happy to produce a somewhat more > invasive patch where all users expect millidegrees. Yeah, I do have a strong preference for not having to keep multiple interfaces around unnecessarily. It'd be somewhat different if we had external interactions, but this is all stuff within the module and we should be able to make these kinds of changes without too much pain. Ben. > > - Jeremy > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Nouveau] [PATCH] drm/nouveau: Add fine-grain temperature reporting
On Thu, 13 Aug 2020 at 06:50, Jeremy Cline wrote: > > Commit d32656373857 ("drm/nouveau/therm/gp100: initial implementation of > new gp1xx temperature sensor") added support for reading finer-grain > temperatures, but continued to report temperatures in 1 degree Celsius > increments via nvkm_therm_temp_get(). > > Rather than altering nvkm_therm_temp_get() to report finer-grain > temperatures, which would be inconvenient for other users of the > function, a second interface has been added to line up with hwmon's > native unit of temperature. Hey Jeremy, Sorry this slipped past me until now. I'm OK with adding support for millidegree temperature reporting, but don't think we need to keep both interfaces around and would rather see the existing code converted to return millidegrees (even on GPUs that don't support it) instead of degrees. Thanks! Ben. > > Signed-off-by: Jeremy Cline > --- > .../drm/nouveau/include/nvkm/subdev/therm.h | 18 + > drivers/gpu/drm/nouveau/nouveau_hwmon.c | 4 +-- > .../gpu/drm/nouveau/nvkm/subdev/therm/base.c | 16 > .../gpu/drm/nouveau/nvkm/subdev/therm/gp100.c | 25 +-- > .../gpu/drm/nouveau/nvkm/subdev/therm/priv.h | 1 + > 5 files changed, 60 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h > b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h > index 62c34f98c930..7b9928dd001c 100644 > --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h > +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h > @@ -100,6 +100,24 @@ struct nvkm_therm { > }; > > int nvkm_therm_temp_get(struct nvkm_therm *); > + > +/** > + * nvkm_therm_temp_millidegree_get() - get the temperature in millidegrees > + * @therm: The thermal device to read from. > + * > + * This interface reports temperatures in units of millidegree Celsius to > + * align with the hwmon API. Some cards may only be capable of reporting in > + * units of Celsius, and those that report finer grain temperatures may not > be > + * capable of millidegree Celsius accuracy, > + * > + * For cases where millidegree temperature is too fine-grain, the > + * nvkm_therm_temp_get() interface reports temperatures in one degree Celsius > + * increments. > + * > + * Return: The temperature in millidegrees Celsius, or -ENODEV if temperature > + * reporting is not supported. > + */ > +int nvkm_therm_temp_millidegree_get(struct nvkm_therm *therm); > int nvkm_therm_fan_sense(struct nvkm_therm *); > int nvkm_therm_cstate(struct nvkm_therm *, int, int); > void nvkm_therm_clkgate_init(struct nvkm_therm *, > diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c > b/drivers/gpu/drm/nouveau/nouveau_hwmon.c > index 1c3104d20571..e96355f93ce5 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c > +++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c > @@ -428,8 +428,8 @@ nouveau_temp_read(struct device *dev, u32 attr, int > channel, long *val) > case hwmon_temp_input: > if (drm_dev->switch_power_state != DRM_SWITCH_POWER_ON) > return -EINVAL; > - ret = nvkm_therm_temp_get(therm); > - *val = ret < 0 ? ret : (ret * 1000); > + ret = nvkm_therm_temp_millidegree_get(therm); > + *val = ret; > break; > case hwmon_temp_max: > *val = therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c > b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c > index 4a4d1e224126..e655b32c78b8 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c > @@ -34,6 +34,22 @@ nvkm_therm_temp_get(struct nvkm_therm *therm) > return -ENODEV; > } > > +int > +nvkm_therm_temp_millidegree_get(struct nvkm_therm *therm) > +{ > + int ret = -ENODEV; > + > + if (therm->func->temp_millidegree_get) > + return therm->func->temp_millidegree_get(therm); > + > + if (therm->func->temp_get) { > + ret = therm->func->temp_get(therm); > + if (ret > 0) > + ret *= 1000; > + } > + return ret; > +} > + > static int > nvkm_therm_update_trip(struct nvkm_therm *therm) > { > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gp100.c > b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gp100.c > index 9f0dea3f61dc..4c3c2895a3cb 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gp100.c > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gp100.c > @@ -24,7 +24,7 @@ > #include "priv.h" > > static int > -gp100_temp_get(struct nvkm_therm *therm) > +gp100_temp_get_raw(struct nvkm_therm *therm) > { > struct nvkm_device *device = therm->subdev.device; > struct nvkm_subdev *subdev = &therm->subdev; > @@ -37,14 +37,35 @@ gp100_temp_get(struct nvkm_therm *therm) > > /* device valid */ > if (tsensor & 0x
Re: [Nouveau] [PATCH v5 1/2] drm/nouveau/kms/nv50-: Program notifier offset before requesting disp caps
On Sat, 5 Sep 2020 at 06:28, Lyude Paul wrote: > > Not entirely sure why this never came up when I originally tested this > (maybe some BIOSes already have this setup?) but the ->caps_init vfunc > appears to cause the display engine to throw an exception on driver > init, at least on my ThinkPad P72: > > nouveau :01:00.0: disp: chid 0 mthd 008c data 508c 102b > > This is magic nvidia speak for "You need to have the DMA notifier offset > programmed before you can call NV507D_GET_CAPABILITIES." So, let's fix > this by doing that, and also perform an update afterwards to prevent > racing with the GPU when reading capabilities. > > v2: > * Don't just program the DMA notifier offset, make sure to actually > perform an update > v3: > * Don't call UPDATE() > * Actually read the correct notifier fields, as apparently the > CAPABILITIES_DONE field lives in a different location than the main > NV_DISP_CORE_NOTIFIER_1 field. As well, 907d+ use a different > CAPABILITIES_DONE field then pre-907d cards. > v4: > * Don't forget to check the return value of core507d_read_caps() > v5: > * Get rid of NV50_DISP_CAPS_NTFY[14], use NV50_DISP_CORE_NTFY > * Disable notifier after calling GetCapabilities() > > Signed-off-by: Lyude Paul > Fixes: 4a2cb4181b07 ("drm/nouveau/kms/nv50-: Probe SOR and PIOR caps for DP > interlacing support") > Cc: # v5.8+ Thanks Lyude, looks good, and merged! Ben. > --- > drivers/gpu/drm/nouveau/dispnv50/core.h | 2 + > drivers/gpu/drm/nouveau/dispnv50/core507d.c | 41 ++- > drivers/gpu/drm/nouveau/dispnv50/core907d.c | 36 +++- > drivers/gpu/drm/nouveau/dispnv50/core917d.c | 2 +- > .../drm/nouveau/include/nvhw/class/cl507d.h | 5 ++- > .../drm/nouveau/include/nvhw/class/cl907d.h | 4 ++ > 6 files changed, 85 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/dispnv50/core.h > b/drivers/gpu/drm/nouveau/dispnv50/core.h > index 498622c0c670d..f75088186fba3 100644 > --- a/drivers/gpu/drm/nouveau/dispnv50/core.h > +++ b/drivers/gpu/drm/nouveau/dispnv50/core.h > @@ -44,6 +44,7 @@ int core507d_new_(const struct nv50_core_func *, struct > nouveau_drm *, s32, > struct nv50_core **); > int core507d_init(struct nv50_core *); > void core507d_ntfy_init(struct nouveau_bo *, u32); > +int core507d_read_caps(struct nv50_disp *disp); > int core507d_caps_init(struct nouveau_drm *, struct nv50_disp *); > int core507d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *); > int core507d_update(struct nv50_core *, u32 *, bool); > @@ -55,6 +56,7 @@ extern const struct nv50_outp_func pior507d; > int core827d_new(struct nouveau_drm *, s32, struct nv50_core **); > > int core907d_new(struct nouveau_drm *, s32, struct nv50_core **); > +int core907d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp); > extern const struct nv50_outp_func dac907d; > extern const struct nv50_outp_func sor907d; > > diff --git a/drivers/gpu/drm/nouveau/dispnv50/core507d.c > b/drivers/gpu/drm/nouveau/dispnv50/core507d.c > index 248edf69e1683..e6f16a7750f07 100644 > --- a/drivers/gpu/drm/nouveau/dispnv50/core507d.c > +++ b/drivers/gpu/drm/nouveau/dispnv50/core507d.c > @@ -78,18 +78,55 @@ core507d_ntfy_init(struct nouveau_bo *bo, u32 offset) > } > > int > -core507d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp) > +core507d_read_caps(struct nv50_disp *disp) > { > struct nvif_push *push = disp->core->chan.push; > int ret; > > - if ((ret = PUSH_WAIT(push, 2))) > + ret = PUSH_WAIT(push, 6); > + if (ret) > return ret; > > + PUSH_MTHD(push, NV507D, SET_NOTIFIER_CONTROL, > + NVDEF(NV507D, SET_NOTIFIER_CONTROL, MODE, WRITE) | > + NVVAL(NV507D, SET_NOTIFIER_CONTROL, OFFSET, > NV50_DISP_CORE_NTFY >> 2) | > + NVDEF(NV507D, SET_NOTIFIER_CONTROL, NOTIFY, ENABLE)); > + > PUSH_MTHD(push, NV507D, GET_CAPABILITIES, 0x); > + > + PUSH_MTHD(push, NV507D, SET_NOTIFIER_CONTROL, > + NVDEF(NV507D, SET_NOTIFIER_CONTROL, NOTIFY, DISABLE)); > + > return PUSH_KICK(push); > } > > +int > +core507d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp) > +{ > + struct nv50_core *core = disp->core; > + struct nouveau_bo *bo = disp->sync; > + s64 time; > + int ret; > + > + NVBO_WR32(bo, NV50_DISP_CORE_NTFY, NV_DISP_CORE_NOTIFIER_1, > CAPABILITIES_1, > +NVDEF(NV_DISP_CORE_NOTIFIER_1, > CAPABILITIES_1, DONE, FALSE)); > + > + ret = core507d_read_caps(disp); > + if (ret < 0) > + return ret; > + > + time = nvif_msec(core->chan.base.device, 2000ULL, > +if (NVBO_TD32(bo, NV50_DISP_CORE_NTFY, > + NV_DISP_CORE_NOTIFIER_1, > CAPABILITIES_1, DONE, ==, TRUE)) > +break; > +
Re: [PATCH 00/13] ttm tt refactor repost of part 1
On Tue, 8 Sep 2020 at 06:46, Dave Airlie wrote: > > Most of these have r-b or acks already, patch 1 I may have > posted before but found in my tree, so reposting it, and patch > 5 for radeon I think were what needed re-review. R-b for ttm and nouveau changes, A-b for the other drivers. Ben. > > I'd like to land these, and I'll revisit the remainder of this > series. > > Dave. > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PULL] nouveau-fixes 5.9
Hey Dave, A couple of minor fixes to the display changes that went in for 5.9. The most important of which is a workaround for a HW bug that was exposed by better push buffer space management, leading to random(ish...) display engine hangs. Ben. The following changes since commit f75aef392f869018f78cfedf3c320a6b3fcfda6b: Linux 5.9-rc3 (2020-08-30 16:01:54 -0700) are available in the Git repository at: git://github.com/skeggsb/linux linux-5.9 for you to fetch changes up to ca386aa7155a5467fa7b2b8376f4da8f8e59be4d: drm/nouveau/kms/nv50-gp1xx: add WAR for EVO push buffer HW bug (2020-09-03 15:32:24 +1000) Ben Skeggs (3): drm/nouveau/kms/nv50-: add some whitespace before debug message drm/nouveau/kms/nv50-gp1xx: disable notifies again after core update drm/nouveau/kms/nv50-gp1xx: add WAR for EVO push buffer HW bug Lyude Paul (1): drm/nouveau/kms/gv100-: Include correct push header in crcc37d.c drivers/gpu/drm/nouveau/dispnv50/core507d.c | 5 - drivers/gpu/drm/nouveau/dispnv50/crcc37d.c | 2 +- drivers/gpu/drm/nouveau/dispnv50/disp.c | 6 ++ drivers/gpu/drm/nouveau/include/nvif/push507c.h | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Nouveau] [PATCH v4] drm/nouveau/kms/nv50-: Program notifier offset before requesting disp caps
On Wed, 2 Sep 2020 at 09:43, Lyude Paul wrote: > > Not entirely sure why this never came up when I originally tested this > (maybe some BIOSes already have this setup?) but the ->caps_init vfunc > appears to cause the display engine to throw an exception on driver > init, at least on my ThinkPad P72: > > nouveau :01:00.0: disp: chid 0 mthd 008c data 508c 102b > > This is magic nvidia speak for "You need to have the DMA notifier offset > programmed before you can call NV507D_GET_CAPABILITIES." So, let's fix > this by doing that, and also perform an update afterwards to prevent > racing with the GPU when reading capabilities. > > v2: > * Don't just program the DMA notifier offset, make sure to actually > perform an update > v3: > * Don't call UPDATE() > * Actually read the correct notifier fields, as apparently the > CAPABILITIES_DONE field lives in a different location than the main > NV_DISP_CORE_NOTIFIER_1 field. As well, 907d+ use a different > CAPABILITIES_DONE field then pre-907d cards. > v4: > * Don't forget to check the return value of core507d_read_caps() > > Signed-off-by: Lyude Paul > Fixes: 4a2cb4181b07 ("drm/nouveau/kms/nv50-: Probe SOR and PIOR caps for DP > interlacing support") > Cc: # v5.8+ > --- > drivers/gpu/drm/nouveau/dispnv50/core.h | 2 + > drivers/gpu/drm/nouveau/dispnv50/core507d.c | 37 ++- > drivers/gpu/drm/nouveau/dispnv50/core907d.c | 36 +- > drivers/gpu/drm/nouveau/dispnv50/core917d.c | 2 +- > drivers/gpu/drm/nouveau/dispnv50/disp.h | 2 + > .../drm/nouveau/include/nvhw/class/cl507d.h | 5 ++- > .../drm/nouveau/include/nvhw/class/cl907d.h | 4 ++ > 7 files changed, 83 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/dispnv50/core.h > b/drivers/gpu/drm/nouveau/dispnv50/core.h > index 498622c0c670d..b789139e5fff6 100644 > --- a/drivers/gpu/drm/nouveau/dispnv50/core.h > +++ b/drivers/gpu/drm/nouveau/dispnv50/core.h > @@ -44,6 +44,7 @@ int core507d_new_(const struct nv50_core_func *, struct > nouveau_drm *, s32, > struct nv50_core **); > int core507d_init(struct nv50_core *); > void core507d_ntfy_init(struct nouveau_bo *, u32); > +int core507d_read_caps(struct nv50_disp *disp, u32 offset); > int core507d_caps_init(struct nouveau_drm *, struct nv50_disp *); > int core507d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *); > int core507d_update(struct nv50_core *, u32 *, bool); > @@ -55,6 +56,7 @@ extern const struct nv50_outp_func pior507d; > int core827d_new(struct nouveau_drm *, s32, struct nv50_core **); > > int core907d_new(struct nouveau_drm *, s32, struct nv50_core **); > +int core907d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp); > extern const struct nv50_outp_func dac907d; > extern const struct nv50_outp_func sor907d; > > diff --git a/drivers/gpu/drm/nouveau/dispnv50/core507d.c > b/drivers/gpu/drm/nouveau/dispnv50/core507d.c > index ad1f09a143aa4..d0f2b80a32103 100644 > --- a/drivers/gpu/drm/nouveau/dispnv50/core507d.c > +++ b/drivers/gpu/drm/nouveau/dispnv50/core507d.c > @@ -75,18 +75,51 @@ core507d_ntfy_init(struct nouveau_bo *bo, u32 offset) > } > > int > -core507d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp) > +core507d_read_caps(struct nv50_disp *disp, u32 offset) > { > struct nvif_push *push = disp->core->chan.push; > int ret; > > - if ((ret = PUSH_WAIT(push, 2))) > + ret = PUSH_WAIT(push, 4); > + if (ret) > return ret; > > + PUSH_MTHD(push, NV507D, SET_NOTIFIER_CONTROL, > + NVDEF(NV507D, SET_NOTIFIER_CONTROL, MODE, WRITE) | > + NVVAL(NV507D, SET_NOTIFIER_CONTROL, OFFSET, offset >> 2) | > + NVDEF(NV507D, SET_NOTIFIER_CONTROL, NOTIFY, ENABLE)); > PUSH_MTHD(push, NV507D, GET_CAPABILITIES, 0x); Can you send a SET_NOTIFIER_CONTROL_NOTIFY_DISABLE after GET_CAPABILITIES() too please :) > + > return PUSH_KICK(push); > } > > +int > +core507d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp) > +{ > + struct nv50_core *core = disp->core; > + struct nouveau_bo *bo = disp->sync; > + s64 time; > + int ret; > + > + NVBO_WR32(bo, NV50_DISP_CAPS_NTFY1, NV_DISP_CORE_NOTIFIER_1, > CAPABILITIES_1, > + NVDEF(NV_DISP_CORE_NOTIFIER_1, > CAPABILITIES_1, DONE, FALSE)); You don't need these NV50_DISP_CAPS_NTFYx thingies. These offsets are already encoded in NVIDIA's headers (NV_DISP_CORE_NOTIFIER_1_CAPABILITIES_1 is an offset), you're adding an additional offset by doing this. Just use NV50_DISP_CORE_NTFY in all these places, and let NVIDIA's headers do the rest. The additional offset in these macros are meant for when there's multiple structures packed into a single nouveau_bo at different offsets. It doesn't actually matter here, because it gets divided away. But for core907d, you're actually rea