From 9dfbd7319909a948146f5c3438f7bd86c2c53cb6 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 2 Feb 2018 16:27:31 +0100 Subject: [PATCH 001/165] drm/nouveau: nouveau: use larger buffer in nvif_vmm_map gcc points out a buffer that is clearly too small to be used in a meaningful way, as the 'sizeof(*args) + argc > sizeof(stack)' will always fail: In function 'memcpy', inlined from 'nvif_vmm_map' at drivers/gpu/drm/nouveau/nvif/vmm.c:55:2: include/linux/string.h:353:9: error: '__builtin_memcpy' offset 40 is out of the bounds [0, 16] of object 'stack' with type 'u8[16]' {aka 'unsigned char[16]'} [-Werror=array-bounds] return __builtin_memcpy(p, q, size); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/gpu/drm/nouveau/nvif/vmm.c: In function 'nvif_vmm_map': drivers/gpu/drm/nouveau/nvif/vmm.c:40:5: note: 'stack' declared here This makes the buffer large enough so it should serve the purpose that the author presumably had in mind. Alternatively we could just get rid of it completely and simplify the code at the cost of always doing the kmalloc (as we do in the current version). Fixes: 920d2b5ef215 ("drm/nouveau/mmu: define user interfaces to mmu vmm opertaions") Signed-off-by: Arnd Bergmann Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvif/vmm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nvif/vmm.c b/drivers/gpu/drm/nouveau/nvif/vmm.c index 31cdb2d2e1ff1..191832be6c658 100644 --- a/drivers/gpu/drm/nouveau/nvif/vmm.c +++ b/drivers/gpu/drm/nouveau/nvif/vmm.c @@ -37,7 +37,7 @@ nvif_vmm_map(struct nvif_vmm *vmm, u64 addr, u64 size, void *argv, u32 argc, struct nvif_mem *mem, u64 offset) { struct nvif_vmm_map_v0 *args; - u8 stack[16]; + u8 stack[48]; int ret; if (sizeof(*args) + argc > sizeof(stack)) { From 7bf5b70befd7817b9e42acbd2291b2042ea1bf81 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Tue, 13 Mar 2018 11:24:11 -0500 Subject: [PATCH 002/165] drm/nouveau/secboot: remove VLA usage In preparation to enabling -Wvla, remove VLA. In this particular case directly use macro NVKM_MSGQUEUE_CMDLINE_SIZE instead of local variable cmdline_size. Also, remove cmdline_size as it is not actually useful anymore. The use of stack Variable Length Arrays needs to be avoided, as they can be a vector for stack exhaustion, which can be both a runtime bug or a security flaw. Also, in general, as code evolves it is easy to lose track of how big a VLA can get. Thus, we can end up having runtime failures that are hard to debug. Also, fixed as part of the directive to remove all VLAs from the kernel: https://lkml.org/lkml/2018/3/7/621 Signed-off-by: Gustavo A. R. Silva Reviewed-by: Thierry Reding Signed-off-by: Ben Skeggs --- .../drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c index 6f10b098676ce..1e1f1c635cabc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c @@ -80,12 +80,11 @@ acr_ls_msgqueue_post_run(struct nvkm_msgqueue *queue, struct nvkm_falcon *falcon, u32 addr_args) { struct nvkm_device *device = falcon->owner->device; - u32 cmdline_size = NVKM_MSGQUEUE_CMDLINE_SIZE; - u8 buf[cmdline_size]; + u8 buf[NVKM_MSGQUEUE_CMDLINE_SIZE]; - memset(buf, 0, cmdline_size); + memset(buf, 0, sizeof(buf)); nvkm_msgqueue_write_cmdline(queue, buf); - nvkm_falcon_load_dmem(falcon, buf, addr_args, cmdline_size, 0); + nvkm_falcon_load_dmem(falcon, buf, addr_args, sizeof(buf), 0); /* rearm the queue so it will wait for the init message */ nvkm_msgqueue_reinit(queue); From 1ce466894b532dc26b02a334fc609378b9231ea8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 003/165] drm/nouveau/core: define FAULT subdev This will be responsible for the handling of MMU fault buffers on GPUs that support them. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/device.h | 3 +++ drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h | 8 ++++++++ drivers/gpu/drm/nouveau/nvkm/core/subdev.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild | 0 7 files changed, 16 insertions(+) create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index 560265b15ec23..f2f9b9e7ce2ea 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h @@ -22,6 +22,7 @@ enum nvkm_devidx { NVKM_SUBDEV_LTC, NVKM_SUBDEV_MMU, NVKM_SUBDEV_BAR, + NVKM_SUBDEV_FAULT, NVKM_SUBDEV_PMU, NVKM_SUBDEV_VOLT, NVKM_SUBDEV_ICCSENSE, @@ -123,6 +124,7 @@ struct nvkm_device { struct nvkm_bus *bus; struct nvkm_clk *clk; struct nvkm_devinit *devinit; + struct nvkm_fault *fault; struct nvkm_fb *fb; struct nvkm_fuse *fuse; struct nvkm_gpio *gpio; @@ -194,6 +196,7 @@ struct nvkm_device_chip { int (*bus )(struct nvkm_device *, int idx, struct nvkm_bus **); int (*clk )(struct nvkm_device *, int idx, struct nvkm_clk **); int (*devinit )(struct nvkm_device *, int idx, struct nvkm_devinit **); + int (*fault )(struct nvkm_device *, int idx, struct nvkm_fault **); int (*fb )(struct nvkm_device *, int idx, struct nvkm_fb **); int (*fuse )(struct nvkm_device *, int idx, struct nvkm_fuse **); int (*gpio )(struct nvkm_device *, int idx, struct nvkm_gpio **); diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h new file mode 100644 index 0000000000000..35a9cfc9301d4 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h @@ -0,0 +1,8 @@ +#ifndef __NVKM_FAULT_H__ +#define __NVKM_FAULT_H__ +#include + +struct nvkm_fault { + struct nvkm_subdev subdev; +}; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c index a134d225f9588..c707306ac286f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c @@ -35,6 +35,7 @@ nvkm_subdev_name[NVKM_SUBDEV_NR] = { [NVKM_SUBDEV_BUS ] = "bus", [NVKM_SUBDEV_CLK ] = "clk", [NVKM_SUBDEV_DEVINIT ] = "devinit", + [NVKM_SUBDEV_FAULT ] = "fault", [NVKM_SUBDEV_FB ] = "fb", [NVKM_SUBDEV_FUSE ] = "fuse", [NVKM_SUBDEV_GPIO ] = "gpio", diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 05cd674326a63..70f3cc0844c9b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2420,6 +2420,7 @@ nvkm_device_subdev(struct nvkm_device *device, int index) _(BUS , device->bus , &device->bus->subdev); _(CLK , device->clk , &device->clk->subdev); _(DEVINIT , device->devinit , &device->devinit->subdev); + _(FAULT , device->fault , &device->fault->subdev); _(FB , device->fb , &device->fb->subdev); _(FUSE , device->fuse , &device->fuse->subdev); _(GPIO , device->gpio , &device->gpio->subdev); @@ -2891,6 +2892,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, _(NVKM_SUBDEV_BUS , bus); _(NVKM_SUBDEV_CLK , clk); _(NVKM_SUBDEV_DEVINIT , devinit); + _(NVKM_SUBDEV_FAULT , fault); _(NVKM_SUBDEV_FB , fb); _(NVKM_SUBDEV_FUSE , fuse); _(NVKM_SUBDEV_GPIO , gpio); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h index 08d0bf6057221..253ab914a8ef8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild index 3f5d38d74fba4..cfdffef1afb9e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild @@ -3,6 +3,7 @@ include $(src)/nvkm/subdev/bios/Kbuild include $(src)/nvkm/subdev/bus/Kbuild include $(src)/nvkm/subdev/clk/Kbuild include $(src)/nvkm/subdev/devinit/Kbuild +include $(src)/nvkm/subdev/fault/Kbuild include $(src)/nvkm/subdev/fb/Kbuild include $(src)/nvkm/subdev/fuse/Kbuild include $(src)/nvkm/subdev/gpio/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild new file mode 100644 index 0000000000000..e69de29bb2d1d From 2f68234fb3e7d0b123a8166ba46bd5c3e577b270 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 004/165] drm/nouveau/mc/gp100-: route fault buffer interrupts to FAULT Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/subdev/mc/gp100.c | 20 ++++++++++++++++++- .../gpu/drm/nouveau/nvkm/subdev/mc/gp10b.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h | 2 ++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gp100.c index 7321ad3758c3b..43db245eec9af 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gp100.c @@ -75,10 +75,28 @@ gp100_mc_intr_mask(struct nvkm_mc *base, u32 mask, u32 intr) spin_unlock_irqrestore(&mc->lock, flags); } +const struct nvkm_mc_map +gp100_mc_intr[] = { + { 0x04000000, NVKM_ENGINE_DISP }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00000200, NVKM_SUBDEV_FAULT }, + { 0x40000000, NVKM_SUBDEV_IBUS }, + { 0x10000000, NVKM_SUBDEV_BUS }, + { 0x08000000, NVKM_SUBDEV_FB }, + { 0x02000000, NVKM_SUBDEV_LTC }, + { 0x01000000, NVKM_SUBDEV_PMU }, + { 0x00200000, NVKM_SUBDEV_GPIO }, + { 0x00200000, NVKM_SUBDEV_I2C }, + { 0x00100000, NVKM_SUBDEV_TIMER }, + { 0x00040000, NVKM_SUBDEV_THERM }, + { 0x00002000, NVKM_SUBDEV_FB }, + {}, +}; + static const struct nvkm_mc_func gp100_mc = { .init = nv50_mc_init, - .intr = gk104_mc_intr, + .intr = gp100_mc_intr, .intr_unarm = gp100_mc_intr_unarm, .intr_rearm = gp100_mc_intr_rearm, .intr_mask = gp100_mc_intr_mask, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gp10b.c index 2283e3b742775..ff8629de97d64 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gp10b.c @@ -34,7 +34,7 @@ gp10b_mc_init(struct nvkm_mc *mc) static const struct nvkm_mc_func gp10b_mc = { .init = gp10b_mc_init, - .intr = gk104_mc_intr, + .intr = gp100_mc_intr, .intr_unarm = gp100_mc_intr_unarm, .intr_rearm = gp100_mc_intr_rearm, .intr_mask = gp100_mc_intr_mask, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h index 8869d79c2b597..d9e3691d45b79 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h @@ -57,4 +57,6 @@ int gp100_mc_new_(const struct nvkm_mc_func *, struct nvkm_device *, int, extern const struct nvkm_mc_map gk104_mc_intr[]; extern const struct nvkm_mc_map gk104_mc_reset[]; + +extern const struct nvkm_mc_map gp100_mc_intr[]; #endif From 36780d7eee827047bd9e736f6e2c0be650f30b4e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 005/165] drm/nouveau/fault: add infrastructure to support fault buffers GPU-specific support will be added separately. Signed-off-by: Ben Skeggs --- .../drm/nouveau/include/nvkm/subdev/fault.h | 6 + .../gpu/drm/nouveau/nvkm/subdev/fault/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/fault/base.c | 179 ++++++++++++++++++ .../gpu/drm/nouveau/nvkm/subdev/fault/priv.h | 34 ++++ 4 files changed, 220 insertions(+) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h index 35a9cfc9301d4..6ba9c179aa09b 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h @@ -3,6 +3,12 @@ #include struct nvkm_fault { + const struct nvkm_fault_func *func; struct nvkm_subdev subdev; + + struct nvkm_fault_buffer *buffer[1]; + int buffer_nr; + + struct nvkm_event event; }; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild index e69de29bb2d1d..2e4c226634a1a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild @@ -0,0 +1 @@ +nvkm-y += nvkm/subdev/fault/base.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c new file mode 100644 index 0000000000000..007bf4af33b99 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c @@ -0,0 +1,179 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "priv.h" + +#include +#include +#include +#include + +static void +nvkm_fault_ntfy_fini(struct nvkm_event *event, int type, int index) +{ + struct nvkm_fault *fault = container_of(event, typeof(*fault), event); + fault->func->buffer.fini(fault->buffer[index]); +} + +static void +nvkm_fault_ntfy_init(struct nvkm_event *event, int type, int index) +{ + struct nvkm_fault *fault = container_of(event, typeof(*fault), event); + fault->func->buffer.init(fault->buffer[index]); +} + +static int +nvkm_fault_ntfy_ctor(struct nvkm_object *object, void *argv, u32 argc, + struct nvkm_notify *notify) +{ + struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object); + if (argc == 0) { + notify->size = 0; + notify->types = 1; + notify->index = buffer->id; + return 0; + } + return -ENOSYS; +} + +static const struct nvkm_event_func +nvkm_fault_ntfy = { + .ctor = nvkm_fault_ntfy_ctor, + .init = nvkm_fault_ntfy_init, + .fini = nvkm_fault_ntfy_fini, +}; + +static void +nvkm_fault_intr(struct nvkm_subdev *subdev) +{ + struct nvkm_fault *fault = nvkm_fault(subdev); + return fault->func->intr(fault); +} + +static int +nvkm_fault_fini(struct nvkm_subdev *subdev, bool suspend) +{ + struct nvkm_fault *fault = nvkm_fault(subdev); + if (fault->func->fini) + fault->func->fini(fault); + return 0; +} + +static int +nvkm_fault_init(struct nvkm_subdev *subdev) +{ + struct nvkm_fault *fault = nvkm_fault(subdev); + if (fault->func->init) + fault->func->init(fault); + return 0; +} + +static int +nvkm_fault_oneinit_buffer(struct nvkm_fault *fault, int id) +{ + struct nvkm_subdev *subdev = &fault->subdev; + struct nvkm_device *device = subdev->device; + struct nvkm_vmm *bar2 = nvkm_bar_bar2_vmm(device); + struct nvkm_fault_buffer *buffer; + int ret; + + if (!(buffer = kzalloc(sizeof(*buffer), GFP_KERNEL))) + return -ENOMEM; + buffer->fault = fault; + buffer->id = id; + buffer->entries = fault->func->buffer.entries(buffer); + fault->buffer[id] = buffer; + + nvkm_debug(subdev, "buffer %d: %d entries\n", id, buffer->entries); + + ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, buffer->entries * + fault->func->buffer.entry_size, 0x1000, true, + &buffer->mem); + if (ret) + return ret; + + ret = nvkm_vmm_get(bar2, 12, nvkm_memory_size(buffer->mem), + &buffer->vma); + if (ret) + return ret; + + return nvkm_memory_map(buffer->mem, 0, bar2, buffer->vma, NULL, 0); +} + +static int +nvkm_fault_oneinit(struct nvkm_subdev *subdev) +{ + struct nvkm_fault *fault = nvkm_fault(subdev); + int ret, i; + + for (i = 0; i < ARRAY_SIZE(fault->buffer); i++) { + if (i < fault->func->buffer.nr) { + ret = nvkm_fault_oneinit_buffer(fault, i); + if (ret) + return ret; + fault->buffer_nr = i + 1; + } + } + + return nvkm_event_init(&nvkm_fault_ntfy, 1, fault->buffer_nr, + &fault->event); +} + +static void * +nvkm_fault_dtor(struct nvkm_subdev *subdev) +{ + struct nvkm_vmm *bar2 = nvkm_bar_bar2_vmm(subdev->device); + struct nvkm_fault *fault = nvkm_fault(subdev); + int i; + + nvkm_event_fini(&fault->event); + + for (i = 0; i < fault->buffer_nr; i++) { + if (fault->buffer[i]) { + nvkm_vmm_put(bar2, &fault->buffer[i]->vma); + nvkm_memory_unref(&fault->buffer[i]->mem); + kfree(fault->buffer[i]); + } + } + + return fault; +} + +static const struct nvkm_subdev_func +nvkm_fault = { + .dtor = nvkm_fault_dtor, + .oneinit = nvkm_fault_oneinit, + .init = nvkm_fault_init, + .fini = nvkm_fault_fini, + .intr = nvkm_fault_intr, +}; + +int +nvkm_fault_new_(const struct nvkm_fault_func *func, struct nvkm_device *device, + int index, struct nvkm_fault **pfault) +{ + struct nvkm_fault *fault; + if (!(fault = *pfault = kzalloc(sizeof(*fault), GFP_KERNEL))) + return -ENOMEM; + nvkm_subdev_ctor(&nvkm_fault, device, index, &fault->subdev); + fault->func = func; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h new file mode 100644 index 0000000000000..44843ecf12b07 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h @@ -0,0 +1,34 @@ +#ifndef __NVKM_FAULT_PRIV_H__ +#define __NVKM_FAULT_PRIV_H__ +#define nvkm_fault_buffer(p) container_of((p), struct nvkm_fault_buffer, object) +#define nvkm_fault(p) container_of((p), struct nvkm_fault, subdev) +#include + +#include +#include + +struct nvkm_fault_buffer { + struct nvkm_object object; + struct nvkm_fault *fault; + int id; + int entries; + struct nvkm_memory *mem; + struct nvkm_vma *vma; +}; + +int nvkm_fault_new_(const struct nvkm_fault_func *, struct nvkm_device *, + int index, struct nvkm_fault **); + +struct nvkm_fault_func { + void (*init)(struct nvkm_fault *); + void (*fini)(struct nvkm_fault *); + void (*intr)(struct nvkm_fault *); + struct { + int nr; + u32 entry_size; + u32 (*entries)(struct nvkm_fault_buffer *); + void (*init)(struct nvkm_fault_buffer *); + void (*fini)(struct nvkm_fault_buffer *); + } buffer; +}; +#endif From d0e9351e420695907e28e921d3786265253787c1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 006/165] drm/nouveau/fault/gp100: implement replayable fault buffer initialisation Signed-off-by: Ben Skeggs --- .../drm/nouveau/include/nvkm/subdev/fault.h | 2 + .../gpu/drm/nouveau/nvkm/engine/device/base.c | 7 ++ .../gpu/drm/nouveau/nvkm/subdev/fault/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/fault/gp100.c | 69 +++++++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp100.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h index 6ba9c179aa09b..8ca66e5727796 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h @@ -11,4 +11,6 @@ struct nvkm_fault { struct nvkm_event event; }; + +int gp100_fault_new(struct nvkm_device *, int, struct nvkm_fault **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 70f3cc0844c9b..379e701962a7b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2161,6 +2161,7 @@ nv130_chipset = { .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gm200_devinit_new, + .fault = gp100_fault_new, .fb = gp100_fb_new, .fuse = gm107_fuse_new, .gpio = gk104_gpio_new, @@ -2196,6 +2197,7 @@ nv132_chipset = { .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gm200_devinit_new, + .fault = gp100_fault_new, .fb = gp102_fb_new, .fuse = gm107_fuse_new, .gpio = gk104_gpio_new, @@ -2231,6 +2233,7 @@ nv134_chipset = { .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gm200_devinit_new, + .fault = gp100_fault_new, .fb = gp102_fb_new, .fuse = gm107_fuse_new, .gpio = gk104_gpio_new, @@ -2266,6 +2269,7 @@ nv136_chipset = { .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gm200_devinit_new, + .fault = gp100_fault_new, .fb = gp102_fb_new, .fuse = gm107_fuse_new, .gpio = gk104_gpio_new, @@ -2301,6 +2305,7 @@ nv137_chipset = { .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gm200_devinit_new, + .fault = gp100_fault_new, .fb = gp102_fb_new, .fuse = gm107_fuse_new, .gpio = gk104_gpio_new, @@ -2336,6 +2341,7 @@ nv138_chipset = { .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gm200_devinit_new, + .fault = gp100_fault_new, .fb = gp102_fb_new, .fuse = gm107_fuse_new, .gpio = gk104_gpio_new, @@ -2369,6 +2375,7 @@ nv13b_chipset = { .name = "GP10B", .bar = gm20b_bar_new, .bus = gf100_bus_new, + .fault = gp100_fault_new, .fb = gp10b_fb_new, .fuse = gm107_fuse_new, .ibus = gp10b_ibus_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild index 2e4c226634a1a..807ea402a162e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild @@ -1 +1,2 @@ nvkm-y += nvkm/subdev/fault/base.o +nvkm-y += nvkm/subdev/fault/gp100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp100.c new file mode 100644 index 0000000000000..5e71db2e8d750 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp100.c @@ -0,0 +1,69 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "priv.h" + +#include + +static void +gp100_fault_buffer_fini(struct nvkm_fault_buffer *buffer) +{ + struct nvkm_device *device = buffer->fault->subdev.device; + nvkm_mask(device, 0x002a70, 0x00000001, 0x00000000); +} + +static void +gp100_fault_buffer_init(struct nvkm_fault_buffer *buffer) +{ + struct nvkm_device *device = buffer->fault->subdev.device; + nvkm_wr32(device, 0x002a74, upper_32_bits(buffer->vma->addr)); + nvkm_wr32(device, 0x002a70, lower_32_bits(buffer->vma->addr)); + nvkm_mask(device, 0x002a70, 0x00000001, 0x00000001); +} + +static u32 +gp100_fault_buffer_entries(struct nvkm_fault_buffer *buffer) +{ + return nvkm_rd32(buffer->fault->subdev.device, 0x002a78); +} + +static void +gp100_fault_intr(struct nvkm_fault *fault) +{ + nvkm_event_send(&fault->event, 1, 0, NULL, 0); +} + +static const struct nvkm_fault_func +gp100_fault = { + .intr = gp100_fault_intr, + .buffer.nr = 1, + .buffer.entry_size = 32, + .buffer.entries = gp100_fault_buffer_entries, + .buffer.init = gp100_fault_buffer_init, + .buffer.fini = gp100_fault_buffer_fini, +}; + +int +gp100_fault_new(struct nvkm_device *device, int index, + struct nvkm_fault **pfault) +{ + return nvkm_fault_new_(&gp100_fault, device, index, pfault); +} From d1ea77ab5f7cf378864255fa90f1ab70676a2a10 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 007/165] drm/nouveau/fb/gf100-: bump size of mmu debug buffers to match big page size Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c index cdc4e0a2cc6bf..e8dc4e913494a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c @@ -46,10 +46,10 @@ gf100_fb_oneinit(struct nvkm_fb *base) { struct gf100_fb *fb = gf100_fb(base); struct nvkm_device *device = fb->base.subdev.device; - int ret, size = 0x1000; + int ret, size = 1 << (fb->base.page ? fb->base.page : 17); size = nvkm_longopt(device->cfgopt, "MmuDebugBufferSize", size); - size = min(size, 0x1000); + size = max(size, 0x1000); ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, size, 0x1000, true, &fb->base.mmu_rd); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c index 147f69b30cd82..d0a47b9a8cd85 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c @@ -48,7 +48,7 @@ gp100_fb_init(struct nvkm_fb *base) nvkm_wr32(device, 0x100cc8, nvkm_memory_addr(fb->base.mmu_wr) >> 8); nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(fb->base.mmu_rd) >> 8); nvkm_mask(device, 0x100cc4, 0x00060000, - max(nvkm_memory_size(fb->base.mmu_rd) >> 16, (u64)2) << 17); + min(nvkm_memory_size(fb->base.mmu_rd) >> 16, (u64)2) << 17); } static const struct nvkm_fb_func From 85a3b9c8398b2c4c3698a9d851165acf4ffc8d26 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 008/165] drm/nouveau/fb/gm200-: fix overwriting of big page setting Likely a rebase bug. Should have no impact in default configuration due to using per-instance setting by default. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c index 8137e19d32923..d3b8c3367152b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c @@ -49,8 +49,6 @@ gm200_fb_init(struct nvkm_fb *base) if (fb->r100c10_page) nvkm_wr32(device, 0x100c10, fb->r100c10 >> 8); - nvkm_mask(device, 0x100c80, 0x00000001, 0x00000000); /* 128KiB lpg */ - nvkm_wr32(device, 0x100cc8, nvkm_memory_addr(fb->base.mmu_wr) >> 8); nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(fb->base.mmu_rd) >> 8); nvkm_mask(device, 0x100cc4, 0x00060000, From 3b9ba66ab0e027e6d7a2b9b62cbb5cd547421ebd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 009/165] drm/nouveau/disp/nv50-: delay subunit construction until oneinit We should be reading registers to determine which subunits are really present on a given board, and this needs to be done after DEVINIT. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/disp/base.c | 6 ++ .../gpu/drm/nouveau/nvkm/engine/disp/nv50.c | 66 +++++++++++-------- .../gpu/drm/nouveau/nvkm/engine/disp/nv50.h | 4 ++ .../gpu/drm/nouveau/nvkm/engine/disp/priv.h | 1 + 4 files changed, 51 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c index 93a75e5b27911..5b9d9c632aeb1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c @@ -376,6 +376,12 @@ nvkm_disp_oneinit(struct nvkm_engine *engine) if (ret) return ret; + if (disp->func->oneinit) { + ret = disp->func->oneinit(disp); + if (ret) + return ret; + } + i = 0; list_for_each_entry(head, &disp->head, head) i = max(i, head->id + 1); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c index 0c570dbd3021b..43373b3662632 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c @@ -59,9 +59,44 @@ nv50_disp_dtor_(struct nvkm_disp *base) return disp; } +static int +nv50_disp_oneinit_(struct nvkm_disp *base) +{ + struct nv50_disp *disp = nv50_disp(base); + const struct nv50_disp_func *func = disp->func; + int ret, i; + + for (i = 0; func->head.new && i < disp->head.nr; i++) { + ret = func->head.new(&disp->base, i); + if (ret) + return ret; + } + + for (i = 0; func->dac.new && i < func->dac.nr; i++) { + ret = func->dac.new(&disp->base, i); + if (ret) + return ret; + } + + for (i = 0; func->pior.new && i < func->pior.nr; i++) { + ret = func->pior.new(&disp->base, i); + if (ret) + return ret; + } + + for (i = 0; func->sor.new && i < func->sor.nr; i++) { + ret = func->sor.new(&disp->base, i); + if (ret) + return ret; + } + + return 0; +} + static const struct nvkm_disp_func nv50_disp_ = { .dtor = nv50_disp_dtor_, + .oneinit = nv50_disp_oneinit_, .intr = nv50_disp_intr_, .root = nv50_disp_root_, }; @@ -71,7 +106,7 @@ nv50_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device, int index, int heads, struct nvkm_disp **pdisp) { struct nv50_disp *disp; - int ret, i; + int ret; if (!(disp = kzalloc(sizeof(*disp), GFP_KERNEL))) return -ENOMEM; @@ -85,33 +120,12 @@ nv50_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device, disp->wq = create_singlethread_workqueue("nvkm-disp"); if (!disp->wq) return -ENOMEM; - INIT_WORK(&disp->supervisor, func->super); - - for (i = 0; func->head.new && i < heads; i++) { - ret = func->head.new(&disp->base, i); - if (ret) - return ret; - } - for (i = 0; func->dac.new && i < func->dac.nr; i++) { - ret = func->dac.new(&disp->base, i); - if (ret) - return ret; - } - - for (i = 0; func->pior.new && i < func->pior.nr; i++) { - ret = func->pior.new(&disp->base, i); - if (ret) - return ret; - } - - for (i = 0; func->sor.new && i < func->sor.nr; i++) { - ret = func->sor.new(&disp->base, i); - if (ret) - return ret; - } + INIT_WORK(&disp->supervisor, func->super); + disp->head.nr = heads; - return nvkm_event_init(func->uevent, 1, 1 + (heads * 4), &disp->uevent); + return nvkm_event_init(func->uevent, 1, ARRAY_SIZE(disp->chan), + &disp->uevent); } static u32 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h index eb0b8acb1c5bb..0ae32cda45e71 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h @@ -15,6 +15,10 @@ struct nv50_disp { struct nvkm_event uevent; + struct { + int nr; + } head; + struct { u32 lvdsconf; } sor; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h index 6c9bfff6d043b..c614351f50127 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h @@ -12,6 +12,7 @@ void nvkm_disp_vblank(struct nvkm_disp *, int head); struct nvkm_disp_func { void *(*dtor)(struct nvkm_disp *); + int (*oneinit)(struct nvkm_disp *); void (*intr)(struct nvkm_disp *); const struct nvkm_disp_oclass *(*root)(struct nvkm_disp *); From f7b2ece37fce822692d3d6e616e0d0f3df9d4f49 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 010/165] drm/nouveau/disp/nv50-: fetch mask of available heads during oneinit Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c | 12 ++---------- drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h | 4 ++++ .../gpu/drm/nouveau/nvkm/engine/disp/headgf119.c | 11 ++++++++--- drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv50.c | 7 +++++++ drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c | 13 ++++++++----- drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h | 6 +++--- 18 files changed, 56 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c index 842e1b72ee421..a1741a80bd050 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c @@ -32,7 +32,7 @@ g84_disp = { .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, .root = &g84_disp_root_oclass, - .head.new = nv50_head_new, + .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .nr = 3, .new = nv50_dac_new }, .sor = { .nr = 2, .new = g84_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, @@ -41,5 +41,5 @@ g84_disp = { int g84_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return nv50_disp_new_(&g84_disp, device, index, 2, pdisp); + return nv50_disp_new_(&g84_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c index d184e6ab8918d..b7febc4b0f856 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c @@ -32,7 +32,7 @@ g94_disp = { .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, .root = &g94_disp_root_oclass, - .head.new = nv50_head_new, + .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .nr = 3, .new = nv50_dac_new }, .sor = { .nr = 4, .new = g94_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, @@ -41,5 +41,5 @@ g94_disp = { int g94_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return nv50_disp_new_(&g94_disp, device, index, 2, pdisp); + return nv50_disp_new_(&g94_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c index d8765b57180b9..b580ca9b4418b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c @@ -164,14 +164,6 @@ gf119_disp_intr(struct nv50_disp *disp) } } -int -gf119_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device, - int index, struct nvkm_disp **pdisp) -{ - u32 heads = nvkm_rd32(device, 0x022448); - return nv50_disp_new_(func, device, index, heads, pdisp); -} - static const struct nv50_disp_func gf119_disp = { .intr = gf119_disp_intr, @@ -179,7 +171,7 @@ gf119_disp = { .uevent = &gf119_disp_chan_uevent, .super = gf119_disp_super, .root = &gf119_disp_root_oclass, - .head.new = gf119_head_new, + .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .dac = { .nr = 3, .new = gf119_dac_new }, .sor = { .nr = 4, .new = gf119_sor_new }, }; @@ -187,5 +179,5 @@ gf119_disp = { int gf119_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return gf119_disp_new_(&gf119_disp, device, index, pdisp); + return nv50_disp_new_(&gf119_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c index e8fe9f315d641..b3ee5b1d4a45f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c @@ -33,7 +33,7 @@ gk104_disp = { .uevent = &gf119_disp_chan_uevent, .super = gf119_disp_super, .root = &gk104_disp_root_oclass, - .head.new = gf119_head_new, + .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .dac = { .nr = 3, .new = gf119_dac_new }, .sor = { .nr = 4, .new = gk104_sor_new }, }; @@ -41,5 +41,5 @@ gk104_disp = { int gk104_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return gf119_disp_new_(&gk104_disp, device, index, pdisp); + return nv50_disp_new_(&gk104_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c index 769687502e7a8..22533abbfb67c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c @@ -33,7 +33,7 @@ gk110_disp = { .uevent = &gf119_disp_chan_uevent, .super = gf119_disp_super, .root = &gk110_disp_root_oclass, - .head.new = gf119_head_new, + .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .dac = { .nr = 3, .new = gf119_dac_new }, .sor = { .nr = 4, .new = gk104_sor_new }, }; @@ -41,5 +41,5 @@ gk110_disp = { int gk110_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return gf119_disp_new_(&gk110_disp, device, index, pdisp); + return nv50_disp_new_(&gk110_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c index ede70e5d188e2..85e602120abc3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c @@ -33,7 +33,7 @@ gm107_disp = { .uevent = &gf119_disp_chan_uevent, .super = gf119_disp_super, .root = &gm107_disp_root_oclass, - .head.new = gf119_head_new, + .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .dac = { .nr = 3, .new = gf119_dac_new }, .sor = { .nr = 4, .new = gm107_sor_new }, }; @@ -41,5 +41,5 @@ gm107_disp = { int gm107_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return gf119_disp_new_(&gm107_disp, device, index, pdisp); + return nv50_disp_new_(&gm107_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c index 292d3b5f97046..48ab65d827178 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c @@ -33,7 +33,7 @@ gm200_disp = { .uevent = &gf119_disp_chan_uevent, .super = gf119_disp_super, .root = &gm200_disp_root_oclass, - .head.new = gf119_head_new, + .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .dac = { .nr = 3, .new = gf119_dac_new }, .sor = { .nr = 4, .new = gm200_sor_new }, }; @@ -41,5 +41,5 @@ gm200_disp = { int gm200_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return gf119_disp_new_(&gm200_disp, device, index, pdisp); + return nv50_disp_new_(&gm200_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c index 39eb98b2c3a24..190d03025fc1b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c @@ -33,12 +33,12 @@ gp100_disp = { .uevent = &gf119_disp_chan_uevent, .super = gf119_disp_super, .root = &gp100_disp_root_oclass, - .head.new = gf119_head_new, + .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .sor = { .nr = 4, .new = gm200_sor_new }, }; int gp100_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return gf119_disp_new_(&gp100_disp, device, index, pdisp); + return nv50_disp_new_(&gp100_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c index 91d70fe18275a..a059c65243a93 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c @@ -59,12 +59,12 @@ gp102_disp = { .uevent = &gf119_disp_chan_uevent, .super = gf119_disp_super, .root = &gp102_disp_root_oclass, - .head.new = gf119_head_new, + .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .sor = { .nr = 4, .new = gm200_sor_new }, }; int gp102_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return gf119_disp_new_(&gp102_disp, device, index, pdisp); + return nv50_disp_new_(&gp102_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c index bf00c4e3be3ac..7554c732a655a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c @@ -32,7 +32,7 @@ gt200_disp = { .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, .root = >200_disp_root_oclass, - .head.new = nv50_head_new, + .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .nr = 3, .new = nv50_dac_new }, .sor = { .nr = 2, .new = g84_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, @@ -41,5 +41,5 @@ gt200_disp = { int gt200_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return nv50_disp_new_(>200_disp, device, index, 2, pdisp); + return nv50_disp_new_(>200_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c index 2cdd4d7a98d30..6a878a7e6af35 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c @@ -32,7 +32,7 @@ gt215_disp = { .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, .root = >215_disp_root_oclass, - .head.new = nv50_head_new, + .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .nr = 3, .new = nv50_dac_new }, .sor = { .nr = 4, .new = gt215_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, @@ -41,5 +41,5 @@ gt215_disp = { int gt215_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return nv50_disp_new_(>215_disp, device, index, 2, pdisp); + return nv50_disp_new_(>215_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h index 57030b3a4a753..4a5d7892ff549 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h @@ -52,6 +52,10 @@ void nv50_head_rgpos(struct nvkm_head *, u16 *, u16 *); #define HEAD_DBG(h,f,a...) HEAD_MSG((h), debug, f, ##a) int nv04_head_new(struct nvkm_disp *, int id); + +int nv50_head_cnt(struct nvkm_disp *, unsigned long *); int nv50_head_new(struct nvkm_disp *, int id); + +int gf119_head_cnt(struct nvkm_disp *, unsigned long *); int gf119_head_new(struct nvkm_disp *, int id); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c index 9fd7ae3313080..bcbdaaf8ba202 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c @@ -92,8 +92,13 @@ gf119_head = { int gf119_head_new(struct nvkm_disp *disp, int id) { - struct nvkm_device *device = disp->engine.subdev.device; - if (!(nvkm_rd32(device, 0x612004) & (0x00000001 << id))) - return 0; return nvkm_head_new_(&gf119_head, disp, id); } + +int +gf119_head_cnt(struct nvkm_disp *disp, unsigned long *pmask) +{ + struct nvkm_device *device = disp->engine.subdev.device; + *pmask = nvkm_rd32(device, 0x612004) & 0x0000000f; + return nvkm_rd32(device, 0x022448); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv50.c index c80d06d5168f5..e7d5c397cd298 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv50.c @@ -90,3 +90,10 @@ nv50_head_new(struct nvkm_disp *disp, int id) { return nvkm_head_new_(&nv50_head, disp, id); } + +int +nv50_head_cnt(struct nvkm_disp *disp, unsigned long *pmask) +{ + *pmask = 3; + return 2; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c index d7e0fbb12bf11..9fc7507774e15 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c @@ -30,7 +30,7 @@ mcp77_disp = { .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, .root = &g94_disp_root_oclass, - .head.new = nv50_head_new, + .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .nr = 3, .new = nv50_dac_new }, .sor = { .nr = 4, .new = mcp77_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, @@ -39,5 +39,5 @@ mcp77_disp = { int mcp77_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return nv50_disp_new_(&mcp77_disp, device, index, 2, pdisp); + return nv50_disp_new_(&mcp77_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c index 7b75c57c12edf..28647d365057d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c @@ -30,7 +30,7 @@ mcp89_disp = { .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, .root = >215_disp_root_oclass, - .head.new = nv50_head_new, + .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .nr = 3, .new = nv50_dac_new }, .sor = { .nr = 4, .new = mcp89_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, @@ -39,5 +39,5 @@ mcp89_disp = { int mcp89_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return nv50_disp_new_(&mcp89_disp, device, index, 2, pdisp); + return nv50_disp_new_(&mcp89_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c index 43373b3662632..bf50b7be88267 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c @@ -64,9 +64,13 @@ nv50_disp_oneinit_(struct nvkm_disp *base) { struct nv50_disp *disp = nv50_disp(base); const struct nv50_disp_func *func = disp->func; + struct nvkm_subdev *subdev = &disp->base.engine.subdev; int ret, i; - for (i = 0; func->head.new && i < disp->head.nr; i++) { + disp->head.nr = func->head.cnt(&disp->base, &disp->head.mask); + nvkm_debug(subdev, " Head(s): %d (%02lx)\n", + disp->head.nr, disp->head.mask); + for_each_set_bit(i, &disp->head.mask, disp->head.nr) { ret = func->head.new(&disp->base, i); if (ret) return ret; @@ -103,7 +107,7 @@ nv50_disp_ = { int nv50_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device, - int index, int heads, struct nvkm_disp **pdisp) + int index, struct nvkm_disp **pdisp) { struct nv50_disp *disp; int ret; @@ -122,7 +126,6 @@ nv50_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device, return -ENOMEM; INIT_WORK(&disp->supervisor, func->super); - disp->head.nr = heads; return nvkm_event_init(func->uevent, 1, ARRAY_SIZE(disp->chan), &disp->uevent); @@ -633,7 +636,7 @@ nv50_disp = { .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, .root = &nv50_disp_root_oclass, - .head.new = nv50_head_new, + .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .nr = 3, .new = nv50_dac_new }, .sor = { .nr = 2, .new = nv50_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, @@ -642,5 +645,5 @@ nv50_disp = { int nv50_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) { - return nv50_disp_new_(&nv50_disp, device, index, 2, pdisp); + return nv50_disp_new_(&nv50_disp, device, index, pdisp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h index 0ae32cda45e71..c7fe29cf3e053 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h @@ -16,6 +16,7 @@ struct nv50_disp { struct nvkm_event uevent; struct { + unsigned long mask; int nr; } head; @@ -38,9 +39,7 @@ void nv50_disp_super_2_2(struct nv50_disp *, struct nvkm_head *); void nv50_disp_super_3_0(struct nv50_disp *, struct nvkm_head *); int nv50_disp_new_(const struct nv50_disp_func *, struct nvkm_device *, - int index, int heads, struct nvkm_disp **); -int gf119_disp_new_(const struct nv50_disp_func *, struct nvkm_device *, - int index, struct nvkm_disp **); + int index, struct nvkm_disp **); struct nv50_disp_func { void (*intr)(struct nv50_disp *); @@ -52,6 +51,7 @@ struct nv50_disp_func { const struct nvkm_disp_oclass *root; struct { + int (*cnt)(struct nvkm_disp *, unsigned long *mask); int (*new)(struct nvkm_disp *, int id); } head; From bf5d1a6b6a4489b7887589fca6321d4024da71c8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 011/165] drm/nouveau/disp/nv50-: fetch mask of available dacs during oneinit Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c | 11 ++++++++--- .../gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c | 11 ++++++++--- drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h | 3 +++ drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c | 15 ++++++++++----- drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h | 9 ++------- .../gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c | 2 +- 18 files changed, 44 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c index dbd032ef352ae..71a94777ea2e6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c @@ -58,8 +58,13 @@ gf119_dac = { int gf119_dac_new(struct nvkm_disp *disp, int id) { - struct nvkm_device *device = disp->engine.subdev.device; - if (!(nvkm_rd32(device, 0x612004) & (0x00000010 << id))) - return 0; return nvkm_ior_new_(&gf119_dac, disp, DAC, id); } + +int +gf119_dac_cnt(struct nvkm_disp *disp, unsigned long *pmask) +{ + struct nvkm_device *device = disp->engine.subdev.device; + *pmask = (nvkm_rd32(device, 0x612004) & 0x000000f0) >> 4; + return 4; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c index 85e692b122602..558012db35f85 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c @@ -109,8 +109,13 @@ nv50_dac = { int nv50_dac_new(struct nvkm_disp *disp, int id) { - struct nvkm_device *device = disp->engine.subdev.device; - if (!(nvkm_rd32(device, 0x610184) & (0x00100000 << id))) - return 0; return nvkm_ior_new_(&nv50_dac, disp, DAC, id); } + +int +nv50_dac_cnt(struct nvkm_disp *disp, unsigned long *pmask) +{ + struct nvkm_device *device = disp->engine.subdev.device; + *pmask = (nvkm_rd32(device, 0x610184) & 0x00700000) >> 20; + return 3; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c index a1741a80bd050..9f31f04e4e58e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c @@ -33,7 +33,7 @@ g84_disp = { .super = nv50_disp_super, .root = &g84_disp_root_oclass, .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, - .dac = { .nr = 3, .new = nv50_dac_new }, + .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, .sor = { .nr = 2, .new = g84_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c index b7febc4b0f856..71fe26b258354 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c @@ -33,7 +33,7 @@ g94_disp = { .super = nv50_disp_super, .root = &g94_disp_root_oclass, .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, - .dac = { .nr = 3, .new = nv50_dac_new }, + .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, .sor = { .nr = 4, .new = g94_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c index b580ca9b4418b..c8495bcf289cf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c @@ -172,7 +172,7 @@ gf119_disp = { .super = gf119_disp_super, .root = &gf119_disp_root_oclass, .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, - .dac = { .nr = 3, .new = gf119_dac_new }, + .dac = { .cnt = gf119_dac_cnt, .new = gf119_dac_new }, .sor = { .nr = 4, .new = gf119_sor_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c index b3ee5b1d4a45f..b948619818cc1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c @@ -34,7 +34,7 @@ gk104_disp = { .super = gf119_disp_super, .root = &gk104_disp_root_oclass, .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, - .dac = { .nr = 3, .new = gf119_dac_new }, + .dac = { .cnt = gf119_dac_cnt, .new = gf119_dac_new }, .sor = { .nr = 4, .new = gk104_sor_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c index 22533abbfb67c..0b4945703568e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c @@ -34,7 +34,7 @@ gk110_disp = { .super = gf119_disp_super, .root = &gk110_disp_root_oclass, .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, - .dac = { .nr = 3, .new = gf119_dac_new }, + .dac = { .cnt = gf119_dac_cnt, .new = gf119_dac_new }, .sor = { .nr = 4, .new = gk104_sor_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c index 85e602120abc3..35ad965ffee27 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c @@ -34,7 +34,7 @@ gm107_disp = { .super = gf119_disp_super, .root = &gm107_disp_root_oclass, .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, - .dac = { .nr = 3, .new = gf119_dac_new }, + .dac = { .cnt = gf119_dac_cnt, .new = gf119_dac_new }, .sor = { .nr = 4, .new = gm107_sor_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c index 48ab65d827178..b2a5d364ffaf4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c @@ -34,7 +34,7 @@ gm200_disp = { .super = gf119_disp_super, .root = &gm200_disp_root_oclass, .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, - .dac = { .nr = 3, .new = gf119_dac_new }, + .dac = { .cnt = gf119_dac_cnt, .new = gf119_dac_new }, .sor = { .nr = 4, .new = gm200_sor_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c index 7554c732a655a..88b6a34e9df7f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c @@ -33,7 +33,7 @@ gt200_disp = { .super = nv50_disp_super, .root = >200_disp_root_oclass, .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, - .dac = { .nr = 3, .new = nv50_dac_new }, + .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, .sor = { .nr = 2, .new = g84_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c index 6a878a7e6af35..1519ca566d9f8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c @@ -33,7 +33,7 @@ gt215_disp = { .super = nv50_disp_super, .root = >215_disp_root_oclass, .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, - .dac = { .nr = 3, .new = nv50_dac_new }, + .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, .sor = { .nr = 4, .new = gt215_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h index 4548c031b9375..89d9ab154c4b6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h @@ -153,7 +153,10 @@ void gf119_hda_eld(struct nvkm_ior *, u8 *, u8); #define IOR_WARN(i,f,a...) IOR_MSG((i), warn, f, ##a) #define IOR_DBG(i,f,a...) IOR_MSG((i), debug, f, ##a) +int nv50_dac_cnt(struct nvkm_disp *, unsigned long *); int nv50_dac_new(struct nvkm_disp *, int); + +int gf119_dac_cnt(struct nvkm_disp *, unsigned long *); int gf119_dac_new(struct nvkm_disp *, int); int nv50_pior_new(struct nvkm_disp *, int); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c index 9fc7507774e15..fb188546f5f8f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c @@ -31,7 +31,7 @@ mcp77_disp = { .super = nv50_disp_super, .root = &g94_disp_root_oclass, .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, - .dac = { .nr = 3, .new = nv50_dac_new }, + .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, .sor = { .nr = 4, .new = mcp77_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c index 28647d365057d..ae7fb96256748 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c @@ -31,7 +31,7 @@ mcp89_disp = { .super = nv50_disp_super, .root = >215_disp_root_oclass, .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, - .dac = { .nr = 3, .new = nv50_dac_new }, + .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, .sor = { .nr = 4, .new = mcp89_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c index bf50b7be88267..500ef8da696a0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c @@ -76,10 +76,15 @@ nv50_disp_oneinit_(struct nvkm_disp *base) return ret; } - for (i = 0; func->dac.new && i < func->dac.nr; i++) { - ret = func->dac.new(&disp->base, i); - if (ret) - return ret; + if (func->dac.cnt) { + disp->dac.nr = func->dac.cnt(&disp->base, &disp->dac.mask); + nvkm_debug(subdev, " DAC(s): %d (%02lx)\n", + disp->dac.nr, disp->dac.mask); + for_each_set_bit(i, &disp->dac.mask, disp->dac.nr) { + ret = func->dac.new(&disp->base, i); + if (ret) + return ret; + } } for (i = 0; func->pior.new && i < func->pior.nr; i++) { @@ -637,7 +642,7 @@ nv50_disp = { .super = nv50_disp_super, .root = &nv50_disp_root_oclass, .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, - .dac = { .nr = 3, .new = nv50_dac_new }, + .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, .sor = { .nr = 2, .new = nv50_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h index c7fe29cf3e053..3415a52584927 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h @@ -18,7 +18,7 @@ struct nv50_disp { struct { unsigned long mask; int nr; - } head; + } head, dac; struct { u32 lvdsconf; @@ -53,12 +53,7 @@ struct nv50_disp_func { struct { int (*cnt)(struct nvkm_disp *, unsigned long *mask); int (*new)(struct nvkm_disp *, int id); - } head; - - struct { - int nr; - int (*new)(struct nvkm_disp *, int id); - } dac; + } head, dac; struct { int nr; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c index 333c8424b413c..7f22b875b9b3e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c @@ -64,7 +64,7 @@ gf119_disp_root_init(struct nv50_disp_root *root) } /* ... DAC caps */ - for (i = 0; i < disp->func->dac.nr; i++) { + for (i = 0; i < disp->dac.nr; i++) { tmp = nvkm_rd32(device, 0x61a000 + (i * 0x800)); nvkm_wr32(device, 0x6101c0 + (i * 0x800), tmp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c index 1208524aae14e..3fbaccd9569bb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c @@ -427,7 +427,7 @@ nv50_disp_root_init(struct nv50_disp_root *root) } /* ... DAC caps */ - for (i = 0; i < disp->func->dac.nr; i++) { + for (i = 0; i < disp->dac.nr; i++) { tmp = nvkm_rd32(device, 0x61a000 + (i * 0x800)); nvkm_wr32(device, 0x6101d0 + (i * 0x04), tmp); } From 9fe4e177045f4b5af25d25859e30450ff1f18be9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 012/165] drm/nouveau/disp/nv50-: fetch mask of available sors during oneinit Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/disp/g84.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/g94.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/gf119.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/gk104.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/gk110.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/gm107.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/gm200.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/gp100.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/gp102.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/gt200.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/gt215.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/ior.h | 10 ++++++++-- .../gpu/drm/nouveau/nvkm/engine/disp/mcp77.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/mcp89.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/nv50.c | 7 +++++-- .../gpu/drm/nouveau/nvkm/engine/disp/nv50.h | 9 +++------ .../drm/nouveau/nvkm/engine/disp/rootgf119.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootnv50.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/sorg84.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/disp/sorg94.c | 10 +++++++++- .../drm/nouveau/nvkm/engine/disp/sorgf119.c | 19 +++++++++---------- .../drm/nouveau/nvkm/engine/disp/sorgk104.c | 2 +- .../drm/nouveau/nvkm/engine/disp/sorgm107.c | 2 +- .../drm/nouveau/nvkm/engine/disp/sorgm200.c | 2 +- .../drm/nouveau/nvkm/engine/disp/sorgt215.c | 2 +- .../drm/nouveau/nvkm/engine/disp/sormcp77.c | 2 +- .../drm/nouveau/nvkm/engine/disp/sormcp89.c | 2 +- .../drm/nouveau/nvkm/engine/disp/sornv50.c | 19 +++++++++---------- 28 files changed, 65 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c index 9f31f04e4e58e..287ac5edc88ab 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c @@ -34,7 +34,7 @@ g84_disp = { .root = &g84_disp_root_oclass, .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, - .sor = { .nr = 2, .new = g84_sor_new }, + .sor = { .cnt = nv50_sor_cnt, .new = g84_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c index 71fe26b258354..e21f76d4e28e3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c @@ -34,7 +34,7 @@ g94_disp = { .root = &g94_disp_root_oclass, .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, - .sor = { .nr = 4, .new = g94_sor_new }, + .sor = { .cnt = g94_sor_cnt, .new = g94_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c index c8495bcf289cf..0139d143c733b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c @@ -173,7 +173,7 @@ gf119_disp = { .root = &gf119_disp_root_oclass, .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .dac = { .cnt = gf119_dac_cnt, .new = gf119_dac_new }, - .sor = { .nr = 4, .new = gf119_sor_new }, + .sor = { .cnt = gf119_sor_cnt, .new = gf119_sor_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c index b948619818cc1..6a59a52468c1f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c @@ -35,7 +35,7 @@ gk104_disp = { .root = &gk104_disp_root_oclass, .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .dac = { .cnt = gf119_dac_cnt, .new = gf119_dac_new }, - .sor = { .nr = 4, .new = gk104_sor_new }, + .sor = { .cnt = gf119_sor_cnt, .new = gk104_sor_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c index 0b4945703568e..f3b10dc4e6735 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c @@ -35,7 +35,7 @@ gk110_disp = { .root = &gk110_disp_root_oclass, .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .dac = { .cnt = gf119_dac_cnt, .new = gf119_dac_new }, - .sor = { .nr = 4, .new = gk104_sor_new }, + .sor = { .cnt = gf119_sor_cnt, .new = gk104_sor_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c index 35ad965ffee27..068c5951efe38 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c @@ -35,7 +35,7 @@ gm107_disp = { .root = &gm107_disp_root_oclass, .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .dac = { .cnt = gf119_dac_cnt, .new = gf119_dac_new }, - .sor = { .nr = 4, .new = gm107_sor_new }, + .sor = { .cnt = gf119_sor_cnt, .new = gm107_sor_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c index b2a5d364ffaf4..1c27dbe6cceca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c @@ -35,7 +35,7 @@ gm200_disp = { .root = &gm200_disp_root_oclass, .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, .dac = { .cnt = gf119_dac_cnt, .new = gf119_dac_new }, - .sor = { .nr = 4, .new = gm200_sor_new }, + .sor = { .cnt = gf119_sor_cnt, .new = gm200_sor_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c index 190d03025fc1b..84933b6119f2c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c @@ -34,7 +34,7 @@ gp100_disp = { .super = gf119_disp_super, .root = &gp100_disp_root_oclass, .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, - .sor = { .nr = 4, .new = gm200_sor_new }, + .sor = { .cnt = gf119_sor_cnt, .new = gm200_sor_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c index a059c65243a93..b36d926f02642 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c @@ -60,7 +60,7 @@ gp102_disp = { .super = gf119_disp_super, .root = &gp102_disp_root_oclass, .head = { .cnt = gf119_head_cnt, .new = gf119_head_new }, - .sor = { .nr = 4, .new = gm200_sor_new }, + .sor = { .cnt = gf119_sor_cnt, .new = gm200_sor_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c index 88b6a34e9df7f..2ca92a23a62a4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c @@ -34,7 +34,7 @@ gt200_disp = { .root = >200_disp_root_oclass, .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, - .sor = { .nr = 2, .new = g84_sor_new }, + .sor = { .cnt = nv50_sor_cnt, .new = g84_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c index 1519ca566d9f8..73b0390696600 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c @@ -34,7 +34,7 @@ gt215_disp = { .root = >215_disp_root_oclass, .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, - .sor = { .nr = 4, .new = gt215_sor_new }, + .sor = { .cnt = g94_sor_cnt, .new = gt215_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h index 89d9ab154c4b6..6432e0611deec 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h @@ -106,7 +106,6 @@ nv50_sor_link(struct nvkm_ior *ior) return nv50_ior_base(ior) + ((ior->asy.link == 2) * 0x80); } -int nv50_sor_new_(const struct nvkm_ior_func *, struct nvkm_disp *, int id); void nv50_sor_state(struct nvkm_ior *, struct nvkm_ior_state *); void nv50_sor_power(struct nvkm_ior *, bool, bool, bool, bool, bool); void nv50_sor_clock(struct nvkm_ior *); @@ -122,7 +121,6 @@ void g94_sor_dp_watermark(struct nvkm_ior *, int, u8); void gt215_sor_dp_audio(struct nvkm_ior *, int, bool); -int gf119_sor_new_(const struct nvkm_ior_func *, struct nvkm_disp *, int id); void gf119_sor_state(struct nvkm_ior *, struct nvkm_ior_state *); void gf119_sor_clock(struct nvkm_ior *); int gf119_sor_dp_links(struct nvkm_ior *, struct nvkm_i2c_aux *); @@ -161,13 +159,21 @@ int gf119_dac_new(struct nvkm_disp *, int); int nv50_pior_new(struct nvkm_disp *, int); +int nv50_sor_cnt(struct nvkm_disp *, unsigned long *); int nv50_sor_new(struct nvkm_disp *, int); + int g84_sor_new(struct nvkm_disp *, int); + +int g94_sor_cnt(struct nvkm_disp *, unsigned long *); int g94_sor_new(struct nvkm_disp *, int); + int mcp77_sor_new(struct nvkm_disp *, int); int gt215_sor_new(struct nvkm_disp *, int); int mcp89_sor_new(struct nvkm_disp *, int); + +int gf119_sor_cnt(struct nvkm_disp *, unsigned long *); int gf119_sor_new(struct nvkm_disp *, int); + int gk104_sor_new(struct nvkm_disp *, int); int gm107_sor_new(struct nvkm_disp *, int); int gm200_sor_new(struct nvkm_disp *, int); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c index fb188546f5f8f..c3f6504ea67d2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c @@ -32,7 +32,7 @@ mcp77_disp = { .root = &g94_disp_root_oclass, .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, - .sor = { .nr = 4, .new = mcp77_sor_new }, + .sor = { .cnt = g94_sor_cnt, .new = mcp77_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c index ae7fb96256748..2d1d9218d2538 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c @@ -32,7 +32,7 @@ mcp89_disp = { .root = >215_disp_root_oclass, .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, - .sor = { .nr = 4, .new = mcp89_sor_new }, + .sor = { .cnt = g94_sor_cnt, .new = mcp89_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c index 500ef8da696a0..1e32814488bf5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c @@ -93,7 +93,10 @@ nv50_disp_oneinit_(struct nvkm_disp *base) return ret; } - for (i = 0; func->sor.new && i < func->sor.nr; i++) { + disp->sor.nr = func->sor.cnt(&disp->base, &disp->sor.mask); + nvkm_debug(subdev, " SOR(s): %d (%02lx)\n", + disp->sor.nr, disp->sor.mask); + for_each_set_bit(i, &disp->sor.mask, disp->sor.nr) { ret = func->sor.new(&disp->base, i); if (ret) return ret; @@ -643,7 +646,7 @@ nv50_disp = { .root = &nv50_disp_root_oclass, .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, - .sor = { .nr = 2, .new = nv50_sor_new }, + .sor = { .cnt = nv50_sor_cnt, .new = nv50_sor_new }, .pior = { .nr = 3, .new = nv50_pior_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h index 3415a52584927..ee2968b7aef16 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h @@ -21,6 +21,8 @@ struct nv50_disp { } head, dac; struct { + unsigned long mask; + int nr; u32 lvdsconf; } sor; @@ -53,12 +55,7 @@ struct nv50_disp_func { struct { int (*cnt)(struct nvkm_disp *, unsigned long *mask); int (*new)(struct nvkm_disp *, int id); - } head, dac; - - struct { - int nr; - int (*new)(struct nvkm_disp *, int id); - } sor; + } head, dac, sor; struct { int nr; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c index 7f22b875b9b3e..4ba2d80db52ba 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c @@ -70,7 +70,7 @@ gf119_disp_root_init(struct nv50_disp_root *root) } /* ... SOR caps */ - for (i = 0; i < disp->func->sor.nr; i++) { + for (i = 0; i < disp->sor.nr; i++) { tmp = nvkm_rd32(device, 0x61c000 + (i * 0x800)); nvkm_wr32(device, 0x6301c4 + (i * 0x800), tmp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c index 3fbaccd9569bb..9d0b5b71d38af 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c @@ -433,7 +433,7 @@ nv50_disp_root_init(struct nv50_disp_root *root) } /* ... SOR caps */ - for (i = 0; i < disp->func->sor.nr; i++) { + for (i = 0; i < disp->sor.nr; i++) { tmp = nvkm_rd32(device, 0x61c000 + (i * 0x800)); nvkm_wr32(device, 0x6101e0 + (i * 0x04), tmp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c index f40b909b4ca2d..ec3a7db081188 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c @@ -34,5 +34,5 @@ g84_sor = { int g84_sor_new(struct nvkm_disp *disp, int id) { - return nv50_sor_new_(&g84_sor, disp, id); + return nvkm_ior_new_(&g84_sor, disp, SOR, id); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c index 49aeafde0031e..4d59d02525d98 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c @@ -279,5 +279,13 @@ g94_sor = { int g94_sor_new(struct nvkm_disp *disp, int id) { - return nv50_sor_new_(&g94_sor, disp, id); + return nvkm_ior_new_(&g94_sor, disp, SOR, id); +} + +int +g94_sor_cnt(struct nvkm_disp *disp, unsigned long *pmask) +{ + struct nvkm_device *device = disp->engine.subdev.device; + *pmask = (nvkm_rd32(device, 0x610184) & 0x0f000000) >> 24; + return 4; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c index 700fc754f28a4..e6e6dfbb1283d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c @@ -152,15 +152,6 @@ gf119_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state) state->head = ctrl & 0x0000000f; } -int -gf119_sor_new_(const struct nvkm_ior_func *func, struct nvkm_disp *disp, int id) -{ - struct nvkm_device *device = disp->engine.subdev.device; - if (!(nvkm_rd32(device, 0x612004) & (0x00000100 << id))) - return 0; - return nvkm_ior_new_(func, disp, SOR, id); -} - static const struct nvkm_ior_func gf119_sor = { .state = gf119_sor_state, @@ -189,5 +180,13 @@ gf119_sor = { int gf119_sor_new(struct nvkm_disp *disp, int id) { - return gf119_sor_new_(&gf119_sor, disp, id); + return nvkm_ior_new_(&gf119_sor, disp, SOR, id); +} + +int +gf119_sor_cnt(struct nvkm_disp *disp, unsigned long *pmask) +{ + struct nvkm_device *device = disp->engine.subdev.device; + *pmask = (nvkm_rd32(device, 0x612004) & 0x0000ff00) >> 8; + return 8; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c index a1547bdf490b8..b94090edaebff 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c @@ -49,5 +49,5 @@ gk104_sor = { int gk104_sor_new(struct nvkm_disp *disp, int id) { - return gf119_sor_new_(&gk104_sor, disp, id); + return nvkm_ior_new_(&gk104_sor, disp, SOR, id); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c index 60230957d82bd..e6965dec09c96 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c @@ -63,5 +63,5 @@ gm107_sor = { int gm107_sor_new(struct nvkm_disp *disp, int id) { - return gf119_sor_new_(&gm107_sor, disp, id); + return nvkm_ior_new_(&gm107_sor, disp, SOR, id); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c index f9b8107aa2a29..8bc019b6ffaba 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c @@ -120,5 +120,5 @@ gm200_sor = { int gm200_sor_new(struct nvkm_disp *disp, int id) { - return gf119_sor_new_(&gm200_sor, disp, id); + return nvkm_ior_new_(&gm200_sor, disp, SOR, id); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c index da228b54b43e4..54d134d4ca1d1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c @@ -65,5 +65,5 @@ gt215_sor = { int gt215_sor_new(struct nvkm_disp *disp, int id) { - return nv50_sor_new_(>215_sor, disp, id); + return nvkm_ior_new_(>215_sor, disp, SOR, id); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c index c0179ccb956d1..8a70dd25b13a9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c @@ -44,5 +44,5 @@ mcp77_sor = { int mcp77_sor_new(struct nvkm_disp *disp, int id) { - return nv50_sor_new_(&mcp77_sor, disp, id); + return nvkm_ior_new_(&mcp77_sor, disp, SOR, id); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c index 9bb01cd966971..eac9c5be9166d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c @@ -49,5 +49,5 @@ mcp89_sor = { int mcp89_sor_new(struct nvkm_disp *disp, int id) { - return nv50_sor_new_(&mcp89_sor, disp, id); + return nvkm_ior_new_(&mcp89_sor, disp, SOR, id); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c index f3ebd0c22e7d4..b4729f8798af2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c @@ -84,15 +84,6 @@ nv50_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state) state->head = ctrl & 0x00000003; } -int -nv50_sor_new_(const struct nvkm_ior_func *func, struct nvkm_disp *disp, int id) -{ - struct nvkm_device *device = disp->engine.subdev.device; - if (!(nvkm_rd32(device, 0x610184) & (0x01000000 << id))) - return 0; - return nvkm_ior_new_(func, disp, SOR, id); -} - static const struct nvkm_ior_func nv50_sor = { .state = nv50_sor_state, @@ -103,5 +94,13 @@ nv50_sor = { int nv50_sor_new(struct nvkm_disp *disp, int id) { - return nv50_sor_new_(&nv50_sor, disp, id); + return nvkm_ior_new_(&nv50_sor, disp, SOR, id); +} + +int +nv50_sor_cnt(struct nvkm_disp *disp, unsigned long *pmask) +{ + struct nvkm_device *device = disp->engine.subdev.device; + *pmask = (nvkm_rd32(device, 0x610184) & 0x03000000) >> 24; + return 2; } From f5e088d6f0b4d969b2e7d8f931af082ba2527a56 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 013/165] drm/nouveau/disp/nv50-: fetch mask of available piors during oneinit Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c | 15 ++++++++++----- drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h | 9 +++------ .../gpu/drm/nouveau/nvkm/engine/disp/piornv50.c | 11 ++++++++--- .../gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c | 2 +- 11 files changed, 29 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c index 287ac5edc88ab..1ec81f3e5d0a0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c @@ -35,7 +35,7 @@ g84_disp = { .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, .sor = { .cnt = nv50_sor_cnt, .new = g84_sor_new }, - .pior = { .nr = 3, .new = nv50_pior_new }, + .pior = { .cnt = nv50_pior_cnt, .new = nv50_pior_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c index e21f76d4e28e3..791c2cd157dcb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c @@ -35,7 +35,7 @@ g94_disp = { .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, .sor = { .cnt = g94_sor_cnt, .new = g94_sor_new }, - .pior = { .nr = 3, .new = nv50_pior_new }, + .pior = { .cnt = nv50_pior_cnt, .new = nv50_pior_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c index 2ca92a23a62a4..62e721d5963a2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c @@ -35,7 +35,7 @@ gt200_disp = { .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, .sor = { .cnt = nv50_sor_cnt, .new = g84_sor_new }, - .pior = { .nr = 3, .new = nv50_pior_new }, + .pior = { .cnt = nv50_pior_cnt, .new = nv50_pior_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c index 73b0390696600..a5b1b1416740c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c @@ -35,7 +35,7 @@ gt215_disp = { .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, .sor = { .cnt = g94_sor_cnt, .new = gt215_sor_new }, - .pior = { .nr = 3, .new = nv50_pior_new }, + .pior = { .cnt = nv50_pior_cnt, .new = nv50_pior_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h index 6432e0611deec..9d43ab23f4d0f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h @@ -157,6 +157,7 @@ int nv50_dac_new(struct nvkm_disp *, int); int gf119_dac_cnt(struct nvkm_disp *, unsigned long *); int gf119_dac_new(struct nvkm_disp *, int); +int nv50_pior_cnt(struct nvkm_disp *, unsigned long *); int nv50_pior_new(struct nvkm_disp *, int); int nv50_sor_cnt(struct nvkm_disp *, unsigned long *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c index c3f6504ea67d2..ff49040a58199 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c @@ -33,7 +33,7 @@ mcp77_disp = { .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, .sor = { .cnt = g94_sor_cnt, .new = mcp77_sor_new }, - .pior = { .nr = 3, .new = nv50_pior_new }, + .pior = { .cnt = nv50_pior_cnt, .new = nv50_pior_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c index 2d1d9218d2538..0cf968d58fca7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c @@ -33,7 +33,7 @@ mcp89_disp = { .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, .sor = { .cnt = g94_sor_cnt, .new = mcp89_sor_new }, - .pior = { .nr = 3, .new = nv50_pior_new }, + .pior = { .cnt = nv50_pior_cnt, .new = nv50_pior_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c index 1e32814488bf5..c0faa3908a006 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c @@ -87,10 +87,15 @@ nv50_disp_oneinit_(struct nvkm_disp *base) } } - for (i = 0; func->pior.new && i < func->pior.nr; i++) { - ret = func->pior.new(&disp->base, i); - if (ret) - return ret; + if (func->pior.cnt) { + disp->pior.nr = func->pior.cnt(&disp->base, &disp->pior.mask); + nvkm_debug(subdev, " PIOR(s): %d (%02lx)\n", + disp->pior.nr, disp->pior.mask); + for_each_set_bit(i, &disp->pior.mask, disp->pior.nr) { + ret = func->pior.new(&disp->base, i); + if (ret) + return ret; + } } disp->sor.nr = func->sor.cnt(&disp->base, &disp->sor.mask); @@ -647,7 +652,7 @@ nv50_disp = { .head = { .cnt = nv50_head_cnt, .new = nv50_head_new }, .dac = { .cnt = nv50_dac_cnt, .new = nv50_dac_new }, .sor = { .cnt = nv50_sor_cnt, .new = nv50_sor_new }, - .pior = { .nr = 3, .new = nv50_pior_new }, + .pior = { .cnt = nv50_pior_cnt, .new = nv50_pior_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h index ee2968b7aef16..a29bcf73ce6fc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h @@ -27,6 +27,8 @@ struct nv50_disp { } sor; struct { + unsigned long mask; + int nr; u8 type[3]; } pior; @@ -55,12 +57,7 @@ struct nv50_disp_func { struct { int (*cnt)(struct nvkm_disp *, unsigned long *mask); int (*new)(struct nvkm_disp *, int id); - } head, dac, sor; - - struct { - int nr; - int (*new)(struct nvkm_disp *, int id); - } pior; + } head, dac, sor, pior; }; void nv50_disp_intr(struct nv50_disp *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c index 99b3b9050635a..e997a207f5465 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c @@ -127,8 +127,13 @@ nv50_pior = { int nv50_pior_new(struct nvkm_disp *disp, int id) { - struct nvkm_device *device = disp->engine.subdev.device; - if (!(nvkm_rd32(device, 0x610184) & (0x10000000 << id))) - return 0; return nvkm_ior_new_(&nv50_pior, disp, PIOR, id); } + +int +nv50_pior_cnt(struct nvkm_disp *disp, unsigned long *pmask) +{ + struct nvkm_device *device = disp->engine.subdev.device; + *pmask = (nvkm_rd32(device, 0x610184) & 0x70000000) >> 28; + return 3; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c index 9d0b5b71d38af..c8379bf37a6da 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c @@ -439,7 +439,7 @@ nv50_disp_root_init(struct nv50_disp_root *root) } /* ... PIOR caps */ - for (i = 0; i < disp->func->pior.nr; i++) { + for (i = 0; i < disp->pior.nr; i++) { tmp = nvkm_rd32(device, 0x61e000 + (i * 0x800)); nvkm_wr32(device, 0x6101f0 + (i * 0x04), tmp); } From bb3b0a422074606400e6aff216300bb4f012b22a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 014/165] drm/nouveau/disp/nv50-: initialise from the engine, rather than the user object Engines are initialised on an as-needed basis, so this results in the same behaviour, whilst allowing us to simplify things a bit. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/disp/base.c | 17 +++ .../drm/nouveau/nvkm/engine/disp/channv50.h | 1 + .../drm/nouveau/nvkm/engine/disp/dmacgf119.c | 2 +- .../drm/nouveau/nvkm/engine/disp/dmacnv50.c | 12 +- .../gpu/drm/nouveau/nvkm/engine/disp/g84.c | 2 + .../gpu/drm/nouveau/nvkm/engine/disp/g94.c | 2 + .../gpu/drm/nouveau/nvkm/engine/disp/gf119.c | 82 ++++++++++++ .../gpu/drm/nouveau/nvkm/engine/disp/gk104.c | 2 + .../gpu/drm/nouveau/nvkm/engine/disp/gk110.c | 2 + .../gpu/drm/nouveau/nvkm/engine/disp/gm107.c | 2 + .../gpu/drm/nouveau/nvkm/engine/disp/gm200.c | 2 + .../gpu/drm/nouveau/nvkm/engine/disp/gp100.c | 2 + .../gpu/drm/nouveau/nvkm/engine/disp/gp102.c | 2 + .../gpu/drm/nouveau/nvkm/engine/disp/gt200.c | 2 + .../gpu/drm/nouveau/nvkm/engine/disp/gt215.c | 2 + .../gpu/drm/nouveau/nvkm/engine/disp/mcp77.c | 2 + .../gpu/drm/nouveau/nvkm/engine/disp/mcp89.c | 2 + .../gpu/drm/nouveau/nvkm/engine/disp/nv50.c | 107 +++++++++++++++- .../gpu/drm/nouveau/nvkm/engine/disp/nv50.h | 9 ++ .../gpu/drm/nouveau/nvkm/engine/disp/priv.h | 2 + .../drm/nouveau/nvkm/engine/disp/rootg84.c | 2 - .../drm/nouveau/nvkm/engine/disp/rootg94.c | 2 - .../drm/nouveau/nvkm/engine/disp/rootgf119.c | 84 ------------ .../drm/nouveau/nvkm/engine/disp/rootgk104.c | 2 - .../drm/nouveau/nvkm/engine/disp/rootgk110.c | 2 - .../drm/nouveau/nvkm/engine/disp/rootgm107.c | 2 - .../drm/nouveau/nvkm/engine/disp/rootgm200.c | 2 - .../drm/nouveau/nvkm/engine/disp/rootgp100.c | 2 - .../drm/nouveau/nvkm/engine/disp/rootgp102.c | 2 - .../drm/nouveau/nvkm/engine/disp/rootgt200.c | 2 - .../drm/nouveau/nvkm/engine/disp/rootgt215.c | 2 - .../drm/nouveau/nvkm/engine/disp/rootnv50.c | 120 ------------------ .../drm/nouveau/nvkm/engine/disp/rootnv50.h | 10 -- 33 files changed, 247 insertions(+), 243 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c index 5b9d9c632aeb1..32fa94a9773f5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c @@ -220,6 +220,9 @@ nvkm_disp_fini(struct nvkm_engine *engine, bool suspend) struct nvkm_conn *conn; struct nvkm_outp *outp; + if (disp->func->fini) + disp->func->fini(disp); + list_for_each_entry(outp, &disp->outp, head) { nvkm_outp_fini(outp); } @@ -237,6 +240,7 @@ nvkm_disp_init(struct nvkm_engine *engine) struct nvkm_disp *disp = nvkm_disp(engine); struct nvkm_conn *conn; struct nvkm_outp *outp; + struct nvkm_ior *ior; list_for_each_entry(conn, &disp->conn, head) { nvkm_conn_init(conn); @@ -246,6 +250,19 @@ nvkm_disp_init(struct nvkm_engine *engine) nvkm_outp_init(outp); } + if (disp->func->init) { + int ret = disp->func->init(disp); + if (ret) + return ret; + } + + /* Set 'normal' (ie. when it's attached to a head) state for + * each output resource to 'fully enabled'. + */ + list_for_each_entry(ior, &disp->ior, head) { + ior->func->power(ior, true, true, true, true, true); + } + return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h index 40681db91a022..b5185853b7d8d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h @@ -4,6 +4,7 @@ #define nv50_disp_chan(p) container_of((p), struct nv50_disp_chan, object) #include #include "nv50.h" +struct nv50_disp_root; struct nv50_disp_chan { const struct nv50_disp_chan_func *func; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c index ce7cd74fbd5db..6680ff8bf029a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c @@ -31,7 +31,7 @@ int gf119_disp_dmac_bind(struct nv50_disp_dmac *chan, struct nvkm_object *object, u32 handle) { - return nvkm_ramht_insert(chan->base.root->ramht, object, + return nvkm_ramht_insert(chan->base.root->disp->ramht, object, chan->base.chid.user, -9, handle, chan->base.chid.user << 27 | 0x00000001); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c index 070ec5e18fdb4..c80d0479c79a3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c @@ -33,7 +33,7 @@ struct nv50_disp_dmac_object { struct nvkm_oproxy oproxy; - struct nv50_disp_root *root; + struct nv50_disp *disp; int hash; }; @@ -42,7 +42,7 @@ nv50_disp_dmac_child_del_(struct nvkm_oproxy *base) { struct nv50_disp_dmac_object *object = container_of(base, typeof(*object), oproxy); - nvkm_ramht_remove(object->root->ramht, object->hash); + nvkm_ramht_remove(object->disp->ramht, object->hash); } static const struct nvkm_oproxy_func @@ -56,8 +56,8 @@ nv50_disp_dmac_child_new_(struct nv50_disp_chan *base, void *data, u32 size, struct nvkm_object **pobject) { struct nv50_disp_dmac *chan = nv50_disp_dmac(base); - struct nv50_disp_root *root = chan->base.root; - struct nvkm_device *device = root->disp->base.engine.subdev.device; + struct nv50_disp *disp = chan->base.root->disp; + struct nvkm_device *device = disp->base.engine.subdev.device; const struct nvkm_device_oclass *sclass = oclass->priv; struct nv50_disp_dmac_object *object; int ret; @@ -65,7 +65,7 @@ nv50_disp_dmac_child_new_(struct nv50_disp_chan *base, if (!(object = kzalloc(sizeof(*object), GFP_KERNEL))) return -ENOMEM; nvkm_oproxy_ctor(&nv50_disp_dmac_child_func_, oclass, &object->oproxy); - object->root = root; + object->disp = disp; *pobject = &object->oproxy.base; ret = sclass->ctor(device, oclass, data, size, &object->oproxy.object); @@ -177,7 +177,7 @@ int nv50_disp_dmac_bind(struct nv50_disp_dmac *chan, struct nvkm_object *object, u32 handle) { - return nvkm_ramht_insert(chan->base.root->ramht, object, + return nvkm_ramht_insert(chan->base.root->disp->ramht, object, chan->base.chid.user, -10, handle, chan->base.chid.user << 28 | chan->base.chid.user); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c index 1ec81f3e5d0a0..731f188fc1ee7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c @@ -28,6 +28,8 @@ static const struct nv50_disp_func g84_disp = { + .init = nv50_disp_init, + .fini = nv50_disp_fini, .intr = nv50_disp_intr, .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c index 791c2cd157dcb..def54fe1951ec 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c @@ -28,6 +28,8 @@ static const struct nv50_disp_func g94_disp = { + .init = nv50_disp_init, + .fini = nv50_disp_fini, .intr = nv50_disp_intr, .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c index 0139d143c733b..382e6a6a6ff2c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c @@ -26,6 +26,9 @@ #include "ior.h" #include "rootnv50.h" +#include +#include + void gf119_disp_super(struct work_struct *work) { @@ -164,8 +167,87 @@ gf119_disp_intr(struct nv50_disp *disp) } } +void +gf119_disp_fini(struct nv50_disp *disp) +{ + struct nvkm_device *device = disp->base.engine.subdev.device; + /* disable all interrupts */ + nvkm_wr32(device, 0x6100b0, 0x00000000); +} + +int +gf119_disp_init(struct nv50_disp *disp) +{ + struct nvkm_device *device = disp->base.engine.subdev.device; + struct nvkm_head *head; + u32 tmp; + int i; + + /* The below segments of code copying values from one register to + * another appear to inform EVO of the display capabilities or + * something similar. + */ + + /* ... CRTC caps */ + list_for_each_entry(head, &disp->base.head, head) { + const u32 hoff = head->id * 0x800; + tmp = nvkm_rd32(device, 0x616104 + hoff); + nvkm_wr32(device, 0x6101b4 + hoff, tmp); + tmp = nvkm_rd32(device, 0x616108 + hoff); + nvkm_wr32(device, 0x6101b8 + hoff, tmp); + tmp = nvkm_rd32(device, 0x61610c + hoff); + nvkm_wr32(device, 0x6101bc + hoff, tmp); + } + + /* ... DAC caps */ + for (i = 0; i < disp->dac.nr; i++) { + tmp = nvkm_rd32(device, 0x61a000 + (i * 0x800)); + nvkm_wr32(device, 0x6101c0 + (i * 0x800), tmp); + } + + /* ... SOR caps */ + for (i = 0; i < disp->sor.nr; i++) { + tmp = nvkm_rd32(device, 0x61c000 + (i * 0x800)); + nvkm_wr32(device, 0x6301c4 + (i * 0x800), tmp); + } + + /* steal display away from vbios, or something like that */ + if (nvkm_rd32(device, 0x6100ac) & 0x00000100) { + nvkm_wr32(device, 0x6100ac, 0x00000100); + nvkm_mask(device, 0x6194e8, 0x00000001, 0x00000000); + if (nvkm_msec(device, 2000, + if (!(nvkm_rd32(device, 0x6194e8) & 0x00000002)) + break; + ) < 0) + return -EBUSY; + } + + /* point at display engine memory area (hash table, objects) */ + nvkm_wr32(device, 0x610010, (disp->inst->addr >> 8) | 9); + + /* enable supervisor interrupts, disable everything else */ + nvkm_wr32(device, 0x610090, 0x00000000); + nvkm_wr32(device, 0x6100a0, 0x00000000); + nvkm_wr32(device, 0x6100b0, 0x00000307); + + /* disable underflow reporting, preventing an intermittent issue + * on some gk104 boards where the production vbios left this + * setting enabled by default. + * + * ftp://download.nvidia.com/open-gpu-doc/gk104-disable-underflow-reporting/1/gk104-disable-underflow-reporting.txt + */ + list_for_each_entry(head, &disp->base.head, head) { + const u32 hoff = head->id * 0x800; + nvkm_mask(device, 0x616308 + hoff, 0x00000111, 0x00000010); + } + + return 0; +} + static const struct nv50_disp_func gf119_disp = { + .init = gf119_disp_init, + .fini = gf119_disp_fini, .intr = gf119_disp_intr, .intr_error = gf119_disp_intr_error, .uevent = &gf119_disp_chan_uevent, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c index 6a59a52468c1f..4c3439b1a62da 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c @@ -28,6 +28,8 @@ static const struct nv50_disp_func gk104_disp = { + .init = gf119_disp_init, + .fini = gf119_disp_fini, .intr = gf119_disp_intr, .intr_error = gf119_disp_intr_error, .uevent = &gf119_disp_chan_uevent, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c index f3b10dc4e6735..bc6f4750c942e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c @@ -28,6 +28,8 @@ static const struct nv50_disp_func gk110_disp = { + .init = gf119_disp_init, + .fini = gf119_disp_fini, .intr = gf119_disp_intr, .intr_error = gf119_disp_intr_error, .uevent = &gf119_disp_chan_uevent, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c index 068c5951efe38..031cf6b03a766 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c @@ -28,6 +28,8 @@ static const struct nv50_disp_func gm107_disp = { + .init = gf119_disp_init, + .fini = gf119_disp_fini, .intr = gf119_disp_intr, .intr_error = gf119_disp_intr_error, .uevent = &gf119_disp_chan_uevent, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c index 1c27dbe6cceca..ec9c33a5162d7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c @@ -28,6 +28,8 @@ static const struct nv50_disp_func gm200_disp = { + .init = gf119_disp_init, + .fini = gf119_disp_fini, .intr = gf119_disp_intr, .intr_error = gf119_disp_intr_error, .uevent = &gf119_disp_chan_uevent, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c index 84933b6119f2c..fd6216684f6d2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c @@ -28,6 +28,8 @@ static const struct nv50_disp_func gp100_disp = { + .init = gf119_disp_init, + .fini = gf119_disp_fini, .intr = gf119_disp_intr, .intr_error = gf119_disp_intr_error, .uevent = &gf119_disp_chan_uevent, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c index b36d926f02642..0a2c5b5f87eb6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c @@ -54,6 +54,8 @@ gp102_disp_intr_error(struct nv50_disp *disp, int chid) static const struct nv50_disp_func gp102_disp = { + .init = gf119_disp_init, + .fini = gf119_disp_fini, .intr = gf119_disp_intr, .intr_error = gp102_disp_intr_error, .uevent = &gf119_disp_chan_uevent, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c index 62e721d5963a2..f80183701f448 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c @@ -28,6 +28,8 @@ static const struct nv50_disp_func gt200_disp = { + .init = nv50_disp_init, + .fini = nv50_disp_fini, .intr = nv50_disp_intr, .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c index a5b1b1416740c..7581efc1357e9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c @@ -28,6 +28,8 @@ static const struct nv50_disp_func gt215_disp = { + .init = nv50_disp_init, + .fini = nv50_disp_fini, .intr = nv50_disp_intr, .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c index ff49040a58199..cfdce23ab83a6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c @@ -26,6 +26,8 @@ static const struct nv50_disp_func mcp77_disp = { + .init = nv50_disp_init, + .fini = nv50_disp_fini, .intr = nv50_disp_intr, .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c index 0cf968d58fca7..85d9329cfa0e1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c @@ -26,6 +26,8 @@ static const struct nv50_disp_func mcp89_disp = { + .init = nv50_disp_init, + .fini = nv50_disp_fini, .intr = nv50_disp_intr, .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c index c0faa3908a006..1d2280ab3194e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include #include @@ -49,13 +49,32 @@ nv50_disp_intr_(struct nvkm_disp *base) disp->func->intr(disp); } +static void +nv50_disp_fini_(struct nvkm_disp *base) +{ + struct nv50_disp *disp = nv50_disp(base); + disp->func->fini(disp); +} + +static int +nv50_disp_init_(struct nvkm_disp *base) +{ + struct nv50_disp *disp = nv50_disp(base); + return disp->func->init(disp); +} + static void * nv50_disp_dtor_(struct nvkm_disp *base) { struct nv50_disp *disp = nv50_disp(base); + + nvkm_ramht_del(&disp->ramht); + nvkm_gpuobj_del(&disp->inst); + nvkm_event_fini(&disp->uevent); if (disp->wq) destroy_workqueue(disp->wq); + return disp; } @@ -65,6 +84,7 @@ nv50_disp_oneinit_(struct nvkm_disp *base) struct nv50_disp *disp = nv50_disp(base); const struct nv50_disp_func *func = disp->func; struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_device *device = subdev->device; int ret, i; disp->head.nr = func->head.cnt(&disp->base, &disp->head.mask); @@ -107,13 +127,20 @@ nv50_disp_oneinit_(struct nvkm_disp *base) return ret; } - return 0; + ret = nvkm_gpuobj_new(device, 0x10000, 0x10000, false, NULL, + &disp->inst); + if (ret) + return ret; + + return nvkm_ramht_new(device, 0x1000, 0, disp->inst, &disp->ramht); } static const struct nvkm_disp_func nv50_disp_ = { .dtor = nv50_disp_dtor_, .oneinit = nv50_disp_oneinit_, + .init = nv50_disp_init_, + .fini = nv50_disp_fini_, .intr = nv50_disp_intr_, .root = nv50_disp_root_, }; @@ -643,8 +670,84 @@ nv50_disp_intr(struct nv50_disp *disp) } } +void +nv50_disp_fini(struct nv50_disp *disp) +{ + struct nvkm_device *device = disp->base.engine.subdev.device; + /* disable all interrupts */ + nvkm_wr32(device, 0x610024, 0x00000000); + nvkm_wr32(device, 0x610020, 0x00000000); +} + +int +nv50_disp_init(struct nv50_disp *disp) +{ + struct nvkm_device *device = disp->base.engine.subdev.device; + struct nvkm_head *head; + u32 tmp; + int i; + + /* The below segments of code copying values from one register to + * another appear to inform EVO of the display capabilities or + * something similar. NFI what the 0x614004 caps are for.. + */ + tmp = nvkm_rd32(device, 0x614004); + nvkm_wr32(device, 0x610184, tmp); + + /* ... CRTC caps */ + list_for_each_entry(head, &disp->base.head, head) { + tmp = nvkm_rd32(device, 0x616100 + (head->id * 0x800)); + nvkm_wr32(device, 0x610190 + (head->id * 0x10), tmp); + tmp = nvkm_rd32(device, 0x616104 + (head->id * 0x800)); + nvkm_wr32(device, 0x610194 + (head->id * 0x10), tmp); + tmp = nvkm_rd32(device, 0x616108 + (head->id * 0x800)); + nvkm_wr32(device, 0x610198 + (head->id * 0x10), tmp); + tmp = nvkm_rd32(device, 0x61610c + (head->id * 0x800)); + nvkm_wr32(device, 0x61019c + (head->id * 0x10), tmp); + } + + /* ... DAC caps */ + for (i = 0; i < disp->dac.nr; i++) { + tmp = nvkm_rd32(device, 0x61a000 + (i * 0x800)); + nvkm_wr32(device, 0x6101d0 + (i * 0x04), tmp); + } + + /* ... SOR caps */ + for (i = 0; i < disp->sor.nr; i++) { + tmp = nvkm_rd32(device, 0x61c000 + (i * 0x800)); + nvkm_wr32(device, 0x6101e0 + (i * 0x04), tmp); + } + + /* ... PIOR caps */ + for (i = 0; i < disp->pior.nr; i++) { + tmp = nvkm_rd32(device, 0x61e000 + (i * 0x800)); + nvkm_wr32(device, 0x6101f0 + (i * 0x04), tmp); + } + + /* steal display away from vbios, or something like that */ + if (nvkm_rd32(device, 0x610024) & 0x00000100) { + nvkm_wr32(device, 0x610024, 0x00000100); + nvkm_mask(device, 0x6194e8, 0x00000001, 0x00000000); + if (nvkm_msec(device, 2000, + if (!(nvkm_rd32(device, 0x6194e8) & 0x00000002)) + break; + ) < 0) + return -EBUSY; + } + + /* point at display engine memory area (hash table, objects) */ + nvkm_wr32(device, 0x610010, (disp->inst->addr >> 8) | 9); + + /* enable supervisor interrupts, disable everything else */ + nvkm_wr32(device, 0x61002c, 0x00000370); + nvkm_wr32(device, 0x610028, 0x00000000); + return 0; +} + static const struct nv50_disp_func nv50_disp = { + .init = nv50_disp_init, + .fini = nv50_disp_fini, .intr = nv50_disp_intr, .uevent = &nv50_disp_chan_uevent, .super = nv50_disp_super, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h index a29bcf73ce6fc..bb622d0f6d639 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h @@ -32,6 +32,9 @@ struct nv50_disp { u8 type[3]; } pior; + struct nvkm_gpuobj *inst; + struct nvkm_ramht *ramht; + struct nv50_disp_chan *chan[21]; }; @@ -46,6 +49,8 @@ int nv50_disp_new_(const struct nv50_disp_func *, struct nvkm_device *, int index, struct nvkm_disp **); struct nv50_disp_func { + int (*init)(struct nv50_disp *); + void (*fini)(struct nv50_disp *); void (*intr)(struct nv50_disp *); void (*intr_error)(struct nv50_disp *, int chid); @@ -60,9 +65,13 @@ struct nv50_disp_func { } head, dac, sor, pior; }; +int nv50_disp_init(struct nv50_disp *); +void nv50_disp_fini(struct nv50_disp *); void nv50_disp_intr(struct nv50_disp *); void nv50_disp_super(struct work_struct *); +int gf119_disp_init(struct nv50_disp *); +void gf119_disp_fini(struct nv50_disp *); void gf119_disp_intr(struct nv50_disp *); void gf119_disp_super(struct work_struct *); void gf119_disp_intr_error(struct nv50_disp *, int); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h index c614351f50127..ef66c5f38ad51 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h @@ -13,6 +13,8 @@ void nvkm_disp_vblank(struct nvkm_disp *, int head); struct nvkm_disp_func { void *(*dtor)(struct nvkm_disp *); int (*oneinit)(struct nvkm_disp *); + int (*init)(struct nvkm_disp *); + void (*fini)(struct nvkm_disp *); void (*intr)(struct nvkm_disp *); const struct nvkm_disp_oclass *(*root)(struct nvkm_disp *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c index 721e4f74d1fce..36ac0d4237c7a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c @@ -28,8 +28,6 @@ static const struct nv50_disp_root_func g84_disp_root = { - .init = nv50_disp_root_init, - .fini = nv50_disp_root_fini, .dmac = { &g84_disp_core_oclass, &g84_disp_base_oclass, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c index 9493f6edf62be..18b87b3df862f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c @@ -28,8 +28,6 @@ static const struct nv50_disp_root_func g94_disp_root = { - .init = nv50_disp_root_init, - .fini = nv50_disp_root_fini, .dmac = { &g94_disp_core_oclass, >200_disp_base_oclass, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c index 4ba2d80db52ba..7c5701f0b496b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c @@ -22,96 +22,12 @@ * Authors: Ben Skeggs */ #include "rootnv50.h" -#include "head.h" #include "dmacnv50.h" -#include -#include - #include -void -gf119_disp_root_fini(struct nv50_disp_root *root) -{ - struct nvkm_device *device = root->disp->base.engine.subdev.device; - /* disable all interrupts */ - nvkm_wr32(device, 0x6100b0, 0x00000000); -} - -int -gf119_disp_root_init(struct nv50_disp_root *root) -{ - struct nv50_disp *disp = root->disp; - struct nvkm_head *head; - struct nvkm_device *device = disp->base.engine.subdev.device; - u32 tmp; - int i; - - /* The below segments of code copying values from one register to - * another appear to inform EVO of the display capabilities or - * something similar. - */ - - /* ... CRTC caps */ - list_for_each_entry(head, &disp->base.head, head) { - const u32 hoff = head->id * 0x800; - tmp = nvkm_rd32(device, 0x616104 + hoff); - nvkm_wr32(device, 0x6101b4 + hoff, tmp); - tmp = nvkm_rd32(device, 0x616108 + hoff); - nvkm_wr32(device, 0x6101b8 + hoff, tmp); - tmp = nvkm_rd32(device, 0x61610c + hoff); - nvkm_wr32(device, 0x6101bc + hoff, tmp); - } - - /* ... DAC caps */ - for (i = 0; i < disp->dac.nr; i++) { - tmp = nvkm_rd32(device, 0x61a000 + (i * 0x800)); - nvkm_wr32(device, 0x6101c0 + (i * 0x800), tmp); - } - - /* ... SOR caps */ - for (i = 0; i < disp->sor.nr; i++) { - tmp = nvkm_rd32(device, 0x61c000 + (i * 0x800)); - nvkm_wr32(device, 0x6301c4 + (i * 0x800), tmp); - } - - /* steal display away from vbios, or something like that */ - if (nvkm_rd32(device, 0x6100ac) & 0x00000100) { - nvkm_wr32(device, 0x6100ac, 0x00000100); - nvkm_mask(device, 0x6194e8, 0x00000001, 0x00000000); - if (nvkm_msec(device, 2000, - if (!(nvkm_rd32(device, 0x6194e8) & 0x00000002)) - break; - ) < 0) - return -EBUSY; - } - - /* point at display engine memory area (hash table, objects) */ - nvkm_wr32(device, 0x610010, (root->instmem->addr >> 8) | 9); - - /* enable supervisor interrupts, disable everything else */ - nvkm_wr32(device, 0x610090, 0x00000000); - nvkm_wr32(device, 0x6100a0, 0x00000000); - nvkm_wr32(device, 0x6100b0, 0x00000307); - - /* disable underflow reporting, preventing an intermittent issue - * on some gk104 boards where the production vbios left this - * setting enabled by default. - * - * ftp://download.nvidia.com/open-gpu-doc/gk104-disable-underflow-reporting/1/gk104-disable-underflow-reporting.txt - */ - list_for_each_entry(head, &disp->base.head, head) { - const u32 hoff = head->id * 0x800; - nvkm_mask(device, 0x616308 + hoff, 0x00000111, 0x00000010); - } - - return 0; -} - static const struct nv50_disp_root_func gf119_disp_root = { - .init = gf119_disp_root_init, - .fini = gf119_disp_root_fini, .dmac = { &gf119_disp_core_oclass, &gf119_disp_base_oclass, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c index 0bfdb1d1c6ab4..c0946a602b719 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c @@ -28,8 +28,6 @@ static const struct nv50_disp_root_func gk104_disp_root = { - .init = gf119_disp_root_init, - .fini = gf119_disp_root_fini, .dmac = { &gk104_disp_core_oclass, &gk104_disp_base_oclass, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c index 1e8dbed8a67c2..2ebc16687b507 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c @@ -28,8 +28,6 @@ static const struct nv50_disp_root_func gk110_disp_root = { - .init = gf119_disp_root_init, - .fini = gf119_disp_root_fini, .dmac = { &gk110_disp_core_oclass, &gk110_disp_base_oclass, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c index 44c55be69e996..5a62c9e1a2cf0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c @@ -28,8 +28,6 @@ static const struct nv50_disp_root_func gm107_disp_root = { - .init = gf119_disp_root_init, - .fini = gf119_disp_root_fini, .dmac = { &gm107_disp_core_oclass, &gk110_disp_base_oclass, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c index 38f5ee1dfc581..2634e06bf6663 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c @@ -28,8 +28,6 @@ static const struct nv50_disp_root_func gm200_disp_root = { - .init = gf119_disp_root_init, - .fini = gf119_disp_root_fini, .dmac = { &gm200_disp_core_oclass, &gk110_disp_base_oclass, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c index ac8fdd728ec68..784723597c7eb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c @@ -28,8 +28,6 @@ static const struct nv50_disp_root_func gp100_disp_root = { - .init = gf119_disp_root_init, - .fini = gf119_disp_root_fini, .dmac = { &gp100_disp_core_oclass, &gk110_disp_base_oclass, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c index 37122ca579ad6..2fdfa8df03782 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c @@ -28,8 +28,6 @@ static const struct nv50_disp_root_func gp102_disp_root = { - .init = gf119_disp_root_init, - .fini = gf119_disp_root_fini, .dmac = { &gp102_disp_core_oclass, &gp102_disp_base_oclass, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c index 124a0c24f92cf..facad2794eb69 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c @@ -28,8 +28,6 @@ static const struct nv50_disp_root_func gt200_disp_root = { - .init = nv50_disp_root_init, - .fini = nv50_disp_root_fini, .dmac = { >200_disp_core_oclass, >200_disp_base_oclass, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c index dff52f30668bd..3e93db58263f3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c @@ -28,8 +28,6 @@ static const struct nv50_disp_root_func gt215_disp_root = { - .init = nv50_disp_root_init, - .fini = nv50_disp_root_fini, .dmac = { >215_disp_core_oclass, >215_disp_base_oclass, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c index c8379bf37a6da..072c8c0e70960 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c @@ -28,8 +28,6 @@ #include "ior.h" #include -#include -#include #include #include @@ -315,49 +313,16 @@ nv50_disp_root_child_get_(struct nvkm_object *object, int index, return -EINVAL; } -static int -nv50_disp_root_fini_(struct nvkm_object *object, bool suspend) -{ - struct nv50_disp_root *root = nv50_disp_root(object); - root->func->fini(root); - return 0; -} - -static int -nv50_disp_root_init_(struct nvkm_object *object) -{ - struct nv50_disp_root *root = nv50_disp_root(object); - struct nvkm_ior *ior; - int ret; - - ret = root->func->init(root); - if (ret) - return ret; - - /* Set 'normal' (ie. when it's attached to a head) state for - * each output resource to 'fully enabled'. - */ - list_for_each_entry(ior, &root->disp->base.ior, head) { - ior->func->power(ior, true, true, true, true, true); - } - - return 0; -} - static void * nv50_disp_root_dtor_(struct nvkm_object *object) { struct nv50_disp_root *root = nv50_disp_root(object); - nvkm_ramht_del(&root->ramht); - nvkm_gpuobj_del(&root->instmem); return root; } static const struct nvkm_object_func nv50_disp_root_ = { .dtor = nv50_disp_root_dtor_, - .init = nv50_disp_root_init_, - .fini = nv50_disp_root_fini_, .mthd = nv50_disp_root_mthd_, .ntfy = nvkm_disp_ntfy, .sclass = nv50_disp_root_child_get_, @@ -370,8 +335,6 @@ nv50_disp_root_new_(const struct nv50_disp_root_func *func, { struct nv50_disp *disp = nv50_disp(base); struct nv50_disp_root *root; - struct nvkm_device *device = disp->base.engine.subdev.device; - int ret; if (!(root = kzalloc(sizeof(*root), GFP_KERNEL))) return -ENOMEM; @@ -380,94 +343,11 @@ nv50_disp_root_new_(const struct nv50_disp_root_func *func, nvkm_object_ctor(&nv50_disp_root_, oclass, &root->object); root->func = func; root->disp = disp; - - ret = nvkm_gpuobj_new(disp->base.engine.subdev.device, 0x10000, 0x10000, - false, NULL, &root->instmem); - if (ret) - return ret; - - return nvkm_ramht_new(device, 0x1000, 0, root->instmem, &root->ramht); -} - -void -nv50_disp_root_fini(struct nv50_disp_root *root) -{ - struct nvkm_device *device = root->disp->base.engine.subdev.device; - /* disable all interrupts */ - nvkm_wr32(device, 0x610024, 0x00000000); - nvkm_wr32(device, 0x610020, 0x00000000); -} - -int -nv50_disp_root_init(struct nv50_disp_root *root) -{ - struct nv50_disp *disp = root->disp; - struct nvkm_head *head; - struct nvkm_device *device = disp->base.engine.subdev.device; - u32 tmp; - int i; - - /* The below segments of code copying values from one register to - * another appear to inform EVO of the display capabilities or - * something similar. NFI what the 0x614004 caps are for.. - */ - tmp = nvkm_rd32(device, 0x614004); - nvkm_wr32(device, 0x610184, tmp); - - /* ... CRTC caps */ - list_for_each_entry(head, &disp->base.head, head) { - tmp = nvkm_rd32(device, 0x616100 + (head->id * 0x800)); - nvkm_wr32(device, 0x610190 + (head->id * 0x10), tmp); - tmp = nvkm_rd32(device, 0x616104 + (head->id * 0x800)); - nvkm_wr32(device, 0x610194 + (head->id * 0x10), tmp); - tmp = nvkm_rd32(device, 0x616108 + (head->id * 0x800)); - nvkm_wr32(device, 0x610198 + (head->id * 0x10), tmp); - tmp = nvkm_rd32(device, 0x61610c + (head->id * 0x800)); - nvkm_wr32(device, 0x61019c + (head->id * 0x10), tmp); - } - - /* ... DAC caps */ - for (i = 0; i < disp->dac.nr; i++) { - tmp = nvkm_rd32(device, 0x61a000 + (i * 0x800)); - nvkm_wr32(device, 0x6101d0 + (i * 0x04), tmp); - } - - /* ... SOR caps */ - for (i = 0; i < disp->sor.nr; i++) { - tmp = nvkm_rd32(device, 0x61c000 + (i * 0x800)); - nvkm_wr32(device, 0x6101e0 + (i * 0x04), tmp); - } - - /* ... PIOR caps */ - for (i = 0; i < disp->pior.nr; i++) { - tmp = nvkm_rd32(device, 0x61e000 + (i * 0x800)); - nvkm_wr32(device, 0x6101f0 + (i * 0x04), tmp); - } - - /* steal display away from vbios, or something like that */ - if (nvkm_rd32(device, 0x610024) & 0x00000100) { - nvkm_wr32(device, 0x610024, 0x00000100); - nvkm_mask(device, 0x6194e8, 0x00000001, 0x00000000); - if (nvkm_msec(device, 2000, - if (!(nvkm_rd32(device, 0x6194e8) & 0x00000002)) - break; - ) < 0) - return -EBUSY; - } - - /* point at display engine memory area (hash table, objects) */ - nvkm_wr32(device, 0x610010, (root->instmem->addr >> 8) | 9); - - /* enable supervisor interrupts, disable everything else */ - nvkm_wr32(device, 0x61002c, 0x00000370); - nvkm_wr32(device, 0x610028, 0x00000000); return 0; } static const struct nv50_disp_root_func nv50_disp_root = { - .init = nv50_disp_root_init, - .fini = nv50_disp_root_fini, .dmac = { &nv50_disp_core_oclass, &nv50_disp_base_oclass, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h index 4818fa69ae6cf..06b554b212bdf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h @@ -10,14 +10,9 @@ struct nv50_disp_root { const struct nv50_disp_root_func *func; struct nv50_disp *disp; struct nvkm_object object; - - struct nvkm_gpuobj *instmem; - struct nvkm_ramht *ramht; }; struct nv50_disp_root_func { - int (*init)(struct nv50_disp_root *); - void (*fini)(struct nv50_disp_root *); const struct nv50_disp_dmac_oclass *dmac[3]; const struct nv50_disp_pioc_oclass *pioc[2]; }; @@ -25,11 +20,6 @@ struct nv50_disp_root_func { int nv50_disp_root_new_(const struct nv50_disp_root_func *, struct nvkm_disp *, const struct nvkm_oclass *, void *data, u32 size, struct nvkm_object **); -int nv50_disp_root_init(struct nv50_disp_root *); -void nv50_disp_root_fini(struct nv50_disp_root *); - -int gf119_disp_root_init(struct nv50_disp_root *); -void gf119_disp_root_fini(struct nv50_disp_root *); extern const struct nvkm_disp_oclass nv50_disp_root_oclass; extern const struct nvkm_disp_oclass g84_disp_root_oclass; From abc1d4379bafc504b05039db2336b3955b17ffdb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 015/165] drm/nouveau/disp/nv50-: replace user object with engine pointer in channels More simplification. Signed-off-by: Ben Skeggs --- .../drm/nouveau/nvkm/engine/disp/basenv50.c | 2 +- .../drm/nouveau/nvkm/engine/disp/channv50.c | 22 +++++++++---------- .../drm/nouveau/nvkm/engine/disp/channv50.h | 6 ++--- .../drm/nouveau/nvkm/engine/disp/coregf119.c | 4 ++-- .../drm/nouveau/nvkm/engine/disp/coregp102.c | 2 +- .../drm/nouveau/nvkm/engine/disp/corenv50.c | 6 ++--- .../drm/nouveau/nvkm/engine/disp/cursnv50.c | 2 +- .../drm/nouveau/nvkm/engine/disp/dmacgf119.c | 6 ++--- .../drm/nouveau/nvkm/engine/disp/dmacgp102.c | 2 +- .../drm/nouveau/nvkm/engine/disp/dmacnv50.c | 14 ++++++------ .../drm/nouveau/nvkm/engine/disp/dmacnv50.h | 2 +- .../drm/nouveau/nvkm/engine/disp/oimmnv50.c | 2 +- .../drm/nouveau/nvkm/engine/disp/ovlynv50.c | 2 +- .../drm/nouveau/nvkm/engine/disp/piocgf119.c | 4 ++-- .../drm/nouveau/nvkm/engine/disp/piocnv50.c | 4 ++-- 15 files changed, 39 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basenv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basenv50.c index f1d6b820d4824..418741a61f115 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basenv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basenv50.c @@ -58,7 +58,7 @@ nv50_disp_base_new(const struct nv50_disp_dmac_func *func, } else return ret; - return nv50_disp_dmac_new_(func, mthd, root, chid + head, + return nv50_disp_dmac_new_(func, mthd, disp, chid + head, head, push, oclass, pobject); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c index 723dcbde2ac2f..96b732d4b9abd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c @@ -65,7 +65,7 @@ nv50_disp_mthd_list(struct nv50_disp *disp, int debug, u32 base, int c, void nv50_disp_chan_mthd(struct nv50_disp_chan *chan, int debug) { - struct nv50_disp *disp = chan->root->disp; + struct nv50_disp *disp = chan->disp; struct nvkm_subdev *subdev = &disp->base.engine.subdev; const struct nv50_disp_chan_mthd *mthd = chan->mthd; const struct nv50_disp_mthd_list *list; @@ -158,7 +158,7 @@ static int nv50_disp_chan_rd32(struct nvkm_object *object, u64 addr, u32 *data) { struct nv50_disp_chan *chan = nv50_disp_chan(object); - struct nv50_disp *disp = chan->root->disp; + struct nv50_disp *disp = chan->disp; struct nvkm_device *device = disp->base.engine.subdev.device; *data = nvkm_rd32(device, 0x640000 + (chan->chid.user * 0x1000) + addr); return 0; @@ -168,7 +168,7 @@ static int nv50_disp_chan_wr32(struct nvkm_object *object, u64 addr, u32 data) { struct nv50_disp_chan *chan = nv50_disp_chan(object); - struct nv50_disp *disp = chan->root->disp; + struct nv50_disp *disp = chan->disp; struct nvkm_device *device = disp->base.engine.subdev.device; nvkm_wr32(device, 0x640000 + (chan->chid.user * 0x1000) + addr, data); return 0; @@ -179,7 +179,7 @@ nv50_disp_chan_ntfy(struct nvkm_object *object, u32 type, struct nvkm_event **pevent) { struct nv50_disp_chan *chan = nv50_disp_chan(object); - struct nv50_disp *disp = chan->root->disp; + struct nv50_disp *disp = chan->disp; switch (type) { case NV50_DISP_CORE_CHANNEL_DMA_V0_NTFY_UEVENT: *pevent = &disp->uevent; @@ -195,7 +195,7 @@ nv50_disp_chan_map(struct nvkm_object *object, void *argv, u32 argc, enum nvkm_object_map *type, u64 *addr, u64 *size) { struct nv50_disp_chan *chan = nv50_disp_chan(object); - struct nv50_disp *disp = chan->root->disp; + struct nv50_disp *disp = chan->disp; struct nvkm_device *device = disp->base.engine.subdev.device; *type = NVKM_OBJECT_MAP_IO; *addr = device->func->resource_addr(device, 0) + @@ -245,7 +245,7 @@ static void * nv50_disp_chan_dtor(struct nvkm_object *object) { struct nv50_disp_chan *chan = nv50_disp_chan(object); - struct nv50_disp *disp = chan->root->disp; + struct nv50_disp *disp = chan->disp; if (chan->chid.user >= 0) disp->chan[chan->chid.user] = NULL; return chan->func->dtor ? chan->func->dtor(chan) : chan; @@ -266,16 +266,14 @@ nv50_disp_chan = { int nv50_disp_chan_ctor(const struct nv50_disp_chan_func *func, const struct nv50_disp_chan_mthd *mthd, - struct nv50_disp_root *root, int ctrl, int user, int head, + struct nv50_disp *disp, int ctrl, int user, int head, const struct nvkm_oclass *oclass, struct nv50_disp_chan *chan) { - struct nv50_disp *disp = root->disp; - nvkm_object_ctor(&nv50_disp_chan, oclass, &chan->object); chan->func = func; chan->mthd = mthd; - chan->root = root; + chan->disp = disp; chan->chid.ctrl = ctrl; chan->chid.user = user; chan->head = head; @@ -291,7 +289,7 @@ nv50_disp_chan_ctor(const struct nv50_disp_chan_func *func, int nv50_disp_chan_new_(const struct nv50_disp_chan_func *func, const struct nv50_disp_chan_mthd *mthd, - struct nv50_disp_root *root, int ctrl, int user, int head, + struct nv50_disp *disp, int ctrl, int user, int head, const struct nvkm_oclass *oclass, struct nvkm_object **pobject) { @@ -301,6 +299,6 @@ nv50_disp_chan_new_(const struct nv50_disp_chan_func *func, return -ENOMEM; *pobject = &chan->object; - return nv50_disp_chan_ctor(func, mthd, root, ctrl, user, + return nv50_disp_chan_ctor(func, mthd, disp, ctrl, user, head, oclass, chan); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h index b5185853b7d8d..c9dc58ce47dd2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h @@ -9,7 +9,7 @@ struct nv50_disp_root; struct nv50_disp_chan { const struct nv50_disp_chan_func *func; const struct nv50_disp_chan_mthd *mthd; - struct nv50_disp_root *root; + struct nv50_disp *disp; struct { int ctrl; @@ -32,11 +32,11 @@ struct nv50_disp_chan_func { int nv50_disp_chan_ctor(const struct nv50_disp_chan_func *, const struct nv50_disp_chan_mthd *, - struct nv50_disp_root *, int ctrl, int user, int head, + struct nv50_disp *, int ctrl, int user, int head, const struct nvkm_oclass *, struct nv50_disp_chan *); int nv50_disp_chan_new_(const struct nv50_disp_chan_func *, const struct nv50_disp_chan_mthd *, - struct nv50_disp_root *, int ctrl, int user, int head, + struct nv50_disp *, int ctrl, int user, int head, const struct nvkm_oclass *, struct nvkm_object **); extern const struct nv50_disp_chan_func nv50_disp_pioc_func; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c index 21fbf89b6319f..200dd90e016b4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c @@ -174,7 +174,7 @@ gf119_disp_core_chan_mthd = { void gf119_disp_core_fini(struct nv50_disp_dmac *chan) { - struct nv50_disp *disp = chan->base.root->disp; + struct nv50_disp *disp = chan->base.disp; struct nvkm_subdev *subdev = &disp->base.engine.subdev; struct nvkm_device *device = subdev->device; @@ -197,7 +197,7 @@ gf119_disp_core_fini(struct nv50_disp_dmac *chan) static int gf119_disp_core_init(struct nv50_disp_dmac *chan) { - struct nv50_disp *disp = chan->base.root->disp; + struct nv50_disp *disp = chan->base.disp; struct nvkm_subdev *subdev = &disp->base.engine.subdev; struct nvkm_device *device = subdev->device; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c index b0df4b752b8c6..6ad5f2fb2ac19 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c @@ -31,7 +31,7 @@ static int gp102_disp_core_init(struct nv50_disp_dmac *chan) { - struct nv50_disp *disp = chan->base.root->disp; + struct nv50_disp *disp = chan->base.disp; struct nvkm_subdev *subdev = &disp->base.engine.subdev; struct nvkm_device *device = subdev->device; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c index b547c8b833cab..839cbc83428cf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c @@ -54,7 +54,7 @@ nv50_disp_core_new(const struct nv50_disp_dmac_func *func, } else return ret; - return nv50_disp_dmac_new_(func, mthd, root, chid, 0, + return nv50_disp_dmac_new_(func, mthd, root->disp, chid, 0, push, oclass, pobject); } @@ -168,7 +168,7 @@ nv50_disp_core_chan_mthd = { static void nv50_disp_core_fini(struct nv50_disp_dmac *chan) { - struct nv50_disp *disp = chan->base.root->disp; + struct nv50_disp *disp = chan->base.disp; struct nvkm_subdev *subdev = &disp->base.engine.subdev; struct nvkm_device *device = subdev->device; @@ -190,7 +190,7 @@ nv50_disp_core_fini(struct nv50_disp_dmac *chan) static int nv50_disp_core_init(struct nv50_disp_dmac *chan) { - struct nv50_disp *disp = chan->base.root->disp; + struct nv50_disp *disp = chan->base.disp; struct nvkm_subdev *subdev = &disp->base.engine.subdev; struct nvkm_device *device = subdev->device; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c index ab51121b7982d..1f9a6c31ab3bb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c @@ -55,7 +55,7 @@ nv50_disp_curs_new(const struct nv50_disp_chan_func *func, } else return ret; - return nv50_disp_chan_new_(func, mthd, root, ctrl + head, user + head, + return nv50_disp_chan_new_(func, mthd, disp, ctrl + head, user + head, head, oclass, pobject); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c index 6680ff8bf029a..b73bcc38a2598 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c @@ -31,7 +31,7 @@ int gf119_disp_dmac_bind(struct nv50_disp_dmac *chan, struct nvkm_object *object, u32 handle) { - return nvkm_ramht_insert(chan->base.root->disp->ramht, object, + return nvkm_ramht_insert(chan->base.disp->ramht, object, chan->base.chid.user, -9, handle, chan->base.chid.user << 27 | 0x00000001); } @@ -39,7 +39,7 @@ gf119_disp_dmac_bind(struct nv50_disp_dmac *chan, void gf119_disp_dmac_fini(struct nv50_disp_dmac *chan) { - struct nv50_disp *disp = chan->base.root->disp; + struct nv50_disp *disp = chan->base.disp; struct nvkm_subdev *subdev = &disp->base.engine.subdev; struct nvkm_device *device = subdev->device; int ctrl = chan->base.chid.ctrl; @@ -64,7 +64,7 @@ gf119_disp_dmac_fini(struct nv50_disp_dmac *chan) static int gf119_disp_dmac_init(struct nv50_disp_dmac *chan) { - struct nv50_disp *disp = chan->base.root->disp; + struct nv50_disp *disp = chan->base.disp; struct nvkm_subdev *subdev = &disp->base.engine.subdev; struct nvkm_device *device = subdev->device; int ctrl = chan->base.chid.ctrl; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c index cdead9500343e..62e9b8430791b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c @@ -29,7 +29,7 @@ static int gp102_disp_dmac_init(struct nv50_disp_dmac *chan) { - struct nv50_disp *disp = chan->base.root->disp; + struct nv50_disp *disp = chan->base.disp; struct nvkm_subdev *subdev = &disp->base.engine.subdev; struct nvkm_device *device = subdev->device; int ctrl = chan->base.chid.ctrl; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c index c80d0479c79a3..d081947d06891 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c @@ -56,7 +56,7 @@ nv50_disp_dmac_child_new_(struct nv50_disp_chan *base, void *data, u32 size, struct nvkm_object **pobject) { struct nv50_disp_dmac *chan = nv50_disp_dmac(base); - struct nv50_disp *disp = chan->base.root->disp; + struct nv50_disp *disp = chan->base.disp; struct nvkm_device *device = disp->base.engine.subdev.device; const struct nvkm_device_oclass *sclass = oclass->priv; struct nv50_disp_dmac_object *object; @@ -85,7 +85,7 @@ nv50_disp_dmac_child_get_(struct nv50_disp_chan *base, int index, struct nvkm_oclass *sclass) { struct nv50_disp_dmac *chan = nv50_disp_dmac(base); - struct nv50_disp *disp = chan->base.root->disp; + struct nv50_disp *disp = chan->base.disp; struct nvkm_device *device = disp->base.engine.subdev.device; const struct nvkm_device_oclass *oclass = NULL; @@ -133,7 +133,7 @@ nv50_disp_dmac_func_ = { int nv50_disp_dmac_new_(const struct nv50_disp_dmac_func *func, const struct nv50_disp_chan_mthd *mthd, - struct nv50_disp_root *root, int chid, int head, u64 push, + struct nv50_disp *disp, int chid, int head, u64 push, const struct nvkm_oclass *oclass, struct nvkm_object **pobject) { @@ -147,7 +147,7 @@ nv50_disp_dmac_new_(const struct nv50_disp_dmac_func *func, *pobject = &chan->base.object; chan->func = func; - ret = nv50_disp_chan_ctor(&nv50_disp_dmac_func_, mthd, root, + ret = nv50_disp_chan_ctor(&nv50_disp_dmac_func_, mthd, disp, chid, chid, head, oclass, &chan->base); if (ret) return ret; @@ -177,7 +177,7 @@ int nv50_disp_dmac_bind(struct nv50_disp_dmac *chan, struct nvkm_object *object, u32 handle) { - return nvkm_ramht_insert(chan->base.root->disp->ramht, object, + return nvkm_ramht_insert(chan->base.disp->ramht, object, chan->base.chid.user, -10, handle, chan->base.chid.user << 28 | chan->base.chid.user); @@ -186,7 +186,7 @@ nv50_disp_dmac_bind(struct nv50_disp_dmac *chan, static void nv50_disp_dmac_fini(struct nv50_disp_dmac *chan) { - struct nv50_disp *disp = chan->base.root->disp; + struct nv50_disp *disp = chan->base.disp; struct nvkm_subdev *subdev = &disp->base.engine.subdev; struct nvkm_device *device = subdev->device; int ctrl = chan->base.chid.ctrl; @@ -210,7 +210,7 @@ nv50_disp_dmac_fini(struct nv50_disp_dmac *chan) static int nv50_disp_dmac_init(struct nv50_disp_dmac *chan) { - struct nv50_disp *disp = chan->base.root->disp; + struct nv50_disp *disp = chan->base.disp; struct nvkm_subdev *subdev = &disp->base.engine.subdev; struct nvkm_device *device = subdev->device; int ctrl = chan->base.chid.ctrl; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h index f9b98211da6a6..ca323864ebfec 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h @@ -18,7 +18,7 @@ struct nv50_disp_dmac_func { int nv50_disp_dmac_new_(const struct nv50_disp_dmac_func *, const struct nv50_disp_chan_mthd *, - struct nv50_disp_root *, int chid, int head, u64 push, + struct nv50_disp *, int chid, int head, u64 push, const struct nvkm_oclass *, struct nvkm_object **); extern const struct nv50_disp_dmac_func nv50_disp_dmac_func; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c index f3b0fa2c59244..7e013cdf6f5c9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c @@ -55,7 +55,7 @@ nv50_disp_oimm_new(const struct nv50_disp_chan_func *func, } else return ret; - return nv50_disp_chan_new_(func, mthd, root, ctrl + head, user + head, + return nv50_disp_chan_new_(func, mthd, disp, ctrl + head, user + head, head, oclass, pobject); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlynv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlynv50.c index 9ebaaa6e9e336..d0e554601cc18 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlynv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlynv50.c @@ -58,7 +58,7 @@ nv50_disp_ovly_new(const struct nv50_disp_dmac_func *func, } else return ret; - return nv50_disp_dmac_new_(func, mthd, root, chid + head, + return nv50_disp_dmac_new_(func, mthd, disp, chid + head, head, push, oclass, pobject); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c index 0abaa6431943b..7b1e9bf75abde 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c @@ -29,7 +29,7 @@ static void gf119_disp_pioc_fini(struct nv50_disp_chan *chan) { - struct nv50_disp *disp = chan->root->disp; + struct nv50_disp *disp = chan->disp; struct nvkm_subdev *subdev = &disp->base.engine.subdev; struct nvkm_device *device = subdev->device; int ctrl = chan->chid.ctrl; @@ -52,7 +52,7 @@ gf119_disp_pioc_fini(struct nv50_disp_chan *chan) static int gf119_disp_pioc_init(struct nv50_disp_chan *chan) { - struct nv50_disp *disp = chan->root->disp; + struct nv50_disp *disp = chan->disp; struct nvkm_subdev *subdev = &disp->base.engine.subdev; struct nvkm_device *device = subdev->device; int ctrl = chan->chid.ctrl; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c index 0211e0e8a35f0..60c20123d84fc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c @@ -29,7 +29,7 @@ static void nv50_disp_pioc_fini(struct nv50_disp_chan *chan) { - struct nv50_disp *disp = chan->root->disp; + struct nv50_disp *disp = chan->disp; struct nvkm_subdev *subdev = &disp->base.engine.subdev; struct nvkm_device *device = subdev->device; int ctrl = chan->chid.ctrl; @@ -48,7 +48,7 @@ nv50_disp_pioc_fini(struct nv50_disp_chan *chan) static int nv50_disp_pioc_init(struct nv50_disp_chan *chan) { - struct nv50_disp *disp = chan->root->disp; + struct nv50_disp *disp = chan->disp; struct nvkm_subdev *subdev = &disp->base.engine.subdev; struct nvkm_device *device = subdev->device; int ctrl = chan->chid.ctrl; From 46f74a8ad79c4da47190df8492f0534fe8c02652 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 016/165] drm/nouveau/disp/nv50-: simplify definition of overlay channels Introduces a new method of defining channels available from the display, common to all channel types, allowing for more flexibility in available channel types/counts, and reducing the amount of boiler-plate required. This will be required to support Volta. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/disp/Kbuild | 1 - .../drm/nouveau/nvkm/engine/disp/channv50.h | 28 +++++++++++++- .../drm/nouveau/nvkm/engine/disp/dmacnv50.h | 12 ------ .../drm/nouveau/nvkm/engine/disp/ovlyg84.c | 24 +++++------- .../drm/nouveau/nvkm/engine/disp/ovlygf119.c | 22 ++++------- .../drm/nouveau/nvkm/engine/disp/ovlygk104.c | 22 ++++------- .../drm/nouveau/nvkm/engine/disp/ovlygp102.c | 20 ++++------ .../drm/nouveau/nvkm/engine/disp/ovlygt200.c | 22 ++++------- .../drm/nouveau/nvkm/engine/disp/ovlygt215.c | 38 ------------------- .../drm/nouveau/nvkm/engine/disp/ovlynv50.c | 38 ++++++++----------- .../drm/nouveau/nvkm/engine/disp/rootg84.c | 5 ++- .../drm/nouveau/nvkm/engine/disp/rootg94.c | 5 ++- .../drm/nouveau/nvkm/engine/disp/rootgf119.c | 5 ++- .../drm/nouveau/nvkm/engine/disp/rootgk104.c | 5 ++- .../drm/nouveau/nvkm/engine/disp/rootgk110.c | 5 ++- .../drm/nouveau/nvkm/engine/disp/rootgm107.c | 5 ++- .../drm/nouveau/nvkm/engine/disp/rootgm200.c | 5 ++- .../drm/nouveau/nvkm/engine/disp/rootgp100.c | 5 ++- .../drm/nouveau/nvkm/engine/disp/rootgp102.c | 5 ++- .../drm/nouveau/nvkm/engine/disp/rootgt200.c | 5 ++- .../drm/nouveau/nvkm/engine/disp/rootgt215.c | 5 ++- .../drm/nouveau/nvkm/engine/disp/rootnv50.c | 23 ++++++++++- .../drm/nouveau/nvkm/engine/disp/rootnv50.h | 7 +++- 23 files changed, 154 insertions(+), 158 deletions(-) delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygt215.c diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild index 48ce6699183e0..67861f2ac2a40 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild @@ -96,7 +96,6 @@ nvkm-y += nvkm/engine/disp/coregp102.o nvkm-y += nvkm/engine/disp/ovlynv50.o nvkm-y += nvkm/engine/disp/ovlyg84.o nvkm-y += nvkm/engine/disp/ovlygt200.o -nvkm-y += nvkm/engine/disp/ovlygt215.o nvkm-y += nvkm/engine/disp/ovlygf119.o nvkm-y += nvkm/engine/disp/ovlygk104.o nvkm-y += nvkm/engine/disp/ovlygp102.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h index c9dc58ce47dd2..b222a1daec407 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h @@ -5,6 +5,7 @@ #include #include "nv50.h" struct nv50_disp_root; +struct nv50_disp_dmac_func; struct nv50_disp_chan { const struct nv50_disp_chan_func *func; @@ -49,6 +50,30 @@ void nv50_disp_chan_uevent_send(struct nv50_disp *, int); extern const struct nvkm_event_func gf119_disp_chan_uevent; +int nv50_disp_ovly_new_(const struct nv50_disp_dmac_func *, + const struct nv50_disp_chan_mthd *, + struct nv50_disp *, int chid, + const struct nvkm_oclass *, void *argv, u32 argc, + struct nvkm_object **); + +int nv50_disp_ovly_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); + +int g84_disp_ovly_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); + +int gt200_disp_ovly_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); + +int gf119_disp_ovly_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); + +int gk104_disp_ovly_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); + +int gp102_disp_ovly_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); + struct nv50_disp_mthd_list { u32 mthd; u32 addr; @@ -81,7 +106,6 @@ extern const struct nv50_disp_chan_mthd g84_disp_core_chan_mthd; extern const struct nv50_disp_mthd_list g84_disp_core_mthd_dac; extern const struct nv50_disp_mthd_list g84_disp_core_mthd_head; extern const struct nv50_disp_chan_mthd g84_disp_base_chan_mthd; -extern const struct nv50_disp_chan_mthd g84_disp_ovly_chan_mthd; extern const struct nv50_disp_chan_mthd g94_disp_core_chan_mthd; @@ -92,7 +116,7 @@ extern const struct nv50_disp_mthd_list gf119_disp_core_mthd_pior; extern const struct nv50_disp_chan_mthd gf119_disp_base_chan_mthd; extern const struct nv50_disp_chan_mthd gk104_disp_core_chan_mthd; -extern const struct nv50_disp_chan_mthd gk104_disp_ovly_chan_mthd; +extern const struct nv50_disp_chan_mthd gk104_disp_ovly_mthd; struct nv50_disp_pioc_oclass { int (*ctor)(const struct nv50_disp_chan_func *, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h index ca323864ebfec..45caaee867443 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h @@ -55,37 +55,26 @@ int nv50_disp_base_new(const struct nv50_disp_dmac_func *, struct nv50_disp_root *, int chid, const struct nvkm_oclass *oclass, void *data, u32 size, struct nvkm_object **); -int nv50_disp_ovly_new(const struct nv50_disp_dmac_func *, - const struct nv50_disp_chan_mthd *, - struct nv50_disp_root *, int chid, - const struct nvkm_oclass *oclass, void *data, u32 size, - struct nvkm_object **); extern const struct nv50_disp_dmac_oclass nv50_disp_core_oclass; extern const struct nv50_disp_dmac_oclass nv50_disp_base_oclass; -extern const struct nv50_disp_dmac_oclass nv50_disp_ovly_oclass; extern const struct nv50_disp_dmac_oclass g84_disp_core_oclass; extern const struct nv50_disp_dmac_oclass g84_disp_base_oclass; -extern const struct nv50_disp_dmac_oclass g84_disp_ovly_oclass; extern const struct nv50_disp_dmac_oclass g94_disp_core_oclass; extern const struct nv50_disp_dmac_oclass gt200_disp_core_oclass; extern const struct nv50_disp_dmac_oclass gt200_disp_base_oclass; -extern const struct nv50_disp_dmac_oclass gt200_disp_ovly_oclass; extern const struct nv50_disp_dmac_oclass gt215_disp_core_oclass; extern const struct nv50_disp_dmac_oclass gt215_disp_base_oclass; -extern const struct nv50_disp_dmac_oclass gt215_disp_ovly_oclass; extern const struct nv50_disp_dmac_oclass gf119_disp_core_oclass; extern const struct nv50_disp_dmac_oclass gf119_disp_base_oclass; -extern const struct nv50_disp_dmac_oclass gf119_disp_ovly_oclass; extern const struct nv50_disp_dmac_oclass gk104_disp_core_oclass; extern const struct nv50_disp_dmac_oclass gk104_disp_base_oclass; -extern const struct nv50_disp_dmac_oclass gk104_disp_ovly_oclass; extern const struct nv50_disp_dmac_oclass gk110_disp_core_oclass; extern const struct nv50_disp_dmac_oclass gk110_disp_base_oclass; @@ -98,5 +87,4 @@ extern const struct nv50_disp_dmac_oclass gp100_disp_core_oclass; extern const struct nv50_disp_dmac_oclass gp102_disp_core_oclass; extern const struct nv50_disp_dmac_oclass gp102_disp_base_oclass; -extern const struct nv50_disp_dmac_oclass gp102_disp_ovly_oclass; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlyg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlyg84.c index db6234eebc61a..6b55cf483fe2a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlyg84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlyg84.c @@ -22,9 +22,6 @@ * Authors: Ben Skeggs */ #include "dmacnv50.h" -#include "rootnv50.h" - -#include static const struct nv50_disp_mthd_list g84_disp_ovly_mthd_base = { @@ -54,8 +51,8 @@ g84_disp_ovly_mthd_base = { } }; -const struct nv50_disp_chan_mthd -g84_disp_ovly_chan_mthd = { +static const struct nv50_disp_chan_mthd +g84_disp_ovly_mthd = { .name = "Overlay", .addr = 0x000540, .prev = 0x000004, @@ -65,13 +62,10 @@ g84_disp_ovly_chan_mthd = { } }; -const struct nv50_disp_dmac_oclass -g84_disp_ovly_oclass = { - .base.oclass = G82_DISP_OVERLAY_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_ovly_new, - .func = &nv50_disp_dmac_func, - .mthd = &g84_disp_ovly_chan_mthd, - .chid = 3, -}; +int +g84_disp_ovly_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_ovly_new_(&nv50_disp_dmac_func, &g84_disp_ovly_mthd, + disp, 3, oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygf119.c index 5985879abd239..30901caf75dc3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygf119.c @@ -22,9 +22,6 @@ * Authors: Ben Skeggs */ #include "dmacnv50.h" -#include "rootnv50.h" - -#include static const struct nv50_disp_mthd_list gf119_disp_ovly_mthd_base = { @@ -79,7 +76,7 @@ gf119_disp_ovly_mthd_base = { }; static const struct nv50_disp_chan_mthd -gf119_disp_ovly_chan_mthd = { +gf119_disp_ovly_mthd = { .name = "Overlay", .addr = 0x001000, .prev = -0x020000, @@ -89,13 +86,10 @@ gf119_disp_ovly_chan_mthd = { } }; -const struct nv50_disp_dmac_oclass -gf119_disp_ovly_oclass = { - .base.oclass = GF110_DISP_OVERLAY_CONTROL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_ovly_new, - .func = &gf119_disp_dmac_func, - .mthd = &gf119_disp_ovly_chan_mthd, - .chid = 5, -}; +int +gf119_disp_ovly_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_ovly_new_(&gf119_disp_dmac_func, &gf119_disp_ovly_mthd, + disp, 5, oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygk104.c index 2f0220b39f346..682c146c39d4e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygk104.c @@ -22,9 +22,6 @@ * Authors: Ben Skeggs */ #include "dmacnv50.h" -#include "rootnv50.h" - -#include static const struct nv50_disp_mthd_list gk104_disp_ovly_mthd_base = { @@ -81,7 +78,7 @@ gk104_disp_ovly_mthd_base = { }; const struct nv50_disp_chan_mthd -gk104_disp_ovly_chan_mthd = { +gk104_disp_ovly_mthd = { .name = "Overlay", .addr = 0x001000, .prev = -0x020000, @@ -91,13 +88,10 @@ gk104_disp_ovly_chan_mthd = { } }; -const struct nv50_disp_dmac_oclass -gk104_disp_ovly_oclass = { - .base.oclass = GK104_DISP_OVERLAY_CONTROL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_ovly_new, - .func = &gf119_disp_dmac_func, - .mthd = &gk104_disp_ovly_chan_mthd, - .chid = 5, -}; +int +gk104_disp_ovly_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_ovly_new_(&gf119_disp_dmac_func, &gk104_disp_ovly_mthd, + disp, 5, oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygp102.c index 589bd2f12b413..bcc5ac40f6f95 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygp102.c @@ -22,17 +22,11 @@ * Authors: Ben Skeggs */ #include "dmacnv50.h" -#include "rootnv50.h" -#include - -const struct nv50_disp_dmac_oclass -gp102_disp_ovly_oclass = { - .base.oclass = GK104_DISP_OVERLAY_CONTROL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_ovly_new, - .func = &gp102_disp_dmac_func, - .mthd = &gk104_disp_ovly_chan_mthd, - .chid = 5, -}; +int +gp102_disp_ovly_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_ovly_new_(&gp102_disp_dmac_func, &gk104_disp_ovly_mthd, + disp, 5, oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygt200.c index f858053db83da..655deb0d2fa0d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygt200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygt200.c @@ -22,9 +22,6 @@ * Authors: Ben Skeggs */ #include "dmacnv50.h" -#include "rootnv50.h" - -#include static const struct nv50_disp_mthd_list gt200_disp_ovly_mthd_base = { @@ -58,7 +55,7 @@ gt200_disp_ovly_mthd_base = { }; static const struct nv50_disp_chan_mthd -gt200_disp_ovly_chan_mthd = { +gt200_disp_ovly_mthd = { .name = "Overlay", .addr = 0x000540, .prev = 0x000004, @@ -68,13 +65,10 @@ gt200_disp_ovly_chan_mthd = { } }; -const struct nv50_disp_dmac_oclass -gt200_disp_ovly_oclass = { - .base.oclass = GT200_DISP_OVERLAY_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_ovly_new, - .func = &nv50_disp_dmac_func, - .mthd = >200_disp_ovly_chan_mthd, - .chid = 3, -}; +int +gt200_disp_ovly_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_ovly_new_(&nv50_disp_dmac_func, >200_disp_ovly_mthd, + disp, 3, oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygt215.c deleted file mode 100644 index c947e1e16a37b..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygt215.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2015 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "dmacnv50.h" -#include "rootnv50.h" - -#include - -const struct nv50_disp_dmac_oclass -gt215_disp_ovly_oclass = { - .base.oclass = GT214_DISP_OVERLAY_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_ovly_new, - .func = &nv50_disp_dmac_func, - .mthd = &g84_disp_ovly_chan_mthd, - .chid = 3, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlynv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlynv50.c index d0e554601cc18..46f5df0b3a1e2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlynv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlynv50.c @@ -23,31 +23,28 @@ */ #include "dmacnv50.h" #include "head.h" -#include "rootnv50.h" #include -#include #include #include int -nv50_disp_ovly_new(const struct nv50_disp_dmac_func *func, - const struct nv50_disp_chan_mthd *mthd, - struct nv50_disp_root *root, int chid, - const struct nvkm_oclass *oclass, void *data, u32 size, - struct nvkm_object **pobject) +nv50_disp_ovly_new_(const struct nv50_disp_dmac_func *func, + const struct nv50_disp_chan_mthd *mthd, + struct nv50_disp *disp, int chid, + const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nvkm_object **pobject) { union { struct nv50_disp_overlay_channel_dma_v0 v0; - } *args = data; + } *args = argv; struct nvkm_object *parent = oclass->parent; - struct nv50_disp *disp = root->disp; int head, ret = -ENOSYS; u64 push; - nvif_ioctl(parent, "create disp overlay channel dma size %d\n", size); - if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { + nvif_ioctl(parent, "create disp overlay channel dma size %d\n", argc); + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { nvif_ioctl(parent, "create disp overlay channel dma vers %d " "pushbuf %016llx head %d\n", args->v0.version, args->v0.pushbuf, args->v0.head); @@ -91,7 +88,7 @@ nv50_disp_ovly_mthd_base = { }; static const struct nv50_disp_chan_mthd -nv50_disp_ovly_chan_mthd = { +nv50_disp_ovly_mthd = { .name = "Overlay", .addr = 0x000540, .prev = 0x000004, @@ -101,13 +98,10 @@ nv50_disp_ovly_chan_mthd = { } }; -const struct nv50_disp_dmac_oclass -nv50_disp_ovly_oclass = { - .base.oclass = NV50_DISP_OVERLAY_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_ovly_new, - .func = &nv50_disp_dmac_func, - .mthd = &nv50_disp_ovly_chan_mthd, - .chid = 3, -}; +int +nv50_disp_ovly_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_ovly_new_(&nv50_disp_dmac_func, &nv50_disp_ovly_mthd, + disp, 3, oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c index 36ac0d4237c7a..ebb0803fd1b61 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c @@ -31,12 +31,15 @@ g84_disp_root = { .dmac = { &g84_disp_core_oclass, &g84_disp_base_oclass, - &g84_disp_ovly_oclass, }, .pioc = { &g84_disp_oimm_oclass, &g84_disp_curs_oclass, }, + .user = { + {{0,0,G82_DISP_OVERLAY_CHANNEL_DMA}, g84_disp_ovly_new }, + {} + }, }; static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c index 18b87b3df862f..6949cf0d98259 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c @@ -31,12 +31,15 @@ g94_disp_root = { .dmac = { &g94_disp_core_oclass, >200_disp_base_oclass, - >200_disp_ovly_oclass, }, .pioc = { &g84_disp_oimm_oclass, &g84_disp_curs_oclass, }, + .user = { + {{0,0,GT200_DISP_OVERLAY_CHANNEL_DMA}, gt200_disp_ovly_new }, + {} + }, }; static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c index 7c5701f0b496b..acc897f943fc9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c @@ -31,12 +31,15 @@ gf119_disp_root = { .dmac = { &gf119_disp_core_oclass, &gf119_disp_base_oclass, - &gf119_disp_ovly_oclass, }, .pioc = { &gf119_disp_oimm_oclass, &gf119_disp_curs_oclass, }, + .user = { + {{0,0,GF110_DISP_OVERLAY_CONTROL_DMA}, gf119_disp_ovly_new }, + {} + }, }; static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c index c0946a602b719..2d19a0613a089 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c @@ -31,12 +31,15 @@ gk104_disp_root = { .dmac = { &gk104_disp_core_oclass, &gk104_disp_base_oclass, - &gk104_disp_ovly_oclass, }, .pioc = { &gk104_disp_oimm_oclass, &gk104_disp_curs_oclass, }, + .user = { + {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, + {} + }, }; static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c index 2ebc16687b507..d7e224962e146 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c @@ -31,12 +31,15 @@ gk110_disp_root = { .dmac = { &gk110_disp_core_oclass, &gk110_disp_base_oclass, - &gk104_disp_ovly_oclass, }, .pioc = { &gk104_disp_oimm_oclass, &gk104_disp_curs_oclass, }, + .user = { + {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, + {} + }, }; static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c index 5a62c9e1a2cf0..de87b2743b226 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c @@ -31,12 +31,15 @@ gm107_disp_root = { .dmac = { &gm107_disp_core_oclass, &gk110_disp_base_oclass, - &gk104_disp_ovly_oclass, }, .pioc = { &gk104_disp_oimm_oclass, &gk104_disp_curs_oclass, }, + .user = { + {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, + {} + }, }; static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c index 2634e06bf6663..9e97c1e6548e4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c @@ -31,12 +31,15 @@ gm200_disp_root = { .dmac = { &gm200_disp_core_oclass, &gk110_disp_base_oclass, - &gk104_disp_ovly_oclass, }, .pioc = { &gk104_disp_oimm_oclass, &gk104_disp_curs_oclass, }, + .user = { + {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, + {} + }, }; static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c index 784723597c7eb..af7031ff4085a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c @@ -31,12 +31,15 @@ gp100_disp_root = { .dmac = { &gp100_disp_core_oclass, &gk110_disp_base_oclass, - &gk104_disp_ovly_oclass, }, .pioc = { &gk104_disp_oimm_oclass, &gk104_disp_curs_oclass, }, + .user = { + {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, + {} + }, }; static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c index 2fdfa8df03782..7603a4131581f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c @@ -31,12 +31,15 @@ gp102_disp_root = { .dmac = { &gp102_disp_core_oclass, &gp102_disp_base_oclass, - &gp102_disp_ovly_oclass, }, .pioc = { &gp102_disp_oimm_oclass, &gp102_disp_curs_oclass, }, + .user = { + {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gp102_disp_ovly_new }, + {} + }, }; static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c index facad2794eb69..8ef149d954cb2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c @@ -31,12 +31,15 @@ gt200_disp_root = { .dmac = { >200_disp_core_oclass, >200_disp_base_oclass, - >200_disp_ovly_oclass, }, .pioc = { &g84_disp_oimm_oclass, &g84_disp_curs_oclass, }, + .user = { + {{0,0,GT200_DISP_OVERLAY_CHANNEL_DMA}, gt200_disp_ovly_new }, + {} + }, }; static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c index 3e93db58263f3..07c8013eddb9e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c @@ -31,12 +31,15 @@ gt215_disp_root = { .dmac = { >215_disp_core_oclass, >215_disp_base_oclass, - >215_disp_ovly_oclass, }, .pioc = { >215_disp_oimm_oclass, >215_disp_curs_oclass, }, + .user = { + {{0,0,GT214_DISP_OVERLAY_CHANNEL_DMA}, g84_disp_ovly_new }, + {} + }, }; static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c index 072c8c0e70960..f02368ffa1c93 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c @@ -288,6 +288,15 @@ nv50_disp_root_pioc_new_(const struct nvkm_oclass *oclass, sclass->chid.user, oclass, data, size, pobject); } +static int +nv50_disp_root_child_new_(const struct nvkm_oclass *oclass, + void *argv, u32 argc, struct nvkm_object **pobject) +{ + struct nv50_disp *disp = nv50_disp_root(oclass->parent)->disp; + const struct nv50_disp_user *user = oclass->priv; + return user->ctor(oclass, argv, argc, disp, pobject); +} + static int nv50_disp_root_child_get_(struct nvkm_object *object, int index, struct nvkm_oclass *sclass) @@ -310,6 +319,15 @@ nv50_disp_root_child_get_(struct nvkm_object *object, int index, return 0; } + index -= ARRAY_SIZE(root->func->pioc); + + if (root->func->user[index].ctor) { + sclass->base = root->func->user[index].base; + sclass->priv = root->func->user + index; + sclass->ctor = nv50_disp_root_child_new_; + return 0; + } + return -EINVAL; } @@ -351,12 +369,15 @@ nv50_disp_root = { .dmac = { &nv50_disp_core_oclass, &nv50_disp_base_oclass, - &nv50_disp_ovly_oclass, }, .pioc = { &nv50_disp_oimm_oclass, &nv50_disp_curs_oclass, }, + .user = { + {{0,0,NV50_DISP_OVERLAY_CHANNEL_DMA}, nv50_disp_ovly_new }, + {} + }, }; static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h index 06b554b212bdf..1c4985a059cd2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h @@ -13,8 +13,13 @@ struct nv50_disp_root { }; struct nv50_disp_root_func { - const struct nv50_disp_dmac_oclass *dmac[3]; + const struct nv50_disp_dmac_oclass *dmac[2]; const struct nv50_disp_pioc_oclass *pioc[2]; + struct nv50_disp_user { + struct nvkm_sclass base; + int (*ctor)(const struct nvkm_oclass *, void *argv, u32 argc, + struct nv50_disp *, struct nvkm_object **); + } user[]; }; int nv50_disp_root_new_(const struct nv50_disp_root_func *, struct nvkm_disp *, From c2c3a00310df71e1f92d99ec3d5818d152f12bc8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 017/165] drm/nouveau/disp/nv50-: simplify definition of overlay immediate channels Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/disp/Kbuild | 3 -- .../drm/nouveau/nvkm/engine/disp/channv50.h | 21 +++++------ .../drm/nouveau/nvkm/engine/disp/oimmg84.c | 37 ------------------- .../drm/nouveau/nvkm/engine/disp/oimmgf119.c | 19 ++++------ .../drm/nouveau/nvkm/engine/disp/oimmgk104.c | 37 ------------------- .../drm/nouveau/nvkm/engine/disp/oimmgp102.c | 19 ++++------ .../drm/nouveau/nvkm/engine/disp/oimmgt215.c | 37 ------------------- .../drm/nouveau/nvkm/engine/disp/oimmnv50.c | 36 ++++++++---------- .../drm/nouveau/nvkm/engine/disp/rootg84.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootg94.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgf119.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgk104.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgk110.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgm107.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgm200.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgp100.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgp102.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgt200.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgt215.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootnv50.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootnv50.h | 2 +- 21 files changed, 52 insertions(+), 183 deletions(-) delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmg84.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgk104.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgt215.c diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild index 67861f2ac2a40..b53a0e2cfee37 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild @@ -111,8 +111,5 @@ nvkm-y += nvkm/engine/disp/cursgk104.o nvkm-y += nvkm/engine/disp/cursgp102.o nvkm-y += nvkm/engine/disp/oimmnv50.o -nvkm-y += nvkm/engine/disp/oimmg84.o -nvkm-y += nvkm/engine/disp/oimmgt215.o nvkm-y += nvkm/engine/disp/oimmgf119.o -nvkm-y += nvkm/engine/disp/oimmgk104.o nvkm-y += nvkm/engine/disp/oimmgp102.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h index b222a1daec407..ba30766fe342f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h @@ -50,12 +50,18 @@ void nv50_disp_chan_uevent_send(struct nv50_disp *, int); extern const struct nvkm_event_func gf119_disp_chan_uevent; +int nv50_disp_oimm_new_(const struct nv50_disp_chan_func *, + struct nv50_disp *, int ctrl, int user, + const struct nvkm_oclass *, void *argv, u32 argc, + struct nvkm_object **); int nv50_disp_ovly_new_(const struct nv50_disp_dmac_func *, const struct nv50_disp_chan_mthd *, struct nv50_disp *, int chid, const struct nvkm_oclass *, void *argv, u32 argc, struct nvkm_object **); +int nv50_disp_oimm_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); int nv50_disp_ovly_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); @@ -65,12 +71,16 @@ int g84_disp_ovly_new(const struct nvkm_oclass *, void *, u32, int gt200_disp_ovly_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); +int gf119_disp_oimm_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); int gf119_disp_ovly_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); int gk104_disp_ovly_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); +int gp102_disp_oimm_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); int gp102_disp_ovly_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); @@ -133,22 +143,16 @@ struct nv50_disp_pioc_oclass { } chid; }; -extern const struct nv50_disp_pioc_oclass nv50_disp_oimm_oclass; extern const struct nv50_disp_pioc_oclass nv50_disp_curs_oclass; -extern const struct nv50_disp_pioc_oclass g84_disp_oimm_oclass; extern const struct nv50_disp_pioc_oclass g84_disp_curs_oclass; -extern const struct nv50_disp_pioc_oclass gt215_disp_oimm_oclass; extern const struct nv50_disp_pioc_oclass gt215_disp_curs_oclass; -extern const struct nv50_disp_pioc_oclass gf119_disp_oimm_oclass; extern const struct nv50_disp_pioc_oclass gf119_disp_curs_oclass; -extern const struct nv50_disp_pioc_oclass gk104_disp_oimm_oclass; extern const struct nv50_disp_pioc_oclass gk104_disp_curs_oclass; -extern const struct nv50_disp_pioc_oclass gp102_disp_oimm_oclass; extern const struct nv50_disp_pioc_oclass gp102_disp_curs_oclass; int nv50_disp_curs_new(const struct nv50_disp_chan_func *, @@ -156,9 +160,4 @@ int nv50_disp_curs_new(const struct nv50_disp_chan_func *, struct nv50_disp_root *, int ctrl, int user, const struct nvkm_oclass *, void *data, u32 size, struct nvkm_object **); -int nv50_disp_oimm_new(const struct nv50_disp_chan_func *, - const struct nv50_disp_chan_mthd *, - struct nv50_disp_root *, int ctrl, int user, - const struct nvkm_oclass *, void *data, u32 size, - struct nvkm_object **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmg84.c deleted file mode 100644 index 5ad5d0f5db05a..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmg84.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2012 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "channv50.h" -#include "rootnv50.h" - -#include - -const struct nv50_disp_pioc_oclass -g84_disp_oimm_oclass = { - .base.oclass = G82_DISP_OVERLAY, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_oimm_new, - .func = &nv50_disp_pioc_func, - .chid = { 5, 5 }, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgf119.c index 1f9fd3403f07d..1ae0bcfc89b94 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgf119.c @@ -22,16 +22,11 @@ * Authors: Ben Skeggs */ #include "channv50.h" -#include "rootnv50.h" -#include - -const struct nv50_disp_pioc_oclass -gf119_disp_oimm_oclass = { - .base.oclass = GF110_DISP_OVERLAY, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_oimm_new, - .func = &gf119_disp_pioc_func, - .chid = { 9, 9 }, -}; +int +gf119_disp_oimm_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_oimm_new_(&gf119_disp_pioc_func, disp, 9, 9, + oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgk104.c deleted file mode 100644 index 0c09fe85e952c..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgk104.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2012 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "channv50.h" -#include "rootnv50.h" - -#include - -const struct nv50_disp_pioc_oclass -gk104_disp_oimm_oclass = { - .base.oclass = GK104_DISP_OVERLAY, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_oimm_new, - .func = &gf119_disp_pioc_func, - .chid = { 9, 9 }, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgp102.c index abf82365c6716..30ffb1008505d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgp102.c @@ -22,16 +22,11 @@ * Authors: Ben Skeggs */ #include "channv50.h" -#include "rootnv50.h" -#include - -const struct nv50_disp_pioc_oclass -gp102_disp_oimm_oclass = { - .base.oclass = GK104_DISP_OVERLAY, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_oimm_new, - .func = &gf119_disp_pioc_func, - .chid = { 9, 13 }, -}; +int +gp102_disp_oimm_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_oimm_new_(&gf119_disp_pioc_func, disp, 9, 13, + oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgt215.c deleted file mode 100644 index 1281db28aebd2..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgt215.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2012 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "channv50.h" -#include "rootnv50.h" - -#include - -const struct nv50_disp_pioc_oclass -gt215_disp_oimm_oclass = { - .base.oclass = GT214_DISP_OVERLAY, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_oimm_new, - .func = &nv50_disp_pioc_func, - .chid = { 5, 5 }, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c index 7e013cdf6f5c9..0db99bfe9db9a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c @@ -23,30 +23,26 @@ */ #include "channv50.h" #include "head.h" -#include "rootnv50.h" #include -#include #include #include int -nv50_disp_oimm_new(const struct nv50_disp_chan_func *func, - const struct nv50_disp_chan_mthd *mthd, - struct nv50_disp_root *root, int ctrl, int user, - const struct nvkm_oclass *oclass, void *data, u32 size, - struct nvkm_object **pobject) +nv50_disp_oimm_new_(const struct nv50_disp_chan_func *func, + struct nv50_disp *disp, int ctrl, int user, + const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nvkm_object **pobject) { union { struct nv50_disp_overlay_v0 v0; - } *args = data; + } *args = argv; struct nvkm_object *parent = oclass->parent; - struct nv50_disp *disp = root->disp; int head, ret = -ENOSYS; - nvif_ioctl(parent, "create disp overlay size %d\n", size); - if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { + nvif_ioctl(parent, "create disp overlay size %d\n", argc); + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { nvif_ioctl(parent, "create disp overlay vers %d head %d\n", args->v0.version, args->v0.head); if (!nvkm_head_find(&disp->base, args->v0.head)) @@ -55,16 +51,14 @@ nv50_disp_oimm_new(const struct nv50_disp_chan_func *func, } else return ret; - return nv50_disp_chan_new_(func, mthd, disp, ctrl + head, user + head, + return nv50_disp_chan_new_(func, NULL, disp, ctrl + head, user + head, head, oclass, pobject); } -const struct nv50_disp_pioc_oclass -nv50_disp_oimm_oclass = { - .base.oclass = NV50_DISP_OVERLAY, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_oimm_new, - .func = &nv50_disp_pioc_func, - .chid = { 5, 5 }, -}; +int +nv50_disp_oimm_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_oimm_new_(&nv50_disp_pioc_func, disp, 5, 5, + oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c index ebb0803fd1b61..650ed0df1f3e7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c @@ -33,10 +33,10 @@ g84_disp_root = { &g84_disp_base_oclass, }, .pioc = { - &g84_disp_oimm_oclass, &g84_disp_curs_oclass, }, .user = { + {{0,0,G82_DISP_OVERLAY }, nv50_disp_oimm_new }, {{0,0,G82_DISP_OVERLAY_CHANNEL_DMA}, g84_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c index 6949cf0d98259..19d23e0e2d289 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c @@ -33,10 +33,10 @@ g94_disp_root = { >200_disp_base_oclass, }, .pioc = { - &g84_disp_oimm_oclass, &g84_disp_curs_oclass, }, .user = { + {{0,0, G82_DISP_OVERLAY }, nv50_disp_oimm_new }, {{0,0,GT200_DISP_OVERLAY_CHANNEL_DMA}, gt200_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c index acc897f943fc9..ef8be6a06b593 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c @@ -33,10 +33,10 @@ gf119_disp_root = { &gf119_disp_base_oclass, }, .pioc = { - &gf119_disp_oimm_oclass, &gf119_disp_curs_oclass, }, .user = { + {{0,0,GF110_DISP_OVERLAY }, gf119_disp_oimm_new }, {{0,0,GF110_DISP_OVERLAY_CONTROL_DMA}, gf119_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c index 2d19a0613a089..67002c02015d7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c @@ -33,10 +33,10 @@ gk104_disp_root = { &gk104_disp_base_oclass, }, .pioc = { - &gk104_disp_oimm_oclass, &gk104_disp_curs_oclass, }, .user = { + {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c index d7e224962e146..f82cf9c7bc87f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c @@ -33,10 +33,10 @@ gk110_disp_root = { &gk110_disp_base_oclass, }, .pioc = { - &gk104_disp_oimm_oclass, &gk104_disp_curs_oclass, }, .user = { + {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c index de87b2743b226..170961e61da1f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c @@ -33,10 +33,10 @@ gm107_disp_root = { &gk110_disp_base_oclass, }, .pioc = { - &gk104_disp_oimm_oclass, &gk104_disp_curs_oclass, }, .user = { + {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c index 9e97c1e6548e4..3f77682aa0175 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c @@ -33,10 +33,10 @@ gm200_disp_root = { &gk110_disp_base_oclass, }, .pioc = { - &gk104_disp_oimm_oclass, &gk104_disp_curs_oclass, }, .user = { + {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c index af7031ff4085a..c87b1d238098f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c @@ -33,10 +33,10 @@ gp100_disp_root = { &gk110_disp_base_oclass, }, .pioc = { - &gk104_disp_oimm_oclass, &gk104_disp_curs_oclass, }, .user = { + {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c index 7603a4131581f..16516a46cc916 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c @@ -33,10 +33,10 @@ gp102_disp_root = { &gp102_disp_base_oclass, }, .pioc = { - &gp102_disp_oimm_oclass, &gp102_disp_curs_oclass, }, .user = { + {{0,0,GK104_DISP_OVERLAY }, gp102_disp_oimm_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gp102_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c index 8ef149d954cb2..6d46bf6cfdb73 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c @@ -33,10 +33,10 @@ gt200_disp_root = { >200_disp_base_oclass, }, .pioc = { - &g84_disp_oimm_oclass, &g84_disp_curs_oclass, }, .user = { + {{0,0, G82_DISP_OVERLAY }, nv50_disp_oimm_new }, {{0,0,GT200_DISP_OVERLAY_CHANNEL_DMA}, gt200_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c index 07c8013eddb9e..6863c94ec22d6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c @@ -33,10 +33,10 @@ gt215_disp_root = { >215_disp_base_oclass, }, .pioc = { - >215_disp_oimm_oclass, >215_disp_curs_oclass, }, .user = { + {{0,0,GT214_DISP_OVERLAY }, nv50_disp_oimm_new }, {{0,0,GT214_DISP_OVERLAY_CHANNEL_DMA}, g84_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c index f02368ffa1c93..41219c2d487c2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c @@ -371,10 +371,10 @@ nv50_disp_root = { &nv50_disp_base_oclass, }, .pioc = { - &nv50_disp_oimm_oclass, &nv50_disp_curs_oclass, }, .user = { + {{0,0,NV50_DISP_OVERLAY }, nv50_disp_oimm_new }, {{0,0,NV50_DISP_OVERLAY_CHANNEL_DMA}, nv50_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h index 1c4985a059cd2..67f951864977d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h @@ -14,7 +14,7 @@ struct nv50_disp_root { struct nv50_disp_root_func { const struct nv50_disp_dmac_oclass *dmac[2]; - const struct nv50_disp_pioc_oclass *pioc[2]; + const struct nv50_disp_pioc_oclass *pioc[1]; struct nv50_disp_user { struct nvkm_sclass base; int (*ctor)(const struct nvkm_oclass *, void *argv, u32 argc, From 3ceeef9c03fc9ed6adbb0646b4b89096ca568670 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 018/165] drm/nouveau/disp/nv50-: simplify definition of base channels Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/disp/Kbuild | 4 -- .../drm/nouveau/nvkm/engine/disp/baseg84.c | 24 +++++------- .../drm/nouveau/nvkm/engine/disp/basegf119.c | 22 ++++------- .../drm/nouveau/nvkm/engine/disp/basegk104.c | 38 ------------------- .../drm/nouveau/nvkm/engine/disp/basegk110.c | 38 ------------------- .../drm/nouveau/nvkm/engine/disp/basegp102.c | 20 ++++------ .../drm/nouveau/nvkm/engine/disp/basegt200.c | 38 ------------------- .../drm/nouveau/nvkm/engine/disp/basegt215.c | 38 ------------------- .../drm/nouveau/nvkm/engine/disp/basenv50.c | 38 ++++++++----------- .../drm/nouveau/nvkm/engine/disp/channv50.h | 16 +++++++- .../drm/nouveau/nvkm/engine/disp/dmacnv50.h | 13 ------- .../drm/nouveau/nvkm/engine/disp/rootg84.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootg94.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgf119.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgk104.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgk110.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgm107.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgm200.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgp100.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgp102.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgt200.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgt215.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootnv50.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootnv50.h | 2 +- 24 files changed, 67 insertions(+), 248 deletions(-) delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/basegk104.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/basegk110.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/basegt200.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/basegt215.c diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild index b53a0e2cfee37..c2d56bb5a4529 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild @@ -73,11 +73,7 @@ nvkm-y += nvkm/engine/disp/dmacgp102.o nvkm-y += nvkm/engine/disp/basenv50.o nvkm-y += nvkm/engine/disp/baseg84.o -nvkm-y += nvkm/engine/disp/basegt200.o -nvkm-y += nvkm/engine/disp/basegt215.o nvkm-y += nvkm/engine/disp/basegf119.o -nvkm-y += nvkm/engine/disp/basegk104.o -nvkm-y += nvkm/engine/disp/basegk110.o nvkm-y += nvkm/engine/disp/basegp102.o nvkm-y += nvkm/engine/disp/corenv50.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/baseg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/baseg84.c index 6d17630a3dee5..03ec508d19f05 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/baseg84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/baseg84.c @@ -22,9 +22,6 @@ * Authors: Ben Skeggs */ #include "dmacnv50.h" -#include "rootnv50.h" - -#include static const struct nv50_disp_mthd_list g84_disp_base_mthd_base = { @@ -56,8 +53,8 @@ g84_disp_base_mthd_base = { } }; -const struct nv50_disp_chan_mthd -g84_disp_base_chan_mthd = { +static const struct nv50_disp_chan_mthd +g84_disp_base_mthd = { .name = "Base", .addr = 0x000540, .prev = 0x000004, @@ -68,13 +65,10 @@ g84_disp_base_chan_mthd = { } }; -const struct nv50_disp_dmac_oclass -g84_disp_base_oclass = { - .base.oclass = G82_DISP_BASE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_base_new, - .func = &nv50_disp_dmac_func, - .mthd = &g84_disp_base_chan_mthd, - .chid = 1, -}; +int +g84_disp_base_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_base_new_(&nv50_disp_dmac_func, &g84_disp_base_mthd, + disp, 1, oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegf119.c index ebcb925e9d908..4c372dc6a1286 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegf119.c @@ -22,9 +22,6 @@ * Authors: Ben Skeggs */ #include "dmacnv50.h" -#include "rootnv50.h" - -#include static const struct nv50_disp_mthd_list gf119_disp_base_mthd_base = { @@ -91,7 +88,7 @@ gf119_disp_base_mthd_image = { }; const struct nv50_disp_chan_mthd -gf119_disp_base_chan_mthd = { +gf119_disp_base_mthd = { .name = "Base", .addr = 0x001000, .prev = -0x020000, @@ -102,13 +99,10 @@ gf119_disp_base_chan_mthd = { } }; -const struct nv50_disp_dmac_oclass -gf119_disp_base_oclass = { - .base.oclass = GF110_DISP_BASE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_base_new, - .func = &gf119_disp_dmac_func, - .mthd = &gf119_disp_base_chan_mthd, - .chid = 1, -}; +int +gf119_disp_base_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_base_new_(&gf119_disp_dmac_func, &gf119_disp_base_mthd, + disp, 1, oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegk104.c deleted file mode 100644 index 780a1d9736341..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegk104.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2015 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "dmacnv50.h" -#include "rootnv50.h" - -#include - -const struct nv50_disp_dmac_oclass -gk104_disp_base_oclass = { - .base.oclass = GK104_DISP_BASE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_base_new, - .func = &gf119_disp_dmac_func, - .mthd = &gf119_disp_base_chan_mthd, - .chid = 1, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegk110.c deleted file mode 100644 index d8bdd246c8ed9..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegk110.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2015 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "dmacnv50.h" -#include "rootnv50.h" - -#include - -const struct nv50_disp_dmac_oclass -gk110_disp_base_oclass = { - .base.oclass = GK110_DISP_BASE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_base_new, - .func = &gf119_disp_dmac_func, - .mthd = &gf119_disp_base_chan_mthd, - .chid = 1, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegp102.c index 8a3cdeef8d2cd..3a25259de0574 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegp102.c @@ -22,17 +22,11 @@ * Authors: Ben Skeggs */ #include "dmacnv50.h" -#include "rootnv50.h" -#include - -const struct nv50_disp_dmac_oclass -gp102_disp_base_oclass = { - .base.oclass = GK110_DISP_BASE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_base_new, - .func = &gp102_disp_dmac_func, - .mthd = &gf119_disp_base_chan_mthd, - .chid = 1, -}; +int +gp102_disp_base_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_base_new_(&gp102_disp_dmac_func, &gf119_disp_base_mthd, + disp, 1, oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegt200.c deleted file mode 100644 index 93451e46570c6..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegt200.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2015 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "dmacnv50.h" -#include "rootnv50.h" - -#include - -const struct nv50_disp_dmac_oclass -gt200_disp_base_oclass = { - .base.oclass = GT200_DISP_BASE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_base_new, - .func = &nv50_disp_dmac_func, - .mthd = &g84_disp_base_chan_mthd, - .chid = 1, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegt215.c deleted file mode 100644 index 08e2b1fa3806a..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegt215.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2015 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "dmacnv50.h" -#include "rootnv50.h" - -#include - -const struct nv50_disp_dmac_oclass -gt215_disp_base_oclass = { - .base.oclass = GT214_DISP_BASE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_base_new, - .func = &nv50_disp_dmac_func, - .mthd = &g84_disp_base_chan_mthd, - .chid = 1, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basenv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basenv50.c index 418741a61f115..11639e2a792f4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basenv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basenv50.c @@ -23,31 +23,28 @@ */ #include "dmacnv50.h" #include "head.h" -#include "rootnv50.h" #include -#include #include #include int -nv50_disp_base_new(const struct nv50_disp_dmac_func *func, - const struct nv50_disp_chan_mthd *mthd, - struct nv50_disp_root *root, int chid, - const struct nvkm_oclass *oclass, void *data, u32 size, - struct nvkm_object **pobject) +nv50_disp_base_new_(const struct nv50_disp_dmac_func *func, + const struct nv50_disp_chan_mthd *mthd, + struct nv50_disp *disp, int chid, + const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nvkm_object **pobject) { union { struct nv50_disp_base_channel_dma_v0 v0; - } *args = data; + } *args = argv; struct nvkm_object *parent = oclass->parent; - struct nv50_disp *disp = root->disp; int head, ret = -ENOSYS; u64 push; - nvif_ioctl(parent, "create disp base channel dma size %d\n", size); - if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { + nvif_ioctl(parent, "create disp base channel dma size %d\n", argc); + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { nvif_ioctl(parent, "create disp base channel dma vers %d " "pushbuf %016llx head %d\n", args->v0.version, args->v0.pushbuf, args->v0.head); @@ -102,7 +99,7 @@ nv50_disp_base_mthd_image = { }; static const struct nv50_disp_chan_mthd -nv50_disp_base_chan_mthd = { +nv50_disp_base_mthd = { .name = "Base", .addr = 0x000540, .prev = 0x000004, @@ -113,13 +110,10 @@ nv50_disp_base_chan_mthd = { } }; -const struct nv50_disp_dmac_oclass -nv50_disp_base_oclass = { - .base.oclass = NV50_DISP_BASE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_base_new, - .func = &nv50_disp_dmac_func, - .mthd = &nv50_disp_base_chan_mthd, - .chid = 1, -}; +int +nv50_disp_base_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_base_new_(&nv50_disp_dmac_func, &nv50_disp_base_mthd, + disp, 1, oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h index ba30766fe342f..5d162775de191 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h @@ -54,6 +54,11 @@ int nv50_disp_oimm_new_(const struct nv50_disp_chan_func *, struct nv50_disp *, int ctrl, int user, const struct nvkm_oclass *, void *argv, u32 argc, struct nvkm_object **); +int nv50_disp_base_new_(const struct nv50_disp_dmac_func *, + const struct nv50_disp_chan_mthd *, + struct nv50_disp *, int chid, + const struct nvkm_oclass *, void *argv, u32 argc, + struct nvkm_object **); int nv50_disp_ovly_new_(const struct nv50_disp_dmac_func *, const struct nv50_disp_chan_mthd *, struct nv50_disp *, int chid, @@ -62,9 +67,13 @@ int nv50_disp_ovly_new_(const struct nv50_disp_dmac_func *, int nv50_disp_oimm_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); +int nv50_disp_base_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); int nv50_disp_ovly_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); +int g84_disp_base_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); int g84_disp_ovly_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); @@ -73,6 +82,8 @@ int gt200_disp_ovly_new(const struct nvkm_oclass *, void *, u32, int gf119_disp_oimm_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); +int gf119_disp_base_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); int gf119_disp_ovly_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); @@ -81,6 +92,8 @@ int gk104_disp_ovly_new(const struct nvkm_oclass *, void *, u32, int gp102_disp_oimm_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); +int gp102_disp_base_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); int gp102_disp_ovly_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); @@ -115,7 +128,6 @@ extern const struct nv50_disp_mthd_list nv50_disp_base_mthd_image; extern const struct nv50_disp_chan_mthd g84_disp_core_chan_mthd; extern const struct nv50_disp_mthd_list g84_disp_core_mthd_dac; extern const struct nv50_disp_mthd_list g84_disp_core_mthd_head; -extern const struct nv50_disp_chan_mthd g84_disp_base_chan_mthd; extern const struct nv50_disp_chan_mthd g94_disp_core_chan_mthd; @@ -123,7 +135,7 @@ extern const struct nv50_disp_mthd_list gf119_disp_core_mthd_base; extern const struct nv50_disp_mthd_list gf119_disp_core_mthd_dac; extern const struct nv50_disp_mthd_list gf119_disp_core_mthd_sor; extern const struct nv50_disp_mthd_list gf119_disp_core_mthd_pior; -extern const struct nv50_disp_chan_mthd gf119_disp_base_chan_mthd; +extern const struct nv50_disp_chan_mthd gf119_disp_base_mthd; extern const struct nv50_disp_chan_mthd gk104_disp_core_chan_mthd; extern const struct nv50_disp_chan_mthd gk104_disp_ovly_mthd; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h index 45caaee867443..ae094c7c47f5d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h @@ -50,34 +50,22 @@ int nv50_disp_core_new(const struct nv50_disp_dmac_func *, struct nv50_disp_root *, int chid, const struct nvkm_oclass *oclass, void *data, u32 size, struct nvkm_object **); -int nv50_disp_base_new(const struct nv50_disp_dmac_func *, - const struct nv50_disp_chan_mthd *, - struct nv50_disp_root *, int chid, - const struct nvkm_oclass *oclass, void *data, u32 size, - struct nvkm_object **); extern const struct nv50_disp_dmac_oclass nv50_disp_core_oclass; -extern const struct nv50_disp_dmac_oclass nv50_disp_base_oclass; extern const struct nv50_disp_dmac_oclass g84_disp_core_oclass; -extern const struct nv50_disp_dmac_oclass g84_disp_base_oclass; extern const struct nv50_disp_dmac_oclass g94_disp_core_oclass; extern const struct nv50_disp_dmac_oclass gt200_disp_core_oclass; -extern const struct nv50_disp_dmac_oclass gt200_disp_base_oclass; extern const struct nv50_disp_dmac_oclass gt215_disp_core_oclass; -extern const struct nv50_disp_dmac_oclass gt215_disp_base_oclass; extern const struct nv50_disp_dmac_oclass gf119_disp_core_oclass; -extern const struct nv50_disp_dmac_oclass gf119_disp_base_oclass; extern const struct nv50_disp_dmac_oclass gk104_disp_core_oclass; -extern const struct nv50_disp_dmac_oclass gk104_disp_base_oclass; extern const struct nv50_disp_dmac_oclass gk110_disp_core_oclass; -extern const struct nv50_disp_dmac_oclass gk110_disp_base_oclass; extern const struct nv50_disp_dmac_oclass gm107_disp_core_oclass; @@ -86,5 +74,4 @@ extern const struct nv50_disp_dmac_oclass gm200_disp_core_oclass; extern const struct nv50_disp_dmac_oclass gp100_disp_core_oclass; extern const struct nv50_disp_dmac_oclass gp102_disp_core_oclass; -extern const struct nv50_disp_dmac_oclass gp102_disp_base_oclass; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c index 650ed0df1f3e7..fa9076ba0a751 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c @@ -30,13 +30,13 @@ static const struct nv50_disp_root_func g84_disp_root = { .dmac = { &g84_disp_core_oclass, - &g84_disp_base_oclass, }, .pioc = { &g84_disp_curs_oclass, }, .user = { {{0,0,G82_DISP_OVERLAY }, nv50_disp_oimm_new }, + {{0,0,G82_DISP_BASE_CHANNEL_DMA }, g84_disp_base_new }, {{0,0,G82_DISP_OVERLAY_CHANNEL_DMA}, g84_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c index 19d23e0e2d289..6aeab0f0278b3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c @@ -30,13 +30,13 @@ static const struct nv50_disp_root_func g94_disp_root = { .dmac = { &g94_disp_core_oclass, - >200_disp_base_oclass, }, .pioc = { &g84_disp_curs_oclass, }, .user = { {{0,0, G82_DISP_OVERLAY }, nv50_disp_oimm_new }, + {{0,0,GT200_DISP_BASE_CHANNEL_DMA }, g84_disp_base_new }, {{0,0,GT200_DISP_OVERLAY_CHANNEL_DMA}, gt200_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c index ef8be6a06b593..b44b145059492 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c @@ -30,13 +30,13 @@ static const struct nv50_disp_root_func gf119_disp_root = { .dmac = { &gf119_disp_core_oclass, - &gf119_disp_base_oclass, }, .pioc = { &gf119_disp_curs_oclass, }, .user = { {{0,0,GF110_DISP_OVERLAY }, gf119_disp_oimm_new }, + {{0,0,GF110_DISP_BASE_CHANNEL_DMA }, gf119_disp_base_new }, {{0,0,GF110_DISP_OVERLAY_CONTROL_DMA}, gf119_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c index 67002c02015d7..c43eab97a3932 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c @@ -30,13 +30,13 @@ static const struct nv50_disp_root_func gk104_disp_root = { .dmac = { &gk104_disp_core_oclass, - &gk104_disp_base_oclass, }, .pioc = { &gk104_disp_curs_oclass, }, .user = { {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, + {{0,0,GK104_DISP_BASE_CHANNEL_DMA }, gf119_disp_base_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c index f82cf9c7bc87f..2d48e73597b0c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c @@ -30,13 +30,13 @@ static const struct nv50_disp_root_func gk110_disp_root = { .dmac = { &gk110_disp_core_oclass, - &gk110_disp_base_oclass, }, .pioc = { &gk104_disp_curs_oclass, }, .user = { {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, + {{0,0,GK110_DISP_BASE_CHANNEL_DMA }, gf119_disp_base_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c index 170961e61da1f..904125e8199f7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c @@ -30,13 +30,13 @@ static const struct nv50_disp_root_func gm107_disp_root = { .dmac = { &gm107_disp_core_oclass, - &gk110_disp_base_oclass, }, .pioc = { &gk104_disp_curs_oclass, }, .user = { {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, + {{0,0,GK110_DISP_BASE_CHANNEL_DMA }, gf119_disp_base_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c index 3f77682aa0175..52e9ccac93fa2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c @@ -30,13 +30,13 @@ static const struct nv50_disp_root_func gm200_disp_root = { .dmac = { &gm200_disp_core_oclass, - &gk110_disp_base_oclass, }, .pioc = { &gk104_disp_curs_oclass, }, .user = { {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, + {{0,0,GK110_DISP_BASE_CHANNEL_DMA }, gf119_disp_base_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c index c87b1d238098f..57f40d4930f73 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c @@ -30,13 +30,13 @@ static const struct nv50_disp_root_func gp100_disp_root = { .dmac = { &gp100_disp_core_oclass, - &gk110_disp_base_oclass, }, .pioc = { &gk104_disp_curs_oclass, }, .user = { {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, + {{0,0,GK110_DISP_BASE_CHANNEL_DMA }, gf119_disp_base_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c index 16516a46cc916..f66d7fced3def 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c @@ -30,13 +30,13 @@ static const struct nv50_disp_root_func gp102_disp_root = { .dmac = { &gp102_disp_core_oclass, - &gp102_disp_base_oclass, }, .pioc = { &gp102_disp_curs_oclass, }, .user = { {{0,0,GK104_DISP_OVERLAY }, gp102_disp_oimm_new }, + {{0,0,GK110_DISP_BASE_CHANNEL_DMA }, gp102_disp_base_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gp102_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c index 6d46bf6cfdb73..c28017998bc6a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c @@ -30,13 +30,13 @@ static const struct nv50_disp_root_func gt200_disp_root = { .dmac = { >200_disp_core_oclass, - >200_disp_base_oclass, }, .pioc = { &g84_disp_curs_oclass, }, .user = { {{0,0, G82_DISP_OVERLAY }, nv50_disp_oimm_new }, + {{0,0,GT200_DISP_BASE_CHANNEL_DMA }, g84_disp_base_new }, {{0,0,GT200_DISP_OVERLAY_CHANNEL_DMA}, gt200_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c index 6863c94ec22d6..b9a6a32de82f6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c @@ -30,13 +30,13 @@ static const struct nv50_disp_root_func gt215_disp_root = { .dmac = { >215_disp_core_oclass, - >215_disp_base_oclass, }, .pioc = { >215_disp_curs_oclass, }, .user = { {{0,0,GT214_DISP_OVERLAY }, nv50_disp_oimm_new }, + {{0,0,GT214_DISP_BASE_CHANNEL_DMA }, g84_disp_base_new }, {{0,0,GT214_DISP_OVERLAY_CHANNEL_DMA}, g84_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c index 41219c2d487c2..a87531d9a3b8e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c @@ -368,13 +368,13 @@ static const struct nv50_disp_root_func nv50_disp_root = { .dmac = { &nv50_disp_core_oclass, - &nv50_disp_base_oclass, }, .pioc = { &nv50_disp_curs_oclass, }, .user = { {{0,0,NV50_DISP_OVERLAY }, nv50_disp_oimm_new }, + {{0,0,NV50_DISP_BASE_CHANNEL_DMA }, nv50_disp_base_new }, {{0,0,NV50_DISP_OVERLAY_CHANNEL_DMA}, nv50_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h index 67f951864977d..371c6ee323131 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h @@ -13,7 +13,7 @@ struct nv50_disp_root { }; struct nv50_disp_root_func { - const struct nv50_disp_dmac_oclass *dmac[2]; + const struct nv50_disp_dmac_oclass *dmac[1]; const struct nv50_disp_pioc_oclass *pioc[1]; struct nv50_disp_user { struct nvkm_sclass base; From 6d41a7536f8cff35be9b3c4ccb94e55f1553a7a1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 019/165] drm/nouveau/disp/nv50-: simplify definition of cursor channels Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/disp/Kbuild | 3 -- .../drm/nouveau/nvkm/engine/disp/channv50.h | 43 +++++-------------- .../drm/nouveau/nvkm/engine/disp/cursg84.c | 37 ---------------- .../drm/nouveau/nvkm/engine/disp/cursgf119.c | 19 +++----- .../drm/nouveau/nvkm/engine/disp/cursgk104.c | 37 ---------------- .../drm/nouveau/nvkm/engine/disp/cursgp102.c | 19 +++----- .../drm/nouveau/nvkm/engine/disp/cursgt215.c | 37 ---------------- .../drm/nouveau/nvkm/engine/disp/cursnv50.c | 36 +++++++--------- .../drm/nouveau/nvkm/engine/disp/rootg84.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootg94.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootgf119.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootgk104.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootgk110.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootgm107.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootgm200.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootgp100.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootgp102.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootgt200.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootgt215.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootnv50.c | 23 +--------- .../drm/nouveau/nvkm/engine/disp/rootnv50.h | 2 - 21 files changed, 51 insertions(+), 249 deletions(-) delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/cursg84.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgk104.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgt215.c diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild index c2d56bb5a4529..ee41fb75c94d7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild @@ -100,10 +100,7 @@ nvkm-y += nvkm/engine/disp/piocnv50.o nvkm-y += nvkm/engine/disp/piocgf119.o nvkm-y += nvkm/engine/disp/cursnv50.o -nvkm-y += nvkm/engine/disp/cursg84.o -nvkm-y += nvkm/engine/disp/cursgt215.o nvkm-y += nvkm/engine/disp/cursgf119.o -nvkm-y += nvkm/engine/disp/cursgk104.o nvkm-y += nvkm/engine/disp/cursgp102.o nvkm-y += nvkm/engine/disp/oimmnv50.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h index 5d162775de191..d52420f410ed3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h @@ -50,6 +50,10 @@ void nv50_disp_chan_uevent_send(struct nv50_disp *, int); extern const struct nvkm_event_func gf119_disp_chan_uevent; +int nv50_disp_curs_new_(const struct nv50_disp_chan_func *, + struct nv50_disp *, int ctrl, int user, + const struct nvkm_oclass *, void *argv, u32 argc, + struct nvkm_object **); int nv50_disp_oimm_new_(const struct nv50_disp_chan_func *, struct nv50_disp *, int ctrl, int user, const struct nvkm_oclass *, void *argv, u32 argc, @@ -65,6 +69,8 @@ int nv50_disp_ovly_new_(const struct nv50_disp_dmac_func *, const struct nvkm_oclass *, void *argv, u32 argc, struct nvkm_object **); +int nv50_disp_curs_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); int nv50_disp_oimm_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); int nv50_disp_base_new(const struct nvkm_oclass *, void *, u32, @@ -80,6 +86,8 @@ int g84_disp_ovly_new(const struct nvkm_oclass *, void *, u32, int gt200_disp_ovly_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); +int gf119_disp_curs_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); int gf119_disp_oimm_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); int gf119_disp_base_new(const struct nvkm_oclass *, void *, u32, @@ -90,6 +98,8 @@ int gf119_disp_ovly_new(const struct nvkm_oclass *, void *, u32, int gk104_disp_ovly_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); +int gp102_disp_curs_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); int gp102_disp_oimm_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); int gp102_disp_base_new(const struct nvkm_oclass *, void *, u32, @@ -139,37 +149,4 @@ extern const struct nv50_disp_chan_mthd gf119_disp_base_mthd; extern const struct nv50_disp_chan_mthd gk104_disp_core_chan_mthd; extern const struct nv50_disp_chan_mthd gk104_disp_ovly_mthd; - -struct nv50_disp_pioc_oclass { - int (*ctor)(const struct nv50_disp_chan_func *, - const struct nv50_disp_chan_mthd *, - struct nv50_disp_root *, int ctrl, int user, - const struct nvkm_oclass *, void *data, u32 size, - struct nvkm_object **); - struct nvkm_sclass base; - const struct nv50_disp_chan_func *func; - const struct nv50_disp_chan_mthd *mthd; - struct { - int ctrl; - int user; - } chid; -}; - -extern const struct nv50_disp_pioc_oclass nv50_disp_curs_oclass; - -extern const struct nv50_disp_pioc_oclass g84_disp_curs_oclass; - -extern const struct nv50_disp_pioc_oclass gt215_disp_curs_oclass; - -extern const struct nv50_disp_pioc_oclass gf119_disp_curs_oclass; - -extern const struct nv50_disp_pioc_oclass gk104_disp_curs_oclass; - -extern const struct nv50_disp_pioc_oclass gp102_disp_curs_oclass; - -int nv50_disp_curs_new(const struct nv50_disp_chan_func *, - const struct nv50_disp_chan_mthd *, - struct nv50_disp_root *, int ctrl, int user, - const struct nvkm_oclass *, void *data, u32 size, - struct nvkm_object **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursg84.c deleted file mode 100644 index fa781b5a7e07f..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursg84.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2015 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "channv50.h" -#include "rootnv50.h" - -#include - -const struct nv50_disp_pioc_oclass -g84_disp_curs_oclass = { - .base.oclass = G82_DISP_CURSOR, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_curs_new, - .func = &nv50_disp_pioc_func, - .chid = { 7, 7 }, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgf119.c index 2be6fb052c65f..cdda3658dcb32 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgf119.c @@ -22,16 +22,11 @@ * Authors: Ben Skeggs */ #include "channv50.h" -#include "rootnv50.h" -#include - -const struct nv50_disp_pioc_oclass -gf119_disp_curs_oclass = { - .base.oclass = GF110_DISP_CURSOR, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_curs_new, - .func = &gf119_disp_pioc_func, - .chid = { 13, 13 }, -}; +int +gf119_disp_curs_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_curs_new_(&gf119_disp_pioc_func, disp, 13, 13, + oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgk104.c deleted file mode 100644 index 2a99db4bf8f8a..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgk104.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2012 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "channv50.h" -#include "rootnv50.h" - -#include - -const struct nv50_disp_pioc_oclass -gk104_disp_curs_oclass = { - .base.oclass = GK104_DISP_CURSOR, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_curs_new, - .func = &gf119_disp_pioc_func, - .chid = { 13, 13 }, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgp102.c index e958210d8105d..1a4601f975e6e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgp102.c @@ -22,16 +22,11 @@ * Authors: Ben Skeggs */ #include "channv50.h" -#include "rootnv50.h" -#include - -const struct nv50_disp_pioc_oclass -gp102_disp_curs_oclass = { - .base.oclass = GK104_DISP_CURSOR, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_curs_new, - .func = &gf119_disp_pioc_func, - .chid = { 13, 17 }, -}; +int +gp102_disp_curs_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_curs_new_(&gf119_disp_pioc_func, disp, 13, 17, + oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgt215.c deleted file mode 100644 index 00a7f35644506..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgt215.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2015 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "channv50.h" -#include "rootnv50.h" - -#include - -const struct nv50_disp_pioc_oclass -gt215_disp_curs_oclass = { - .base.oclass = GT214_DISP_CURSOR, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_curs_new, - .func = &nv50_disp_pioc_func, - .chid = { 7, 7 }, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c index 1f9a6c31ab3bb..d29758504a5fd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c @@ -23,30 +23,26 @@ */ #include "channv50.h" #include "head.h" -#include "rootnv50.h" #include -#include #include #include int -nv50_disp_curs_new(const struct nv50_disp_chan_func *func, - const struct nv50_disp_chan_mthd *mthd, - struct nv50_disp_root *root, int ctrl, int user, - const struct nvkm_oclass *oclass, void *data, u32 size, - struct nvkm_object **pobject) +nv50_disp_curs_new_(const struct nv50_disp_chan_func *func, + struct nv50_disp *disp, int ctrl, int user, + const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nvkm_object **pobject) { union { struct nv50_disp_cursor_v0 v0; - } *args = data; + } *args = argv; struct nvkm_object *parent = oclass->parent; - struct nv50_disp *disp = root->disp; int head, ret = -ENOSYS; - nvif_ioctl(parent, "create disp cursor size %d\n", size); - if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { + nvif_ioctl(parent, "create disp cursor size %d\n", argc); + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { nvif_ioctl(parent, "create disp cursor vers %d head %d\n", args->v0.version, args->v0.head); if (!nvkm_head_find(&disp->base, args->v0.head)) @@ -55,16 +51,14 @@ nv50_disp_curs_new(const struct nv50_disp_chan_func *func, } else return ret; - return nv50_disp_chan_new_(func, mthd, disp, ctrl + head, user + head, + return nv50_disp_chan_new_(func, NULL, disp, ctrl + head, user + head, head, oclass, pobject); } -const struct nv50_disp_pioc_oclass -nv50_disp_curs_oclass = { - .base.oclass = NV50_DISP_CURSOR, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_curs_new, - .func = &nv50_disp_pioc_func, - .chid = { 7, 7 }, -}; +int +nv50_disp_curs_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_curs_new_(&nv50_disp_pioc_func, disp, 7, 7, + oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c index fa9076ba0a751..0f7e662cd175e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c @@ -31,10 +31,8 @@ g84_disp_root = { .dmac = { &g84_disp_core_oclass, }, - .pioc = { - &g84_disp_curs_oclass, - }, .user = { + {{0,0,G82_DISP_CURSOR }, nv50_disp_curs_new }, {{0,0,G82_DISP_OVERLAY }, nv50_disp_oimm_new }, {{0,0,G82_DISP_BASE_CHANNEL_DMA }, g84_disp_base_new }, {{0,0,G82_DISP_OVERLAY_CHANNEL_DMA}, g84_disp_ovly_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c index 6aeab0f0278b3..20709d6e8a8b4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c @@ -31,10 +31,8 @@ g94_disp_root = { .dmac = { &g94_disp_core_oclass, }, - .pioc = { - &g84_disp_curs_oclass, - }, .user = { + {{0,0, G82_DISP_CURSOR }, nv50_disp_curs_new }, {{0,0, G82_DISP_OVERLAY }, nv50_disp_oimm_new }, {{0,0,GT200_DISP_BASE_CHANNEL_DMA }, g84_disp_base_new }, {{0,0,GT200_DISP_OVERLAY_CHANNEL_DMA}, gt200_disp_ovly_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c index b44b145059492..1161698dbb4e2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c @@ -31,10 +31,8 @@ gf119_disp_root = { .dmac = { &gf119_disp_core_oclass, }, - .pioc = { - &gf119_disp_curs_oclass, - }, .user = { + {{0,0,GF110_DISP_CURSOR }, gf119_disp_curs_new }, {{0,0,GF110_DISP_OVERLAY }, gf119_disp_oimm_new }, {{0,0,GF110_DISP_BASE_CHANNEL_DMA }, gf119_disp_base_new }, {{0,0,GF110_DISP_OVERLAY_CONTROL_DMA}, gf119_disp_ovly_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c index c43eab97a3932..15379ff5ebf46 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c @@ -31,10 +31,8 @@ gk104_disp_root = { .dmac = { &gk104_disp_core_oclass, }, - .pioc = { - &gk104_disp_curs_oclass, - }, .user = { + {{0,0,GK104_DISP_CURSOR }, gf119_disp_curs_new }, {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, {{0,0,GK104_DISP_BASE_CHANNEL_DMA }, gf119_disp_base_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c index 2d48e73597b0c..0a47674f6541c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c @@ -31,10 +31,8 @@ gk110_disp_root = { .dmac = { &gk110_disp_core_oclass, }, - .pioc = { - &gk104_disp_curs_oclass, - }, .user = { + {{0,0,GK104_DISP_CURSOR }, gf119_disp_curs_new }, {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, {{0,0,GK110_DISP_BASE_CHANNEL_DMA }, gf119_disp_base_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c index 904125e8199f7..819521e257178 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c @@ -31,10 +31,8 @@ gm107_disp_root = { .dmac = { &gm107_disp_core_oclass, }, - .pioc = { - &gk104_disp_curs_oclass, - }, .user = { + {{0,0,GK104_DISP_CURSOR }, gf119_disp_curs_new }, {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, {{0,0,GK110_DISP_BASE_CHANNEL_DMA }, gf119_disp_base_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c index 52e9ccac93fa2..0dca1772bf339 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c @@ -31,10 +31,8 @@ gm200_disp_root = { .dmac = { &gm200_disp_core_oclass, }, - .pioc = { - &gk104_disp_curs_oclass, - }, .user = { + {{0,0,GK104_DISP_CURSOR }, gf119_disp_curs_new }, {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, {{0,0,GK110_DISP_BASE_CHANNEL_DMA }, gf119_disp_base_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c index 57f40d4930f73..6fcf8583b8195 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c @@ -31,10 +31,8 @@ gp100_disp_root = { .dmac = { &gp100_disp_core_oclass, }, - .pioc = { - &gk104_disp_curs_oclass, - }, .user = { + {{0,0,GK104_DISP_CURSOR }, gf119_disp_curs_new }, {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, {{0,0,GK110_DISP_BASE_CHANNEL_DMA }, gf119_disp_base_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c index f66d7fced3def..bf5cbc32120d8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c @@ -31,10 +31,8 @@ gp102_disp_root = { .dmac = { &gp102_disp_core_oclass, }, - .pioc = { - &gp102_disp_curs_oclass, - }, .user = { + {{0,0,GK104_DISP_CURSOR }, gp102_disp_curs_new }, {{0,0,GK104_DISP_OVERLAY }, gp102_disp_oimm_new }, {{0,0,GK110_DISP_BASE_CHANNEL_DMA }, gp102_disp_base_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gp102_disp_ovly_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c index c28017998bc6a..2bd3f36475e30 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c @@ -31,10 +31,8 @@ gt200_disp_root = { .dmac = { >200_disp_core_oclass, }, - .pioc = { - &g84_disp_curs_oclass, - }, .user = { + {{0,0, G82_DISP_CURSOR }, nv50_disp_curs_new }, {{0,0, G82_DISP_OVERLAY }, nv50_disp_oimm_new }, {{0,0,GT200_DISP_BASE_CHANNEL_DMA }, g84_disp_base_new }, {{0,0,GT200_DISP_OVERLAY_CHANNEL_DMA}, gt200_disp_ovly_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c index b9a6a32de82f6..aa4c52355e884 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c @@ -31,10 +31,8 @@ gt215_disp_root = { .dmac = { >215_disp_core_oclass, }, - .pioc = { - >215_disp_curs_oclass, - }, .user = { + {{0,0,GT214_DISP_CURSOR }, nv50_disp_curs_new }, {{0,0,GT214_DISP_OVERLAY }, nv50_disp_oimm_new }, {{0,0,GT214_DISP_BASE_CHANNEL_DMA }, g84_disp_base_new }, {{0,0,GT214_DISP_OVERLAY_CHANNEL_DMA}, g84_disp_ovly_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c index a87531d9a3b8e..24e8b418ac657 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c @@ -278,16 +278,6 @@ nv50_disp_root_dmac_new_(const struct nvkm_oclass *oclass, oclass, data, size, pobject); } -static int -nv50_disp_root_pioc_new_(const struct nvkm_oclass *oclass, - void *data, u32 size, struct nvkm_object **pobject) -{ - const struct nv50_disp_pioc_oclass *sclass = oclass->priv; - struct nv50_disp_root *root = nv50_disp_root(oclass->parent); - return sclass->ctor(sclass->func, sclass->mthd, root, sclass->chid.ctrl, - sclass->chid.user, oclass, data, size, pobject); -} - static int nv50_disp_root_child_new_(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject) @@ -312,15 +302,6 @@ nv50_disp_root_child_get_(struct nvkm_object *object, int index, index -= ARRAY_SIZE(root->func->dmac); - if (index < ARRAY_SIZE(root->func->pioc)) { - sclass->base = root->func->pioc[index]->base; - sclass->priv = root->func->pioc[index]; - sclass->ctor = nv50_disp_root_pioc_new_; - return 0; - } - - index -= ARRAY_SIZE(root->func->pioc); - if (root->func->user[index].ctor) { sclass->base = root->func->user[index].base; sclass->priv = root->func->user + index; @@ -369,10 +350,8 @@ nv50_disp_root = { .dmac = { &nv50_disp_core_oclass, }, - .pioc = { - &nv50_disp_curs_oclass, - }, .user = { + {{0,0,NV50_DISP_CURSOR }, nv50_disp_curs_new }, {{0,0,NV50_DISP_OVERLAY }, nv50_disp_oimm_new }, {{0,0,NV50_DISP_BASE_CHANNEL_DMA }, nv50_disp_base_new }, {{0,0,NV50_DISP_OVERLAY_CHANNEL_DMA}, nv50_disp_ovly_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h index 371c6ee323131..484868af65977 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h @@ -3,7 +3,6 @@ #define __NV50_DISP_ROOT_H__ #define nv50_disp_root(p) container_of((p), struct nv50_disp_root, object) #include "nv50.h" -#include "channv50.h" #include "dmacnv50.h" struct nv50_disp_root { @@ -14,7 +13,6 @@ struct nv50_disp_root { struct nv50_disp_root_func { const struct nv50_disp_dmac_oclass *dmac[1]; - const struct nv50_disp_pioc_oclass *pioc[1]; struct nv50_disp_user { struct nvkm_sclass base; int (*ctor)(const struct nvkm_oclass *, void *argv, u32 argc, From 9b096283bf78f659e1286ef9b783b27ecf5a9977 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 020/165] drm/nouveau/disp/nv50-: simplify definiton of core channels Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/disp/Kbuild | 6 --- .../drm/nouveau/nvkm/engine/disp/channv50.h | 24 +++++++++-- .../drm/nouveau/nvkm/engine/disp/coreg84.c | 22 ++++------ .../drm/nouveau/nvkm/engine/disp/coreg94.c | 22 ++++------ .../drm/nouveau/nvkm/engine/disp/coregf119.c | 24 ++++------- .../drm/nouveau/nvkm/engine/disp/coregk104.c | 22 ++++------ .../drm/nouveau/nvkm/engine/disp/coregk110.c | 38 ----------------- .../drm/nouveau/nvkm/engine/disp/coregm107.c | 38 ----------------- .../drm/nouveau/nvkm/engine/disp/coregm200.c | 38 ----------------- .../drm/nouveau/nvkm/engine/disp/coregp100.c | 38 ----------------- .../drm/nouveau/nvkm/engine/disp/coregp102.c | 20 ++++----- .../drm/nouveau/nvkm/engine/disp/coregt200.c | 38 ----------------- .../drm/nouveau/nvkm/engine/disp/coregt215.c | 38 ----------------- .../drm/nouveau/nvkm/engine/disp/corenv50.c | 39 ++++++++--------- .../drm/nouveau/nvkm/engine/disp/dmacnv50.h | 42 ------------------- .../gpu/drm/nouveau/nvkm/engine/disp/nv50.c | 1 + .../drm/nouveau/nvkm/engine/disp/rootg84.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootg94.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootgf119.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootgk104.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootgk110.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootgm107.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootgm200.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootgp100.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootgp102.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootgt200.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootgt215.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootnv50.c | 23 +--------- .../drm/nouveau/nvkm/engine/disp/rootnv50.h | 2 +- 29 files changed, 91 insertions(+), 428 deletions(-) delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/coregk110.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/coregm107.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/coregm200.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp100.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/coregt200.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/coregt215.c diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild index ee41fb75c94d7..b580581ef5b83 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild @@ -79,14 +79,8 @@ nvkm-y += nvkm/engine/disp/basegp102.o nvkm-y += nvkm/engine/disp/corenv50.o nvkm-y += nvkm/engine/disp/coreg84.o nvkm-y += nvkm/engine/disp/coreg94.o -nvkm-y += nvkm/engine/disp/coregt200.o -nvkm-y += nvkm/engine/disp/coregt215.o nvkm-y += nvkm/engine/disp/coregf119.o nvkm-y += nvkm/engine/disp/coregk104.o -nvkm-y += nvkm/engine/disp/coregk110.o -nvkm-y += nvkm/engine/disp/coregm107.o -nvkm-y += nvkm/engine/disp/coregm200.o -nvkm-y += nvkm/engine/disp/coregp100.o nvkm-y += nvkm/engine/disp/coregp102.o nvkm-y += nvkm/engine/disp/ovlynv50.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h index d52420f410ed3..10ce217cc0818 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h @@ -63,6 +63,11 @@ int nv50_disp_base_new_(const struct nv50_disp_dmac_func *, struct nv50_disp *, int chid, const struct nvkm_oclass *, void *argv, u32 argc, struct nvkm_object **); +int nv50_disp_core_new_(const struct nv50_disp_dmac_func *, + const struct nv50_disp_chan_mthd *, + struct nv50_disp *, int chid, + const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nvkm_object **); int nv50_disp_ovly_new_(const struct nv50_disp_dmac_func *, const struct nv50_disp_chan_mthd *, struct nv50_disp *, int chid, @@ -75,14 +80,21 @@ int nv50_disp_oimm_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); int nv50_disp_base_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); +int nv50_disp_core_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); int nv50_disp_ovly_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); int g84_disp_base_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); +int g84_disp_core_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); int g84_disp_ovly_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); +int g94_disp_core_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); + int gt200_disp_ovly_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); @@ -92,9 +104,13 @@ int gf119_disp_oimm_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); int gf119_disp_base_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); +int gf119_disp_core_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); int gf119_disp_ovly_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); +int gk104_disp_core_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); int gk104_disp_ovly_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); @@ -104,6 +120,8 @@ int gp102_disp_oimm_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); int gp102_disp_base_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); +int gp102_disp_core_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); int gp102_disp_ovly_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); @@ -135,11 +153,11 @@ extern const struct nv50_disp_mthd_list nv50_disp_core_mthd_sor; extern const struct nv50_disp_mthd_list nv50_disp_core_mthd_pior; extern const struct nv50_disp_mthd_list nv50_disp_base_mthd_image; -extern const struct nv50_disp_chan_mthd g84_disp_core_chan_mthd; +extern const struct nv50_disp_chan_mthd g84_disp_core_mthd; extern const struct nv50_disp_mthd_list g84_disp_core_mthd_dac; extern const struct nv50_disp_mthd_list g84_disp_core_mthd_head; -extern const struct nv50_disp_chan_mthd g94_disp_core_chan_mthd; +extern const struct nv50_disp_chan_mthd g94_disp_core_mthd; extern const struct nv50_disp_mthd_list gf119_disp_core_mthd_base; extern const struct nv50_disp_mthd_list gf119_disp_core_mthd_dac; @@ -147,6 +165,6 @@ extern const struct nv50_disp_mthd_list gf119_disp_core_mthd_sor; extern const struct nv50_disp_mthd_list gf119_disp_core_mthd_pior; extern const struct nv50_disp_chan_mthd gf119_disp_base_mthd; -extern const struct nv50_disp_chan_mthd gk104_disp_core_chan_mthd; +extern const struct nv50_disp_chan_mthd gk104_disp_core_mthd; extern const struct nv50_disp_chan_mthd gk104_disp_ovly_mthd; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg84.c index 1baa5c34b3272..b16857f468eec 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg84.c @@ -22,9 +22,6 @@ * Authors: Ben Skeggs */ #include "dmacnv50.h" -#include "rootnv50.h" - -#include const struct nv50_disp_mthd_list g84_disp_core_mthd_dac = { @@ -91,7 +88,7 @@ g84_disp_core_mthd_head = { }; const struct nv50_disp_chan_mthd -g84_disp_core_chan_mthd = { +g84_disp_core_mthd = { .name = "Core", .addr = 0x000000, .prev = 0x000004, @@ -105,13 +102,10 @@ g84_disp_core_chan_mthd = { } }; -const struct nv50_disp_dmac_oclass -g84_disp_core_oclass = { - .base.oclass = G82_DISP_CORE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_core_new, - .func = &nv50_disp_core_func, - .mthd = &g84_disp_core_chan_mthd, - .chid = 0, -}; +int +g84_disp_core_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_core_new_(&nv50_disp_core_func, &g84_disp_core_mthd, + disp, 0, oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg94.c index c65c9f3ff69fb..ea5f48912c77a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg94.c @@ -22,9 +22,6 @@ * Authors: Ben Skeggs */ #include "dmacnv50.h" -#include "rootnv50.h" - -#include static const struct nv50_disp_mthd_list g94_disp_core_mthd_sor = { @@ -37,7 +34,7 @@ g94_disp_core_mthd_sor = { }; const struct nv50_disp_chan_mthd -g94_disp_core_chan_mthd = { +g94_disp_core_mthd = { .name = "Core", .addr = 0x000000, .prev = 0x000004, @@ -51,13 +48,10 @@ g94_disp_core_chan_mthd = { } }; -const struct nv50_disp_dmac_oclass -g94_disp_core_oclass = { - .base.oclass = GT206_DISP_CORE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_core_new, - .func = &nv50_disp_core_func, - .mthd = &g94_disp_core_chan_mthd, - .chid = 0, -}; +int +g94_disp_core_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_core_new_(&nv50_disp_core_func, &g94_disp_core_mthd, + disp, 0, oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c index 200dd90e016b4..9e48cc3625b5b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c @@ -22,14 +22,9 @@ * Authors: Ben Skeggs */ #include "dmacnv50.h" -#include "rootnv50.h" -#include #include -#include -#include - const struct nv50_disp_mthd_list gf119_disp_core_mthd_base = { .mthd = 0x0000, @@ -157,7 +152,7 @@ gf119_disp_core_mthd_head = { }; static const struct nv50_disp_chan_mthd -gf119_disp_core_chan_mthd = { +gf119_disp_core_mthd = { .name = "Core", .addr = 0x000000, .prev = -0x020000, @@ -232,13 +227,10 @@ gf119_disp_core_func = { .bind = gf119_disp_dmac_bind, }; -const struct nv50_disp_dmac_oclass -gf119_disp_core_oclass = { - .base.oclass = GF110_DISP_CORE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_core_new, - .func = &gf119_disp_core_func, - .mthd = &gf119_disp_core_chan_mthd, - .chid = 0, -}; +int +gf119_disp_core_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_core_new_(&gf119_disp_core_func, &gf119_disp_core_mthd, + disp, 0, oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregk104.c index 088ab222e8232..ca095958efdf3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregk104.c @@ -22,9 +22,6 @@ * Authors: Ben Skeggs */ #include "dmacnv50.h" -#include "rootnv50.h" - -#include static const struct nv50_disp_mthd_list gk104_disp_core_mthd_head = { @@ -106,7 +103,7 @@ gk104_disp_core_mthd_head = { }; const struct nv50_disp_chan_mthd -gk104_disp_core_chan_mthd = { +gk104_disp_core_mthd = { .name = "Core", .addr = 0x000000, .prev = -0x020000, @@ -120,13 +117,10 @@ gk104_disp_core_chan_mthd = { } }; -const struct nv50_disp_dmac_oclass -gk104_disp_core_oclass = { - .base.oclass = GK104_DISP_CORE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_core_new, - .func = &gf119_disp_core_func, - .mthd = &gk104_disp_core_chan_mthd, - .chid = 0, -}; +int +gk104_disp_core_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_core_new_(&gf119_disp_core_func, &gk104_disp_core_mthd, + disp, 0, oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregk110.c deleted file mode 100644 index df0f45c20108e..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregk110.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2015 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "dmacnv50.h" -#include "rootnv50.h" - -#include - -const struct nv50_disp_dmac_oclass -gk110_disp_core_oclass = { - .base.oclass = GK110_DISP_CORE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_core_new, - .func = &gf119_disp_core_func, - .mthd = &gk104_disp_core_chan_mthd, - .chid = 0, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregm107.c deleted file mode 100644 index 9e27f8fd98b6c..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregm107.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2015 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "dmacnv50.h" -#include "rootnv50.h" - -#include - -const struct nv50_disp_dmac_oclass -gm107_disp_core_oclass = { - .base.oclass = GM107_DISP_CORE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_core_new, - .func = &gf119_disp_core_func, - .mthd = &gk104_disp_core_chan_mthd, - .chid = 0, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregm200.c deleted file mode 100644 index bb23a8658ac07..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregm200.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2015 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "dmacnv50.h" -#include "rootnv50.h" - -#include - -const struct nv50_disp_dmac_oclass -gm200_disp_core_oclass = { - .base.oclass = GM200_DISP_CORE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_core_new, - .func = &gf119_disp_core_func, - .mthd = &gk104_disp_core_chan_mthd, - .chid = 0, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp100.c deleted file mode 100644 index d5dff6619d4d0..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp100.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2015 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "dmacnv50.h" -#include "rootnv50.h" - -#include - -const struct nv50_disp_dmac_oclass -gp100_disp_core_oclass = { - .base.oclass = GP100_DISP_CORE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_core_new, - .func = &gf119_disp_core_func, - .mthd = &gk104_disp_core_chan_mthd, - .chid = 0, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c index 6ad5f2fb2ac19..3ec353e90b3e8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c @@ -22,12 +22,9 @@ * Authors: Ben Skeggs */ #include "dmacnv50.h" -#include "rootnv50.h" #include -#include - static int gp102_disp_core_init(struct nv50_disp_dmac *chan) { @@ -66,13 +63,10 @@ gp102_disp_core_func = { .bind = gf119_disp_dmac_bind, }; -const struct nv50_disp_dmac_oclass -gp102_disp_core_oclass = { - .base.oclass = GP102_DISP_CORE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_core_new, - .func = &gp102_disp_core_func, - .mthd = &gk104_disp_core_chan_mthd, - .chid = 0, -}; +int +gp102_disp_core_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_core_new_(&gp102_disp_core_func, &gk104_disp_core_mthd, + disp, 0, oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregt200.c deleted file mode 100644 index b234547708fcf..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregt200.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2015 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "dmacnv50.h" -#include "rootnv50.h" - -#include - -const struct nv50_disp_dmac_oclass -gt200_disp_core_oclass = { - .base.oclass = GT200_DISP_CORE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_core_new, - .func = &nv50_disp_core_func, - .mthd = &g84_disp_core_chan_mthd, - .chid = 0, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregt215.c deleted file mode 100644 index 8f5ba20189756..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregt215.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2015 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "dmacnv50.h" -#include "rootnv50.h" - -#include - -const struct nv50_disp_dmac_oclass -gt215_disp_core_oclass = { - .base.oclass = GT214_DISP_CORE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_core_new, - .func = &nv50_disp_core_func, - .mthd = &g94_disp_core_chan_mthd, - .chid = 0, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c index 839cbc83428cf..8cdcf5b590e73 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c @@ -22,31 +22,29 @@ * Authors: Ben Skeggs */ #include "dmacnv50.h" -#include "rootnv50.h" #include #include -#include #include #include int -nv50_disp_core_new(const struct nv50_disp_dmac_func *func, - const struct nv50_disp_chan_mthd *mthd, - struct nv50_disp_root *root, int chid, - const struct nvkm_oclass *oclass, void *data, u32 size, - struct nvkm_object **pobject) +nv50_disp_core_new_(const struct nv50_disp_dmac_func *func, + const struct nv50_disp_chan_mthd *mthd, + struct nv50_disp *disp, int chid, + const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nvkm_object **pobject) { union { struct nv50_disp_core_channel_dma_v0 v0; - } *args = data; + } *args = argv; struct nvkm_object *parent = oclass->parent; u64 push; int ret = -ENOSYS; - nvif_ioctl(parent, "create disp core channel dma size %d\n", size); - if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { + nvif_ioctl(parent, "create disp core channel dma size %d\n", argc); + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { nvif_ioctl(parent, "create disp core channel dma vers %d " "pushbuf %016llx\n", args->v0.version, args->v0.pushbuf); @@ -54,7 +52,7 @@ nv50_disp_core_new(const struct nv50_disp_dmac_func *func, } else return ret; - return nv50_disp_dmac_new_(func, mthd, root->disp, chid, 0, + return nv50_disp_dmac_new_(func, mthd, disp, chid, 0, push, oclass, pobject); } @@ -151,7 +149,7 @@ nv50_disp_core_mthd_head = { }; static const struct nv50_disp_chan_mthd -nv50_disp_core_chan_mthd = { +nv50_disp_core_mthd = { .name = "Core", .addr = 0x000000, .prev = 0x000004, @@ -231,13 +229,10 @@ nv50_disp_core_func = { .bind = nv50_disp_dmac_bind, }; -const struct nv50_disp_dmac_oclass -nv50_disp_core_oclass = { - .base.oclass = NV50_DISP_CORE_CHANNEL_DMA, - .base.minver = 0, - .base.maxver = 0, - .ctor = nv50_disp_core_new, - .func = &nv50_disp_core_func, - .mthd = &nv50_disp_core_chan_mthd, - .chid = 0, -}; +int +nv50_disp_core_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_core_new_(&nv50_disp_core_func, &nv50_disp_core_mthd, + disp, 0, oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h index ae094c7c47f5d..feeb5882dc910 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h @@ -32,46 +32,4 @@ extern const struct nv50_disp_dmac_func gf119_disp_core_func; void gf119_disp_core_fini(struct nv50_disp_dmac *); extern const struct nv50_disp_dmac_func gp102_disp_dmac_func; - -struct nv50_disp_dmac_oclass { - int (*ctor)(const struct nv50_disp_dmac_func *, - const struct nv50_disp_chan_mthd *, - struct nv50_disp_root *, int chid, - const struct nvkm_oclass *, void *data, u32 size, - struct nvkm_object **); - struct nvkm_sclass base; - const struct nv50_disp_dmac_func *func; - const struct nv50_disp_chan_mthd *mthd; - int chid; -}; - -int nv50_disp_core_new(const struct nv50_disp_dmac_func *, - const struct nv50_disp_chan_mthd *, - struct nv50_disp_root *, int chid, - const struct nvkm_oclass *oclass, void *data, u32 size, - struct nvkm_object **); - -extern const struct nv50_disp_dmac_oclass nv50_disp_core_oclass; - -extern const struct nv50_disp_dmac_oclass g84_disp_core_oclass; - -extern const struct nv50_disp_dmac_oclass g94_disp_core_oclass; - -extern const struct nv50_disp_dmac_oclass gt200_disp_core_oclass; - -extern const struct nv50_disp_dmac_oclass gt215_disp_core_oclass; - -extern const struct nv50_disp_dmac_oclass gf119_disp_core_oclass; - -extern const struct nv50_disp_dmac_oclass gk104_disp_core_oclass; - -extern const struct nv50_disp_dmac_oclass gk110_disp_core_oclass; - -extern const struct nv50_disp_dmac_oclass gm107_disp_core_oclass; - -extern const struct nv50_disp_dmac_oclass gm200_disp_core_oclass; - -extern const struct nv50_disp_dmac_oclass gp100_disp_core_oclass; - -extern const struct nv50_disp_dmac_oclass gp102_disp_core_oclass; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c index 1d2280ab3194e..4a37c44fcbed6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c @@ -24,6 +24,7 @@ #include "nv50.h" #include "head.h" #include "ior.h" +#include "channv50.h" #include "rootnv50.h" #include diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c index 0f7e662cd175e..e51f89f325075 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c @@ -28,13 +28,11 @@ static const struct nv50_disp_root_func g84_disp_root = { - .dmac = { - &g84_disp_core_oclass, - }, .user = { {{0,0,G82_DISP_CURSOR }, nv50_disp_curs_new }, {{0,0,G82_DISP_OVERLAY }, nv50_disp_oimm_new }, {{0,0,G82_DISP_BASE_CHANNEL_DMA }, g84_disp_base_new }, + {{0,0,G82_DISP_CORE_CHANNEL_DMA }, g84_disp_core_new }, {{0,0,G82_DISP_OVERLAY_CHANNEL_DMA}, g84_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c index 20709d6e8a8b4..ed7838eedb2ce 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c @@ -28,13 +28,11 @@ static const struct nv50_disp_root_func g94_disp_root = { - .dmac = { - &g94_disp_core_oclass, - }, .user = { {{0,0, G82_DISP_CURSOR }, nv50_disp_curs_new }, {{0,0, G82_DISP_OVERLAY }, nv50_disp_oimm_new }, {{0,0,GT200_DISP_BASE_CHANNEL_DMA }, g84_disp_base_new }, + {{0,0,GT206_DISP_CORE_CHANNEL_DMA }, g94_disp_core_new }, {{0,0,GT200_DISP_OVERLAY_CHANNEL_DMA}, gt200_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c index 1161698dbb4e2..ac92e65131c9c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c @@ -28,13 +28,11 @@ static const struct nv50_disp_root_func gf119_disp_root = { - .dmac = { - &gf119_disp_core_oclass, - }, .user = { {{0,0,GF110_DISP_CURSOR }, gf119_disp_curs_new }, {{0,0,GF110_DISP_OVERLAY }, gf119_disp_oimm_new }, {{0,0,GF110_DISP_BASE_CHANNEL_DMA }, gf119_disp_base_new }, + {{0,0,GF110_DISP_CORE_CHANNEL_DMA }, gf119_disp_core_new }, {{0,0,GF110_DISP_OVERLAY_CONTROL_DMA}, gf119_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c index 15379ff5ebf46..3bb6d601aed2c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c @@ -28,13 +28,11 @@ static const struct nv50_disp_root_func gk104_disp_root = { - .dmac = { - &gk104_disp_core_oclass, - }, .user = { {{0,0,GK104_DISP_CURSOR }, gf119_disp_curs_new }, {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, {{0,0,GK104_DISP_BASE_CHANNEL_DMA }, gf119_disp_base_new }, + {{0,0,GK104_DISP_CORE_CHANNEL_DMA }, gk104_disp_core_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c index 0a47674f6541c..336419815d983 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c @@ -28,13 +28,11 @@ static const struct nv50_disp_root_func gk110_disp_root = { - .dmac = { - &gk110_disp_core_oclass, - }, .user = { {{0,0,GK104_DISP_CURSOR }, gf119_disp_curs_new }, {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, {{0,0,GK110_DISP_BASE_CHANNEL_DMA }, gf119_disp_base_new }, + {{0,0,GK110_DISP_CORE_CHANNEL_DMA }, gk104_disp_core_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c index 819521e257178..c53e71ee69e78 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c @@ -28,13 +28,11 @@ static const struct nv50_disp_root_func gm107_disp_root = { - .dmac = { - &gm107_disp_core_oclass, - }, .user = { {{0,0,GK104_DISP_CURSOR }, gf119_disp_curs_new }, {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, {{0,0,GK110_DISP_BASE_CHANNEL_DMA }, gf119_disp_base_new }, + {{0,0,GM107_DISP_CORE_CHANNEL_DMA }, gk104_disp_core_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c index 0dca1772bf339..85409d1bc7bca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c @@ -28,13 +28,11 @@ static const struct nv50_disp_root_func gm200_disp_root = { - .dmac = { - &gm200_disp_core_oclass, - }, .user = { {{0,0,GK104_DISP_CURSOR }, gf119_disp_curs_new }, {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, {{0,0,GK110_DISP_BASE_CHANNEL_DMA }, gf119_disp_base_new }, + {{0,0,GM200_DISP_CORE_CHANNEL_DMA }, gk104_disp_core_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c index 6fcf8583b8195..ebfd245c573af 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c @@ -28,13 +28,11 @@ static const struct nv50_disp_root_func gp100_disp_root = { - .dmac = { - &gp100_disp_core_oclass, - }, .user = { {{0,0,GK104_DISP_CURSOR }, gf119_disp_curs_new }, {{0,0,GK104_DISP_OVERLAY }, gf119_disp_oimm_new }, {{0,0,GK110_DISP_BASE_CHANNEL_DMA }, gf119_disp_base_new }, + {{0,0,GP100_DISP_CORE_CHANNEL_DMA }, gk104_disp_core_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gk104_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c index bf5cbc32120d8..54b5fda992087 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c @@ -28,13 +28,11 @@ static const struct nv50_disp_root_func gp102_disp_root = { - .dmac = { - &gp102_disp_core_oclass, - }, .user = { {{0,0,GK104_DISP_CURSOR }, gp102_disp_curs_new }, {{0,0,GK104_DISP_OVERLAY }, gp102_disp_oimm_new }, {{0,0,GK110_DISP_BASE_CHANNEL_DMA }, gp102_disp_base_new }, + {{0,0,GP102_DISP_CORE_CHANNEL_DMA }, gp102_disp_core_new }, {{0,0,GK104_DISP_OVERLAY_CONTROL_DMA}, gp102_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c index 2bd3f36475e30..14ac83bf36937 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c @@ -28,13 +28,11 @@ static const struct nv50_disp_root_func gt200_disp_root = { - .dmac = { - >200_disp_core_oclass, - }, .user = { {{0,0, G82_DISP_CURSOR }, nv50_disp_curs_new }, {{0,0, G82_DISP_OVERLAY }, nv50_disp_oimm_new }, {{0,0,GT200_DISP_BASE_CHANNEL_DMA }, g84_disp_base_new }, + {{0,0,GT200_DISP_CORE_CHANNEL_DMA }, g84_disp_core_new }, {{0,0,GT200_DISP_OVERLAY_CHANNEL_DMA}, gt200_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c index aa4c52355e884..cb1a208e68bd9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c @@ -28,13 +28,11 @@ static const struct nv50_disp_root_func gt215_disp_root = { - .dmac = { - >215_disp_core_oclass, - }, .user = { {{0,0,GT214_DISP_CURSOR }, nv50_disp_curs_new }, {{0,0,GT214_DISP_OVERLAY }, nv50_disp_oimm_new }, {{0,0,GT214_DISP_BASE_CHANNEL_DMA }, g84_disp_base_new }, + {{0,0,GT214_DISP_CORE_CHANNEL_DMA }, g94_disp_core_new }, {{0,0,GT214_DISP_OVERLAY_CHANNEL_DMA}, g84_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c index 24e8b418ac657..9d716ee7621e5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c @@ -268,16 +268,6 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size) return -EINVAL; } -static int -nv50_disp_root_dmac_new_(const struct nvkm_oclass *oclass, - void *data, u32 size, struct nvkm_object **pobject) -{ - const struct nv50_disp_dmac_oclass *sclass = oclass->priv; - struct nv50_disp_root *root = nv50_disp_root(oclass->parent); - return sclass->ctor(sclass->func, sclass->mthd, root, sclass->chid, - oclass, data, size, pobject); -} - static int nv50_disp_root_child_new_(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject) @@ -293,15 +283,6 @@ nv50_disp_root_child_get_(struct nvkm_object *object, int index, { struct nv50_disp_root *root = nv50_disp_root(object); - if (index < ARRAY_SIZE(root->func->dmac)) { - sclass->base = root->func->dmac[index]->base; - sclass->priv = root->func->dmac[index]; - sclass->ctor = nv50_disp_root_dmac_new_; - return 0; - } - - index -= ARRAY_SIZE(root->func->dmac); - if (root->func->user[index].ctor) { sclass->base = root->func->user[index].base; sclass->priv = root->func->user + index; @@ -347,13 +328,11 @@ nv50_disp_root_new_(const struct nv50_disp_root_func *func, static const struct nv50_disp_root_func nv50_disp_root = { - .dmac = { - &nv50_disp_core_oclass, - }, .user = { {{0,0,NV50_DISP_CURSOR }, nv50_disp_curs_new }, {{0,0,NV50_DISP_OVERLAY }, nv50_disp_oimm_new }, {{0,0,NV50_DISP_BASE_CHANNEL_DMA }, nv50_disp_base_new }, + {{0,0,NV50_DISP_CORE_CHANNEL_DMA }, nv50_disp_core_new }, {{0,0,NV50_DISP_OVERLAY_CHANNEL_DMA}, nv50_disp_ovly_new }, {} }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h index 484868af65977..12fc13b397eda 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h @@ -12,7 +12,7 @@ struct nv50_disp_root { }; struct nv50_disp_root_func { - const struct nv50_disp_dmac_oclass *dmac[1]; + int blah; struct nv50_disp_user { struct nvkm_sclass base; int (*ctor)(const struct nvkm_oclass *, void *argv, u32 argc, From 8531f57027136fa63ddae91821ca89b32b571fe2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 021/165] drm/nouveau/disp/nv50-: merge handling of pio and dma channels Unnecessarily complicated, and a barrier to cleanly supporting Volta. Signed-off-by: Ben Skeggs --- .../drm/nouveau/nvkm/engine/disp/baseg84.c | 2 +- .../drm/nouveau/nvkm/engine/disp/basegf119.c | 2 +- .../drm/nouveau/nvkm/engine/disp/basegp102.c | 2 +- .../drm/nouveau/nvkm/engine/disp/basenv50.c | 4 +- .../drm/nouveau/nvkm/engine/disp/channv50.c | 97 ++++++++---- .../drm/nouveau/nvkm/engine/disp/channv50.h | 39 ++--- .../drm/nouveau/nvkm/engine/disp/coreg84.c | 2 +- .../drm/nouveau/nvkm/engine/disp/coreg94.c | 2 +- .../drm/nouveau/nvkm/engine/disp/coregf119.c | 14 +- .../drm/nouveau/nvkm/engine/disp/coregk104.c | 2 +- .../drm/nouveau/nvkm/engine/disp/coregp102.c | 9 +- .../drm/nouveau/nvkm/engine/disp/corenv50.c | 16 +- .../drm/nouveau/nvkm/engine/disp/dmacgf119.c | 31 ++-- .../drm/nouveau/nvkm/engine/disp/dmacgp102.c | 14 +- .../drm/nouveau/nvkm/engine/disp/dmacnv50.c | 147 +++--------------- .../drm/nouveau/nvkm/engine/disp/dmacnv50.h | 35 ----- .../gpu/drm/nouveau/nvkm/engine/disp/gf119.c | 1 + .../gpu/drm/nouveau/nvkm/engine/disp/gp102.c | 1 + .../gpu/drm/nouveau/nvkm/engine/disp/nv50.h | 7 + .../drm/nouveau/nvkm/engine/disp/ovlyg84.c | 2 +- .../drm/nouveau/nvkm/engine/disp/ovlygf119.c | 2 +- .../drm/nouveau/nvkm/engine/disp/ovlygk104.c | 2 +- .../drm/nouveau/nvkm/engine/disp/ovlygp102.c | 2 +- .../drm/nouveau/nvkm/engine/disp/ovlygt200.c | 2 +- .../drm/nouveau/nvkm/engine/disp/ovlynv50.c | 4 +- .../drm/nouveau/nvkm/engine/disp/rootg84.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootg94.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgf119.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgk104.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgk110.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgm107.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgm200.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgp100.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgp102.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgt200.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootgt215.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootnv50.c | 2 +- .../drm/nouveau/nvkm/engine/disp/rootnv50.h | 2 +- 38 files changed, 183 insertions(+), 284 deletions(-) delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/baseg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/baseg84.c index 03ec508d19f05..01253f4a99467 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/baseg84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/baseg84.c @@ -21,7 +21,7 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" +#include "channv50.h" static const struct nv50_disp_mthd_list g84_disp_base_mthd_base = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegf119.c index 4c372dc6a1286..389e19dfc5141 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegf119.c @@ -21,7 +21,7 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" +#include "channv50.h" static const struct nv50_disp_mthd_list gf119_disp_base_mthd_base = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegp102.c index 3a25259de0574..0cb23d673aa0c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basegp102.c @@ -21,7 +21,7 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" +#include "channv50.h" int gp102_disp_base_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basenv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basenv50.c index 11639e2a792f4..19eb7dde01f2e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/basenv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/basenv50.c @@ -21,7 +21,7 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" +#include "channv50.h" #include "head.h" #include @@ -30,7 +30,7 @@ #include int -nv50_disp_base_new_(const struct nv50_disp_dmac_func *func, +nv50_disp_base_new_(const struct nv50_disp_chan_func *func, const struct nv50_disp_chan_mthd *mthd, struct nv50_disp *disp, int chid, const struct nvkm_oclass *oclass, void *argv, u32 argc, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c index 96b732d4b9abd..91a2f0c64731e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -204,25 +205,76 @@ nv50_disp_chan_map(struct nvkm_object *object, void *argv, u32 argc, return 0; } +struct nv50_disp_chan_object { + struct nvkm_oproxy oproxy; + struct nv50_disp *disp; + int hash; +}; + +static void +nv50_disp_chan_child_del_(struct nvkm_oproxy *base) +{ + struct nv50_disp_chan_object *object = + container_of(base, typeof(*object), oproxy); + nvkm_ramht_remove(object->disp->ramht, object->hash); +} + +static const struct nvkm_oproxy_func +nv50_disp_chan_child_func_ = { + .dtor[0] = nv50_disp_chan_child_del_, +}; + static int nv50_disp_chan_child_new(const struct nvkm_oclass *oclass, - void *data, u32 size, struct nvkm_object **pobject) + void *argv, u32 argc, struct nvkm_object **pobject) { struct nv50_disp_chan *chan = nv50_disp_chan(oclass->parent); - return chan->func->child_new(chan, oclass, data, size, pobject); + struct nv50_disp *disp = chan->disp; + struct nvkm_device *device = disp->base.engine.subdev.device; + const struct nvkm_device_oclass *sclass = oclass->priv; + struct nv50_disp_chan_object *object; + int ret; + + if (!(object = kzalloc(sizeof(*object), GFP_KERNEL))) + return -ENOMEM; + nvkm_oproxy_ctor(&nv50_disp_chan_child_func_, oclass, &object->oproxy); + object->disp = disp; + *pobject = &object->oproxy.base; + + ret = sclass->ctor(device, oclass, argv, argc, &object->oproxy.object); + if (ret) + return ret; + + object->hash = chan->func->bind(chan, object->oproxy.object, + oclass->handle); + if (object->hash < 0) + return object->hash; + + return 0; } static int nv50_disp_chan_child_get(struct nvkm_object *object, int index, - struct nvkm_oclass *oclass) + struct nvkm_oclass *sclass) { struct nv50_disp_chan *chan = nv50_disp_chan(object); - if (chan->func->child_get) { - int ret = chan->func->child_get(chan, index, oclass); - if (ret == 0) - oclass->ctor = nv50_disp_chan_child_new; - return ret; + struct nvkm_device *device = chan->disp->base.engine.subdev.device; + const struct nvkm_device_oclass *oclass = NULL; + + if (chan->func->bind) + sclass->engine = nvkm_device_engine(device, NVKM_ENGINE_DMAOBJ); + else + sclass->engine = NULL; + + if (sclass->engine && sclass->engine->func->base.sclass) { + sclass->engine->func->base.sclass(sclass, index, &oclass); + if (oclass) { + sclass->ctor = nv50_disp_chan_child_new, + sclass->priv = oclass; + return 0; + } } + return -EINVAL; } @@ -248,7 +300,7 @@ nv50_disp_chan_dtor(struct nvkm_object *object) struct nv50_disp *disp = chan->disp; if (chan->chid.user >= 0) disp->chan[chan->chid.user] = NULL; - return chan->func->dtor ? chan->func->dtor(chan) : chan; + return chan; } static const struct nvkm_object_func @@ -264,12 +316,18 @@ nv50_disp_chan = { }; int -nv50_disp_chan_ctor(const struct nv50_disp_chan_func *func, +nv50_disp_chan_new_(const struct nv50_disp_chan_func *func, const struct nv50_disp_chan_mthd *mthd, struct nv50_disp *disp, int ctrl, int user, int head, const struct nvkm_oclass *oclass, - struct nv50_disp_chan *chan) + struct nvkm_object **pobject) { + struct nv50_disp_chan *chan; + + if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + return -ENOMEM; + *pobject = &chan->object; + nvkm_object_ctor(&nv50_disp_chan, oclass, &chan->object); chan->func = func; chan->mthd = mthd; @@ -285,20 +343,3 @@ nv50_disp_chan_ctor(const struct nv50_disp_chan_func *func, disp->chan[chan->chid.user] = chan; return 0; } - -int -nv50_disp_chan_new_(const struct nv50_disp_chan_func *func, - const struct nv50_disp_chan_mthd *mthd, - struct nv50_disp *disp, int ctrl, int user, int head, - const struct nvkm_oclass *oclass, - struct nvkm_object **pobject) -{ - struct nv50_disp_chan *chan; - - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) - return -ENOMEM; - *pobject = &chan->object; - - return nv50_disp_chan_ctor(func, mthd, disp, ctrl, user, - head, oclass, chan); -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h index 10ce217cc0818..feb8a56fcc858 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h @@ -5,7 +5,6 @@ #include #include "nv50.h" struct nv50_disp_root; -struct nv50_disp_dmac_func; struct nv50_disp_chan { const struct nv50_disp_chan_func *func; @@ -19,36 +18,38 @@ struct nv50_disp_chan { int head; struct nvkm_object object; + + u64 push; }; struct nv50_disp_chan_func { - void *(*dtor)(struct nv50_disp_chan *); int (*init)(struct nv50_disp_chan *); void (*fini)(struct nv50_disp_chan *); - int (*child_get)(struct nv50_disp_chan *, int index, - struct nvkm_oclass *); - int (*child_new)(struct nv50_disp_chan *, const struct nvkm_oclass *, - void *data, u32 size, struct nvkm_object **); + int (*bind)(struct nv50_disp_chan *, struct nvkm_object *, u32 handle); }; -int nv50_disp_chan_ctor(const struct nv50_disp_chan_func *, - const struct nv50_disp_chan_mthd *, - struct nv50_disp *, int ctrl, int user, int head, - const struct nvkm_oclass *, struct nv50_disp_chan *); int nv50_disp_chan_new_(const struct nv50_disp_chan_func *, const struct nv50_disp_chan_mthd *, struct nv50_disp *, int ctrl, int user, int head, const struct nvkm_oclass *, struct nvkm_object **); +int nv50_disp_dmac_new_(const struct nv50_disp_chan_func *, + const struct nv50_disp_chan_mthd *, + struct nv50_disp *, int chid, int head, u64 push, + const struct nvkm_oclass *, struct nvkm_object **); extern const struct nv50_disp_chan_func nv50_disp_pioc_func; -extern const struct nv50_disp_chan_func gf119_disp_pioc_func; +extern const struct nv50_disp_chan_func nv50_disp_dmac_func; +int nv50_disp_dmac_bind(struct nv50_disp_chan *, struct nvkm_object *, u32); +extern const struct nv50_disp_chan_func nv50_disp_core_func; -extern const struct nvkm_event_func nv50_disp_chan_uevent; -int nv50_disp_chan_uevent_ctor(struct nvkm_object *, void *, u32, - struct nvkm_notify *); -void nv50_disp_chan_uevent_send(struct nv50_disp *, int); +extern const struct nv50_disp_chan_func gf119_disp_pioc_func; +extern const struct nv50_disp_chan_func gf119_disp_dmac_func; +void gf119_disp_dmac_fini(struct nv50_disp_chan *); +int gf119_disp_dmac_bind(struct nv50_disp_chan *, struct nvkm_object *, u32); +extern const struct nv50_disp_chan_func gf119_disp_core_func; +void gf119_disp_core_fini(struct nv50_disp_chan *); -extern const struct nvkm_event_func gf119_disp_chan_uevent; +extern const struct nv50_disp_chan_func gp102_disp_dmac_func; int nv50_disp_curs_new_(const struct nv50_disp_chan_func *, struct nv50_disp *, int ctrl, int user, @@ -58,17 +59,17 @@ int nv50_disp_oimm_new_(const struct nv50_disp_chan_func *, struct nv50_disp *, int ctrl, int user, const struct nvkm_oclass *, void *argv, u32 argc, struct nvkm_object **); -int nv50_disp_base_new_(const struct nv50_disp_dmac_func *, +int nv50_disp_base_new_(const struct nv50_disp_chan_func *, const struct nv50_disp_chan_mthd *, struct nv50_disp *, int chid, const struct nvkm_oclass *, void *argv, u32 argc, struct nvkm_object **); -int nv50_disp_core_new_(const struct nv50_disp_dmac_func *, +int nv50_disp_core_new_(const struct nv50_disp_chan_func *, const struct nv50_disp_chan_mthd *, struct nv50_disp *, int chid, const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **); -int nv50_disp_ovly_new_(const struct nv50_disp_dmac_func *, +int nv50_disp_ovly_new_(const struct nv50_disp_chan_func *, const struct nv50_disp_chan_mthd *, struct nv50_disp *, int chid, const struct nvkm_oclass *, void *argv, u32 argc, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg84.c index b16857f468eec..cfc54aad3e7cb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg84.c @@ -21,7 +21,7 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" +#include "channv50.h" const struct nv50_disp_mthd_list g84_disp_core_mthd_dac = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg94.c index ea5f48912c77a..e911925f1182d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg94.c @@ -21,7 +21,7 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" +#include "channv50.h" static const struct nv50_disp_mthd_list g94_disp_core_mthd_sor = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c index 9e48cc3625b5b..17c66162417bd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c @@ -21,7 +21,7 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" +#include "channv50.h" #include @@ -167,10 +167,9 @@ gf119_disp_core_mthd = { }; void -gf119_disp_core_fini(struct nv50_disp_dmac *chan) +gf119_disp_core_fini(struct nv50_disp_chan *chan) { - struct nv50_disp *disp = chan->base.disp; - struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; struct nvkm_device *device = subdev->device; /* deactivate channel */ @@ -190,10 +189,9 @@ gf119_disp_core_fini(struct nv50_disp_dmac *chan) } static int -gf119_disp_core_init(struct nv50_disp_dmac *chan) +gf119_disp_core_init(struct nv50_disp_chan *chan) { - struct nv50_disp *disp = chan->base.disp; - struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; struct nvkm_device *device = subdev->device; /* enable error reporting */ @@ -220,7 +218,7 @@ gf119_disp_core_init(struct nv50_disp_dmac *chan) return 0; } -const struct nv50_disp_dmac_func +const struct nv50_disp_chan_func gf119_disp_core_func = { .init = gf119_disp_core_init, .fini = gf119_disp_core_fini, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregk104.c index ca095958efdf3..5c800174e0791 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregk104.c @@ -21,7 +21,7 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" +#include "channv50.h" static const struct nv50_disp_mthd_list gk104_disp_core_mthd_head = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c index 3ec353e90b3e8..57d26051bc95b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c @@ -21,15 +21,14 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" +#include "channv50.h" #include static int -gp102_disp_core_init(struct nv50_disp_dmac *chan) +gp102_disp_core_init(struct nv50_disp_chan *chan) { - struct nv50_disp *disp = chan->base.disp; - struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; struct nvkm_device *device = subdev->device; /* enable error reporting */ @@ -56,7 +55,7 @@ gp102_disp_core_init(struct nv50_disp_dmac *chan) return 0; } -static const struct nv50_disp_dmac_func +static const struct nv50_disp_chan_func gp102_disp_core_func = { .init = gp102_disp_core_init, .fini = gf119_disp_core_fini, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c index 8cdcf5b590e73..d648c4d7b55c5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c @@ -21,7 +21,7 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" +#include "channv50.h" #include #include @@ -30,7 +30,7 @@ #include int -nv50_disp_core_new_(const struct nv50_disp_dmac_func *func, +nv50_disp_core_new_(const struct nv50_disp_chan_func *func, const struct nv50_disp_chan_mthd *mthd, struct nv50_disp *disp, int chid, const struct nvkm_oclass *oclass, void *argv, u32 argc, @@ -164,10 +164,9 @@ nv50_disp_core_mthd = { }; static void -nv50_disp_core_fini(struct nv50_disp_dmac *chan) +nv50_disp_core_fini(struct nv50_disp_chan *chan) { - struct nv50_disp *disp = chan->base.disp; - struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; struct nvkm_device *device = subdev->device; /* deactivate channel */ @@ -186,10 +185,9 @@ nv50_disp_core_fini(struct nv50_disp_dmac *chan) } static int -nv50_disp_core_init(struct nv50_disp_dmac *chan) +nv50_disp_core_init(struct nv50_disp_chan *chan) { - struct nv50_disp *disp = chan->base.disp; - struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; struct nvkm_device *device = subdev->device; /* enable error reporting */ @@ -222,7 +220,7 @@ nv50_disp_core_init(struct nv50_disp_dmac *chan) return 0; } -const struct nv50_disp_dmac_func +const struct nv50_disp_chan_func nv50_disp_core_func = { .init = nv50_disp_core_init, .fini = nv50_disp_core_fini, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c index b73bcc38a2598..f69749a29df86 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c @@ -21,29 +21,27 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" -#include "rootnv50.h" +#include "channv50.h" #include #include int -gf119_disp_dmac_bind(struct nv50_disp_dmac *chan, +gf119_disp_dmac_bind(struct nv50_disp_chan *chan, struct nvkm_object *object, u32 handle) { - return nvkm_ramht_insert(chan->base.disp->ramht, object, - chan->base.chid.user, -9, handle, - chan->base.chid.user << 27 | 0x00000001); + return nvkm_ramht_insert(chan->disp->ramht, object, + chan->chid.user, -9, handle, + chan->chid.user << 27 | 0x00000001); } void -gf119_disp_dmac_fini(struct nv50_disp_dmac *chan) +gf119_disp_dmac_fini(struct nv50_disp_chan *chan) { - struct nv50_disp *disp = chan->base.disp; - struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; struct nvkm_device *device = subdev->device; - int ctrl = chan->base.chid.ctrl; - int user = chan->base.chid.user; + int ctrl = chan->chid.ctrl; + int user = chan->chid.user; /* deactivate channel */ nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00001010, 0x00001000); @@ -62,13 +60,12 @@ gf119_disp_dmac_fini(struct nv50_disp_dmac *chan) } static int -gf119_disp_dmac_init(struct nv50_disp_dmac *chan) +gf119_disp_dmac_init(struct nv50_disp_chan *chan) { - struct nv50_disp *disp = chan->base.disp; - struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; struct nvkm_device *device = subdev->device; - int ctrl = chan->base.chid.ctrl; - int user = chan->base.chid.user; + int ctrl = chan->chid.ctrl; + int user = chan->chid.user; /* enable error reporting */ nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user); @@ -94,7 +91,7 @@ gf119_disp_dmac_init(struct nv50_disp_dmac *chan) return 0; } -const struct nv50_disp_dmac_func +const struct nv50_disp_chan_func gf119_disp_dmac_func = { .init = gf119_disp_dmac_init, .fini = gf119_disp_dmac_fini, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c index 62e9b8430791b..22fa5925644a0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c @@ -21,19 +21,17 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" -#include "rootnv50.h" +#include "channv50.h" #include static int -gp102_disp_dmac_init(struct nv50_disp_dmac *chan) +gp102_disp_dmac_init(struct nv50_disp_chan *chan) { - struct nv50_disp *disp = chan->base.disp; - struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; struct nvkm_device *device = subdev->device; - int ctrl = chan->base.chid.ctrl; - int user = chan->base.chid.user; + int ctrl = chan->chid.ctrl; + int user = chan->chid.user; /* enable error reporting */ nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user); @@ -59,7 +57,7 @@ gp102_disp_dmac_init(struct nv50_disp_dmac *chan) return 0; } -const struct nv50_disp_dmac_func +const struct nv50_disp_chan_func gp102_disp_dmac_func = { .init = gp102_disp_dmac_init, .fini = gf119_disp_dmac_fini, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c index d081947d06891..5cd08cad2c269 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c @@ -21,117 +21,16 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" -#include "rootnv50.h" +#include "channv50.h" #include -#include #include #include #include #include -struct nv50_disp_dmac_object { - struct nvkm_oproxy oproxy; - struct nv50_disp *disp; - int hash; -}; - -static void -nv50_disp_dmac_child_del_(struct nvkm_oproxy *base) -{ - struct nv50_disp_dmac_object *object = - container_of(base, typeof(*object), oproxy); - nvkm_ramht_remove(object->disp->ramht, object->hash); -} - -static const struct nvkm_oproxy_func -nv50_disp_dmac_child_func_ = { - .dtor[0] = nv50_disp_dmac_child_del_, -}; - -static int -nv50_disp_dmac_child_new_(struct nv50_disp_chan *base, - const struct nvkm_oclass *oclass, - void *data, u32 size, struct nvkm_object **pobject) -{ - struct nv50_disp_dmac *chan = nv50_disp_dmac(base); - struct nv50_disp *disp = chan->base.disp; - struct nvkm_device *device = disp->base.engine.subdev.device; - const struct nvkm_device_oclass *sclass = oclass->priv; - struct nv50_disp_dmac_object *object; - int ret; - - if (!(object = kzalloc(sizeof(*object), GFP_KERNEL))) - return -ENOMEM; - nvkm_oproxy_ctor(&nv50_disp_dmac_child_func_, oclass, &object->oproxy); - object->disp = disp; - *pobject = &object->oproxy.base; - - ret = sclass->ctor(device, oclass, data, size, &object->oproxy.object); - if (ret) - return ret; - - object->hash = chan->func->bind(chan, object->oproxy.object, - oclass->handle); - if (object->hash < 0) - return object->hash; - - return 0; -} - -static int -nv50_disp_dmac_child_get_(struct nv50_disp_chan *base, int index, - struct nvkm_oclass *sclass) -{ - struct nv50_disp_dmac *chan = nv50_disp_dmac(base); - struct nv50_disp *disp = chan->base.disp; - struct nvkm_device *device = disp->base.engine.subdev.device; - const struct nvkm_device_oclass *oclass = NULL; - - sclass->engine = nvkm_device_engine(device, NVKM_ENGINE_DMAOBJ); - if (sclass->engine && sclass->engine->func->base.sclass) { - sclass->engine->func->base.sclass(sclass, index, &oclass); - if (oclass) { - sclass->priv = oclass; - return 0; - } - } - - return -EINVAL; -} - -static void -nv50_disp_dmac_fini_(struct nv50_disp_chan *base) -{ - struct nv50_disp_dmac *chan = nv50_disp_dmac(base); - chan->func->fini(chan); -} - -static int -nv50_disp_dmac_init_(struct nv50_disp_chan *base) -{ - struct nv50_disp_dmac *chan = nv50_disp_dmac(base); - return chan->func->init(chan); -} - -static void * -nv50_disp_dmac_dtor_(struct nv50_disp_chan *base) -{ - return nv50_disp_dmac(base); -} - -static const struct nv50_disp_chan_func -nv50_disp_dmac_func_ = { - .dtor = nv50_disp_dmac_dtor_, - .init = nv50_disp_dmac_init_, - .fini = nv50_disp_dmac_fini_, - .child_get = nv50_disp_dmac_child_get_, - .child_new = nv50_disp_dmac_child_new_, -}; - int -nv50_disp_dmac_new_(const struct nv50_disp_dmac_func *func, +nv50_disp_dmac_new_(const struct nv50_disp_chan_func *func, const struct nv50_disp_chan_mthd *mthd, struct nv50_disp *disp, int chid, int head, u64 push, const struct nvkm_oclass *oclass, @@ -139,16 +38,12 @@ nv50_disp_dmac_new_(const struct nv50_disp_dmac_func *func, { struct nvkm_client *client = oclass->client; struct nvkm_dmaobj *dmaobj; - struct nv50_disp_dmac *chan; + struct nv50_disp_chan *chan; int ret; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) - return -ENOMEM; - *pobject = &chan->base.object; - chan->func = func; - - ret = nv50_disp_chan_ctor(&nv50_disp_dmac_func_, mthd, disp, - chid, chid, head, oclass, &chan->base); + ret = nv50_disp_chan_new_(func, mthd, disp, chid, chid, head, oclass, + pobject); + chan = nv50_disp_chan(*pobject); if (ret) return ret; @@ -174,23 +69,22 @@ nv50_disp_dmac_new_(const struct nv50_disp_dmac_func *func, } int -nv50_disp_dmac_bind(struct nv50_disp_dmac *chan, +nv50_disp_dmac_bind(struct nv50_disp_chan *chan, struct nvkm_object *object, u32 handle) { - return nvkm_ramht_insert(chan->base.disp->ramht, object, - chan->base.chid.user, -10, handle, - chan->base.chid.user << 28 | - chan->base.chid.user); + return nvkm_ramht_insert(chan->disp->ramht, object, + chan->chid.user, -10, handle, + chan->chid.user << 28 | + chan->chid.user); } static void -nv50_disp_dmac_fini(struct nv50_disp_dmac *chan) +nv50_disp_dmac_fini(struct nv50_disp_chan *chan) { - struct nv50_disp *disp = chan->base.disp; - struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; struct nvkm_device *device = subdev->device; - int ctrl = chan->base.chid.ctrl; - int user = chan->base.chid.user; + int ctrl = chan->chid.ctrl; + int user = chan->chid.user; /* deactivate channel */ nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00001010, 0x00001000); @@ -208,13 +102,12 @@ nv50_disp_dmac_fini(struct nv50_disp_dmac *chan) } static int -nv50_disp_dmac_init(struct nv50_disp_dmac *chan) +nv50_disp_dmac_init(struct nv50_disp_chan *chan) { - struct nv50_disp *disp = chan->base.disp; - struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; struct nvkm_device *device = subdev->device; - int ctrl = chan->base.chid.ctrl; - int user = chan->base.chid.user; + int ctrl = chan->chid.ctrl; + int user = chan->chid.user; /* enable error reporting */ nvkm_mask(device, 0x610028, 0x00010000 << user, 0x00010000 << user); @@ -240,7 +133,7 @@ nv50_disp_dmac_init(struct nv50_disp_dmac *chan) return 0; } -const struct nv50_disp_dmac_func +const struct nv50_disp_chan_func nv50_disp_dmac_func = { .init = nv50_disp_dmac_init, .fini = nv50_disp_dmac_fini, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h deleted file mode 100644 index feeb5882dc910..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __NV50_DISP_DMAC_H__ -#define __NV50_DISP_DMAC_H__ -#define nv50_disp_dmac(p) container_of((p), struct nv50_disp_dmac, base) -#include "channv50.h" - -struct nv50_disp_dmac { - const struct nv50_disp_dmac_func *func; - struct nv50_disp_chan base; - u32 push; -}; - -struct nv50_disp_dmac_func { - int (*init)(struct nv50_disp_dmac *); - void (*fini)(struct nv50_disp_dmac *); - int (*bind)(struct nv50_disp_dmac *, struct nvkm_object *, u32 handle); -}; - -int nv50_disp_dmac_new_(const struct nv50_disp_dmac_func *, - const struct nv50_disp_chan_mthd *, - struct nv50_disp *, int chid, int head, u64 push, - const struct nvkm_oclass *, struct nvkm_object **); - -extern const struct nv50_disp_dmac_func nv50_disp_dmac_func; -int nv50_disp_dmac_bind(struct nv50_disp_dmac *, struct nvkm_object *, u32); -extern const struct nv50_disp_dmac_func nv50_disp_core_func; - -extern const struct nv50_disp_dmac_func gf119_disp_dmac_func; -void gf119_disp_dmac_fini(struct nv50_disp_dmac *); -int gf119_disp_dmac_bind(struct nv50_disp_dmac *, struct nvkm_object *, u32); -extern const struct nv50_disp_dmac_func gf119_disp_core_func; -void gf119_disp_core_fini(struct nv50_disp_dmac *); - -extern const struct nv50_disp_dmac_func gp102_disp_dmac_func; -#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c index 382e6a6a6ff2c..794e90982641e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c @@ -24,6 +24,7 @@ #include "nv50.h" #include "head.h" #include "ior.h" +#include "channv50.h" #include "rootnv50.h" #include diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c index 0a2c5b5f87eb6..3468ddec1270b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c @@ -24,6 +24,7 @@ #include "nv50.h" #include "head.h" #include "ior.h" +#include "channv50.h" #include "rootnv50.h" static void diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h index bb622d0f6d639..77aa2c8cfcd6a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h @@ -79,4 +79,11 @@ void gf119_disp_intr_error(struct nv50_disp *, int); void nv50_disp_dptmds_war_2(struct nv50_disp *, struct dcb_output *); void nv50_disp_dptmds_war_3(struct nv50_disp *, struct dcb_output *); void nv50_disp_update_sppll1(struct nv50_disp *); + +extern const struct nvkm_event_func nv50_disp_chan_uevent; +int nv50_disp_chan_uevent_ctor(struct nvkm_object *, void *, u32, + struct nvkm_notify *); +void nv50_disp_chan_uevent_send(struct nv50_disp *, int); + +extern const struct nvkm_event_func gf119_disp_chan_uevent; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlyg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlyg84.c index 6b55cf483fe2a..31b915d486995 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlyg84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlyg84.c @@ -21,7 +21,7 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" +#include "channv50.h" static const struct nv50_disp_mthd_list g84_disp_ovly_mthd_base = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygf119.c index 30901caf75dc3..83fd534c44dab 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygf119.c @@ -21,7 +21,7 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" +#include "channv50.h" static const struct nv50_disp_mthd_list gf119_disp_ovly_mthd_base = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygk104.c index 682c146c39d4e..a7acacbc92c15 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygk104.c @@ -21,7 +21,7 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" +#include "channv50.h" static const struct nv50_disp_mthd_list gk104_disp_ovly_mthd_base = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygp102.c index bcc5ac40f6f95..e0eca6ea914ca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygp102.c @@ -21,7 +21,7 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" +#include "channv50.h" int gp102_disp_ovly_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygt200.c index 655deb0d2fa0d..dc60cd00dc16e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygt200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlygt200.c @@ -21,7 +21,7 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" +#include "channv50.h" static const struct nv50_disp_mthd_list gt200_disp_ovly_mthd_base = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlynv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlynv50.c index 46f5df0b3a1e2..6974c12c45186 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlynv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ovlynv50.c @@ -21,7 +21,7 @@ * * Authors: Ben Skeggs */ -#include "dmacnv50.h" +#include "channv50.h" #include "head.h" #include @@ -30,7 +30,7 @@ #include int -nv50_disp_ovly_new_(const struct nv50_disp_dmac_func *func, +nv50_disp_ovly_new_(const struct nv50_disp_chan_func *func, const struct nv50_disp_chan_mthd *mthd, struct nv50_disp *disp, int chid, const struct nvkm_oclass *oclass, void *argv, u32 argc, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c index e51f89f325075..1ed371fd7ddfa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg84.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #include "rootnv50.h" -#include "dmacnv50.h" +#include "channv50.h" #include diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c index ed7838eedb2ce..ef579eb00238c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootg94.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #include "rootnv50.h" -#include "dmacnv50.h" +#include "channv50.h" #include diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c index ac92e65131c9c..fe011165dc020 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgf119.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #include "rootnv50.h" -#include "dmacnv50.h" +#include "channv50.h" #include diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c index 3bb6d601aed2c..9e8ffd348b504 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk104.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #include "rootnv50.h" -#include "dmacnv50.h" +#include "channv50.h" #include diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c index 336419815d983..dc85cc1c94907 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgk110.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #include "rootnv50.h" -#include "dmacnv50.h" +#include "channv50.h" #include diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c index c53e71ee69e78..e0181ca088406 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm107.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #include "rootnv50.h" -#include "dmacnv50.h" +#include "channv50.h" #include diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c index 85409d1bc7bca..e5e590e19f621 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgm200.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #include "rootnv50.h" -#include "dmacnv50.h" +#include "channv50.h" #include diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c index ebfd245c573af..762a1a922e051 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp100.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #include "rootnv50.h" -#include "dmacnv50.h" +#include "channv50.h" #include diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c index 54b5fda992087..c7f00946c9af8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp102.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #include "rootnv50.h" -#include "dmacnv50.h" +#include "channv50.h" #include diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c index 14ac83bf36937..a6963654087cb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt200.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #include "rootnv50.h" -#include "dmacnv50.h" +#include "channv50.h" #include diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c index cb1a208e68bd9..4fe0a3ae8891f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgt215.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #include "rootnv50.h" -#include "dmacnv50.h" +#include "channv50.h" #include diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c index 9d716ee7621e5..3aa5a28792393 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #include "rootnv50.h" -#include "dmacnv50.h" +#include "channv50.h" #include "dp.h" #include "head.h" #include "ior.h" diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h index 12fc13b397eda..9983a424d30db 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h @@ -2,8 +2,8 @@ #ifndef __NV50_DISP_ROOT_H__ #define __NV50_DISP_ROOT_H__ #define nv50_disp_root(p) container_of((p), struct nv50_disp_root, object) +#include #include "nv50.h" -#include "dmacnv50.h" struct nv50_disp_root { const struct nv50_disp_root_func *func; From 4a8621a24a8f68ecba6e59dccad2b252fa90ba59 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 022/165] drm/nouveau/disp/nv50-: add channel interfaces to determine the user area This will be required to support Volta. Signed-off-by: Ben Skeggs --- .../drm/nouveau/nvkm/engine/disp/channv50.c | 27 +++++++++++-------- .../drm/nouveau/nvkm/engine/disp/channv50.h | 2 ++ .../drm/nouveau/nvkm/engine/disp/coregf119.c | 1 + .../drm/nouveau/nvkm/engine/disp/coregp102.c | 1 + .../drm/nouveau/nvkm/engine/disp/corenv50.c | 1 + .../drm/nouveau/nvkm/engine/disp/dmacgf119.c | 1 + .../drm/nouveau/nvkm/engine/disp/dmacgp102.c | 1 + .../drm/nouveau/nvkm/engine/disp/dmacnv50.c | 1 + .../drm/nouveau/nvkm/engine/disp/piocgf119.c | 1 + .../drm/nouveau/nvkm/engine/disp/piocnv50.c | 1 + 10 files changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c index 91a2f0c64731e..8e79aa5f52e69 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c @@ -155,13 +155,20 @@ nv50_disp_chan_uevent = { .fini = nv50_disp_chan_uevent_fini, }; +u64 +nv50_disp_chan_user(struct nv50_disp_chan *chan, u64 *psize) +{ + *psize = 0x1000; + return 0x640000 + (chan->chid.user * 0x1000); +} + static int nv50_disp_chan_rd32(struct nvkm_object *object, u64 addr, u32 *data) { struct nv50_disp_chan *chan = nv50_disp_chan(object); - struct nv50_disp *disp = chan->disp; - struct nvkm_device *device = disp->base.engine.subdev.device; - *data = nvkm_rd32(device, 0x640000 + (chan->chid.user * 0x1000) + addr); + struct nvkm_device *device = chan->disp->base.engine.subdev.device; + u64 size, base = chan->func->user(chan, &size); + *data = nvkm_rd32(device, base + addr); return 0; } @@ -169,9 +176,9 @@ static int nv50_disp_chan_wr32(struct nvkm_object *object, u64 addr, u32 data) { struct nv50_disp_chan *chan = nv50_disp_chan(object); - struct nv50_disp *disp = chan->disp; - struct nvkm_device *device = disp->base.engine.subdev.device; - nvkm_wr32(device, 0x640000 + (chan->chid.user * 0x1000) + addr, data); + struct nvkm_device *device = chan->disp->base.engine.subdev.device; + u64 size, base = chan->func->user(chan, &size); + nvkm_wr32(device, base + addr, data); return 0; } @@ -196,12 +203,10 @@ nv50_disp_chan_map(struct nvkm_object *object, void *argv, u32 argc, enum nvkm_object_map *type, u64 *addr, u64 *size) { struct nv50_disp_chan *chan = nv50_disp_chan(object); - struct nv50_disp *disp = chan->disp; - struct nvkm_device *device = disp->base.engine.subdev.device; + struct nvkm_device *device = chan->disp->base.engine.subdev.device; + const u64 base = device->func->resource_addr(device, 0); *type = NVKM_OBJECT_MAP_IO; - *addr = device->func->resource_addr(device, 0) + - 0x640000 + (chan->chid.user * 0x1000); - *size = 0x001000; + *addr = base + chan->func->user(chan, size); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h index feb8a56fcc858..75ae181da0e81 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h @@ -25,6 +25,7 @@ struct nv50_disp_chan { struct nv50_disp_chan_func { int (*init)(struct nv50_disp_chan *); void (*fini)(struct nv50_disp_chan *); + u64 (*user)(struct nv50_disp_chan *, u64 *size); int (*bind)(struct nv50_disp_chan *, struct nvkm_object *, u32 handle); }; @@ -37,6 +38,7 @@ int nv50_disp_dmac_new_(const struct nv50_disp_chan_func *, struct nv50_disp *, int chid, int head, u64 push, const struct nvkm_oclass *, struct nvkm_object **); +u64 nv50_disp_chan_user(struct nv50_disp_chan *, u64 *); extern const struct nv50_disp_chan_func nv50_disp_pioc_func; extern const struct nv50_disp_chan_func nv50_disp_dmac_func; int nv50_disp_dmac_bind(struct nv50_disp_chan *, struct nvkm_object *, u32); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c index 17c66162417bd..9ba4a8cd3dba2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c @@ -222,6 +222,7 @@ const struct nv50_disp_chan_func gf119_disp_core_func = { .init = gf119_disp_core_init, .fini = gf119_disp_core_fini, + .user = nv50_disp_chan_user, .bind = gf119_disp_dmac_bind, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c index 57d26051bc95b..aae5db4dc622e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c @@ -59,6 +59,7 @@ static const struct nv50_disp_chan_func gp102_disp_core_func = { .init = gp102_disp_core_init, .fini = gf119_disp_core_fini, + .user = nv50_disp_chan_user, .bind = gf119_disp_dmac_bind, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c index d648c4d7b55c5..5fd449d32109d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c @@ -224,6 +224,7 @@ const struct nv50_disp_chan_func nv50_disp_core_func = { .init = nv50_disp_core_init, .fini = nv50_disp_core_fini, + .user = nv50_disp_chan_user, .bind = nv50_disp_dmac_bind, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c index f69749a29df86..2a6d0728dd2e2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c @@ -95,5 +95,6 @@ const struct nv50_disp_chan_func gf119_disp_dmac_func = { .init = gf119_disp_dmac_init, .fini = gf119_disp_dmac_fini, + .user = nv50_disp_chan_user, .bind = gf119_disp_dmac_bind, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c index 22fa5925644a0..7e6b308eb596a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c @@ -61,5 +61,6 @@ const struct nv50_disp_chan_func gp102_disp_dmac_func = { .init = gp102_disp_dmac_init, .fini = gf119_disp_dmac_fini, + .user = nv50_disp_chan_user, .bind = gf119_disp_dmac_bind, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c index 5cd08cad2c269..5db26e31a799a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c @@ -137,5 +137,6 @@ const struct nv50_disp_chan_func nv50_disp_dmac_func = { .init = nv50_disp_dmac_init, .fini = nv50_disp_dmac_fini, + .user = nv50_disp_chan_user, .bind = nv50_disp_dmac_bind, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c index 7b1e9bf75abde..5970e40f4d69c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c @@ -80,4 +80,5 @@ const struct nv50_disp_chan_func gf119_disp_pioc_func = { .init = gf119_disp_pioc_init, .fini = gf119_disp_pioc_fini, + .user = nv50_disp_chan_user, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c index 60c20123d84fc..0a76bda4ef2a5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c @@ -82,4 +82,5 @@ const struct nv50_disp_chan_func nv50_disp_pioc_func = { .init = nv50_disp_pioc_init, .fini = nv50_disp_pioc_fini, + .user = nv50_disp_chan_user, }; From a9c44a88ca2f957c755bcb2ce8b9d2e031d65f64 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 023/165] drm/nouveau/disp/nv50-: add channel interfaces to control error interrupts This will be required to support Volta, but also allows us to remove code that's duplicated for each channel type already. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/disp/changf119.c | 13 +++++++++++++ drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c | 11 +++++++++++ drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h | 3 +++ .../gpu/drm/nouveau/nvkm/engine/disp/coregf119.c | 8 +------- .../gpu/drm/nouveau/nvkm/engine/disp/coregp102.c | 4 +--- drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c | 7 +------ .../gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c | 8 +------- .../gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c | 4 +--- drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c | 7 +------ .../gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c | 8 +------- drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c | 1 + 11 files changed, 35 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/changf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/changf119.c index 17a3d835cb424..29e6dd58ac48c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/changf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/changf119.c @@ -47,3 +47,16 @@ gf119_disp_chan_uevent = { .init = gf119_disp_chan_uevent_init, .fini = gf119_disp_chan_uevent_fini, }; + +void +gf119_disp_chan_intr(struct nv50_disp_chan *chan, bool en) +{ + struct nvkm_device *device = chan->disp->base.engine.subdev.device; + const u64 mask = 0x00000001 << chan->chid.user; + if (!en) { + nvkm_mask(device, 0x610090, mask, 0x00000000); + nvkm_mask(device, 0x6100a0, mask, 0x00000000); + } else { + nvkm_mask(device, 0x6100a0, mask, mask); + } +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c index 8e79aa5f52e69..53c3ed6da9aea 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c @@ -162,6 +162,15 @@ nv50_disp_chan_user(struct nv50_disp_chan *chan, u64 *psize) return 0x640000 + (chan->chid.user * 0x1000); } +void +nv50_disp_chan_intr(struct nv50_disp_chan *chan, bool en) +{ + struct nvkm_device *device = chan->disp->base.engine.subdev.device; + const u64 mask = 0x00010001 << chan->chid.user; + const u64 data = en ? 0x00010000 : 0x00000000; + nvkm_mask(device, 0x610028, mask, data); +} + static int nv50_disp_chan_rd32(struct nvkm_object *object, u64 addr, u32 *data) { @@ -288,6 +297,7 @@ nv50_disp_chan_fini(struct nvkm_object *object, bool suspend) { struct nv50_disp_chan *chan = nv50_disp_chan(object); chan->func->fini(chan); + chan->func->intr(chan, false); return 0; } @@ -295,6 +305,7 @@ static int nv50_disp_chan_init(struct nvkm_object *object) { struct nv50_disp_chan *chan = nv50_disp_chan(object); + chan->func->intr(chan, true); return chan->func->init(chan); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h index 75ae181da0e81..2a48243b00aea 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h @@ -25,6 +25,7 @@ struct nv50_disp_chan { struct nv50_disp_chan_func { int (*init)(struct nv50_disp_chan *); void (*fini)(struct nv50_disp_chan *); + void (*intr)(struct nv50_disp_chan *, bool en); u64 (*user)(struct nv50_disp_chan *, u64 *size); int (*bind)(struct nv50_disp_chan *, struct nvkm_object *, u32 handle); }; @@ -38,12 +39,14 @@ int nv50_disp_dmac_new_(const struct nv50_disp_chan_func *, struct nv50_disp *, int chid, int head, u64 push, const struct nvkm_oclass *, struct nvkm_object **); +void nv50_disp_chan_intr(struct nv50_disp_chan *, bool); u64 nv50_disp_chan_user(struct nv50_disp_chan *, u64 *); extern const struct nv50_disp_chan_func nv50_disp_pioc_func; extern const struct nv50_disp_chan_func nv50_disp_dmac_func; int nv50_disp_dmac_bind(struct nv50_disp_chan *, struct nvkm_object *, u32); extern const struct nv50_disp_chan_func nv50_disp_core_func; +void gf119_disp_chan_intr(struct nv50_disp_chan *, bool); extern const struct nv50_disp_chan_func gf119_disp_pioc_func; extern const struct nv50_disp_chan_func gf119_disp_dmac_func; void gf119_disp_dmac_fini(struct nv50_disp_chan *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c index 9ba4a8cd3dba2..d162b9cf4eac6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregf119.c @@ -182,10 +182,6 @@ gf119_disp_core_fini(struct nv50_disp_chan *chan) nvkm_error(subdev, "core fini: %08x\n", nvkm_rd32(device, 0x610490)); } - - /* disable error reporting and completion notification */ - nvkm_mask(device, 0x610090, 0x00000001, 0x00000000); - nvkm_mask(device, 0x6100a0, 0x00000001, 0x00000000); } static int @@ -194,9 +190,6 @@ gf119_disp_core_init(struct nv50_disp_chan *chan) struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; struct nvkm_device *device = subdev->device; - /* enable error reporting */ - nvkm_mask(device, 0x6100a0, 0x00000001, 0x00000001); - /* initialise channel for dma command submission */ nvkm_wr32(device, 0x610494, chan->push); nvkm_wr32(device, 0x610498, 0x00010000); @@ -222,6 +215,7 @@ const struct nv50_disp_chan_func gf119_disp_core_func = { .init = gf119_disp_core_init, .fini = gf119_disp_core_fini, + .intr = gf119_disp_chan_intr, .user = nv50_disp_chan_user, .bind = gf119_disp_dmac_bind, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c index aae5db4dc622e..5b7f993c73c73 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp102.c @@ -31,9 +31,6 @@ gp102_disp_core_init(struct nv50_disp_chan *chan) struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; struct nvkm_device *device = subdev->device; - /* enable error reporting */ - nvkm_mask(device, 0x6100a0, 0x00000001, 0x00000001); - /* initialise channel for dma command submission */ nvkm_wr32(device, 0x611494, chan->push); nvkm_wr32(device, 0x611498, 0x00010000); @@ -59,6 +56,7 @@ static const struct nv50_disp_chan_func gp102_disp_core_func = { .init = gp102_disp_core_init, .fini = gf119_disp_core_fini, + .intr = gf119_disp_chan_intr, .user = nv50_disp_chan_user, .bind = gf119_disp_dmac_bind, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c index 5fd449d32109d..55db9a22b4be4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/corenv50.c @@ -179,9 +179,6 @@ nv50_disp_core_fini(struct nv50_disp_chan *chan) nvkm_error(subdev, "core fini: %08x\n", nvkm_rd32(device, 0x610200)); } - - /* disable error reporting and completion notifications */ - nvkm_mask(device, 0x610028, 0x00010001, 0x00000000); } static int @@ -190,9 +187,6 @@ nv50_disp_core_init(struct nv50_disp_chan *chan) struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; struct nvkm_device *device = subdev->device; - /* enable error reporting */ - nvkm_mask(device, 0x610028, 0x00010000, 0x00010000); - /* attempt to unstick channel from some unknown state */ if ((nvkm_rd32(device, 0x610200) & 0x009f0000) == 0x00020000) nvkm_mask(device, 0x610200, 0x00800000, 0x00800000); @@ -224,6 +218,7 @@ const struct nv50_disp_chan_func nv50_disp_core_func = { .init = nv50_disp_core_init, .fini = nv50_disp_core_fini, + .intr = nv50_disp_chan_intr, .user = nv50_disp_chan_user, .bind = nv50_disp_dmac_bind, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c index 2a6d0728dd2e2..edf7dd0d931df 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c @@ -53,10 +53,6 @@ gf119_disp_dmac_fini(struct nv50_disp_chan *chan) nvkm_error(subdev, "ch %d fini: %08x\n", user, nvkm_rd32(device, 0x610490 + (ctrl * 0x10))); } - - /* disable error reporting and completion notification */ - nvkm_mask(device, 0x610090, 0x00000001 << user, 0x00000000); - nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000000); } static int @@ -67,9 +63,6 @@ gf119_disp_dmac_init(struct nv50_disp_chan *chan) int ctrl = chan->chid.ctrl; int user = chan->chid.user; - /* enable error reporting */ - nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user); - /* initialise channel for dma command submission */ nvkm_wr32(device, 0x610494 + (ctrl * 0x0010), chan->push); nvkm_wr32(device, 0x610498 + (ctrl * 0x0010), 0x00010000); @@ -95,6 +88,7 @@ const struct nv50_disp_chan_func gf119_disp_dmac_func = { .init = gf119_disp_dmac_init, .fini = gf119_disp_dmac_fini, + .intr = gf119_disp_chan_intr, .user = nv50_disp_chan_user, .bind = gf119_disp_dmac_bind, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c index 7e6b308eb596a..f21a433199aa0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp102.c @@ -33,9 +33,6 @@ gp102_disp_dmac_init(struct nv50_disp_chan *chan) int ctrl = chan->chid.ctrl; int user = chan->chid.user; - /* enable error reporting */ - nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user); - /* initialise channel for dma command submission */ nvkm_wr32(device, 0x611494 + (ctrl * 0x0010), chan->push); nvkm_wr32(device, 0x611498 + (ctrl * 0x0010), 0x00010000); @@ -61,6 +58,7 @@ const struct nv50_disp_chan_func gp102_disp_dmac_func = { .init = gp102_disp_dmac_init, .fini = gf119_disp_dmac_fini, + .intr = gf119_disp_chan_intr, .user = nv50_disp_chan_user, .bind = gf119_disp_dmac_bind, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c index 5db26e31a799a..981b98def151e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c @@ -96,9 +96,6 @@ nv50_disp_dmac_fini(struct nv50_disp_chan *chan) nvkm_error(subdev, "ch %d fini timeout, %08x\n", user, nvkm_rd32(device, 0x610200 + (ctrl * 0x10))); } - - /* disable error reporting and completion notifications */ - nvkm_mask(device, 0x610028, 0x00010001 << user, 0x00000000 << user); } static int @@ -109,9 +106,6 @@ nv50_disp_dmac_init(struct nv50_disp_chan *chan) int ctrl = chan->chid.ctrl; int user = chan->chid.user; - /* enable error reporting */ - nvkm_mask(device, 0x610028, 0x00010000 << user, 0x00010000 << user); - /* initialise channel for dma command submission */ nvkm_wr32(device, 0x610204 + (ctrl * 0x0010), chan->push); nvkm_wr32(device, 0x610208 + (ctrl * 0x0010), 0x00010000); @@ -137,6 +131,7 @@ const struct nv50_disp_chan_func nv50_disp_dmac_func = { .init = nv50_disp_dmac_init, .fini = nv50_disp_dmac_fini, + .intr = nv50_disp_chan_intr, .user = nv50_disp_chan_user, .bind = nv50_disp_dmac_bind, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c index 5970e40f4d69c..5296e7bee8133 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c @@ -43,10 +43,6 @@ gf119_disp_pioc_fini(struct nv50_disp_chan *chan) nvkm_error(subdev, "ch %d fini: %08x\n", user, nvkm_rd32(device, 0x610490 + (ctrl * 0x10))); } - - /* disable error reporting and completion notification */ - nvkm_mask(device, 0x610090, 0x00000001 << user, 0x00000000); - nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000000); } static int @@ -58,9 +54,6 @@ gf119_disp_pioc_init(struct nv50_disp_chan *chan) int ctrl = chan->chid.ctrl; int user = chan->chid.user; - /* enable error reporting */ - nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user); - /* activate channel */ nvkm_wr32(device, 0x610490 + (ctrl * 0x10), 0x00000001); if (nvkm_msec(device, 2000, @@ -80,5 +73,6 @@ const struct nv50_disp_chan_func gf119_disp_pioc_func = { .init = gf119_disp_pioc_init, .fini = gf119_disp_pioc_fini, + .intr = gf119_disp_chan_intr, .user = nv50_disp_chan_user, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c index 0a76bda4ef2a5..4faed6fce682b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c @@ -82,5 +82,6 @@ const struct nv50_disp_chan_func nv50_disp_pioc_func = { .init = nv50_disp_pioc_init, .fini = nv50_disp_pioc_fini, + .intr = nv50_disp_chan_intr, .user = nv50_disp_chan_user, }; From f5650478ab07c0921127a6a0735253b64073e978 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 024/165] drm/nouveau/disp/nv50-: pass nvkm_memory objects for channel push buffers Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/mem.h | 2 + drivers/gpu/drm/nouveau/include/nvif/mmu.h | 1 + drivers/gpu/drm/nouveau/nv50_display.c | 48 +++++++------------ drivers/gpu/drm/nouveau/nvif/mem.c | 13 +++++ drivers/gpu/drm/nouveau/nvif/mmu.c | 11 +++++ .../drm/nouveau/nvkm/engine/disp/channv50.c | 1 + .../drm/nouveau/nvkm/engine/disp/channv50.h | 1 + .../drm/nouveau/nvkm/engine/disp/dmacnv50.c | 22 ++++----- 8 files changed, 55 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvif/mem.h b/drivers/gpu/drm/nouveau/include/nvif/mem.h index b542fe38398ea..80ee4ab0f016b 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/mem.h +++ b/drivers/gpu/drm/nouveau/include/nvif/mem.h @@ -15,4 +15,6 @@ int nvif_mem_init_type(struct nvif_mmu *mmu, s32 oclass, int type, u8 page, int nvif_mem_init(struct nvif_mmu *mmu, s32 oclass, u8 type, u8 page, u64 size, void *argv, u32 argc, struct nvif_mem *); void nvif_mem_fini(struct nvif_mem *); + +int nvif_mem_init_map(struct nvif_mmu *, u8 type, u64 size, struct nvif_mem *); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/mmu.h b/drivers/gpu/drm/nouveau/include/nvif/mmu.h index c8cd5b5b06889..747ecf67e4038 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvif/mmu.h @@ -8,6 +8,7 @@ struct nvif_mmu { u8 heap_nr; u8 type_nr; u16 kind_nr; + s32 mem; struct { u64 size; diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 2b3ccd8507505..e90330e4e8c51 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -34,6 +34,8 @@ #include #include +#include + #include #include #include @@ -400,7 +402,8 @@ struct nv50_dmac_ctxdma { struct nv50_dmac { struct nv50_chan base; - dma_addr_t handle; + + struct nvif_mem push; u32 *ptr; struct nvif_object sync; @@ -482,9 +485,8 @@ nv50_dmac_ctxdma_new(struct nv50_dmac *dmac, struct nouveau_framebuffer *fb) } static void -nv50_dmac_destroy(struct nv50_dmac *dmac, struct nvif_object *disp) +nv50_dmac_destroy(struct nv50_dmac *dmac) { - struct nvif_device *device = dmac->base.device; struct nv50_dmac_ctxdma *ctxdma, *ctxtmp; list_for_each_entry_safe(ctxdma, ctxtmp, &dmac->ctxdma, head) { @@ -496,10 +498,7 @@ nv50_dmac_destroy(struct nv50_dmac *dmac, struct nvif_object *disp) nv50_chan_destroy(&dmac->base); - if (dmac->ptr) { - struct device *dev = nvxx_device(device)->dev; - dma_free_coherent(dev, PAGE_SIZE, dmac->ptr, dmac->handle); - } + nvif_mem_fini(&dmac->push); } static int @@ -507,33 +506,24 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, const s32 *oclass, u8 head, void *data, u32 size, u64 syncbuf, struct nv50_dmac *dmac) { + struct nouveau_cli *cli = (void *)device->object.client; struct nv50_disp_core_channel_dma_v0 *args = data; - struct nvif_object pushbuf; int ret; mutex_init(&dmac->lock); INIT_LIST_HEAD(&dmac->ctxdma); - dmac->ptr = dma_alloc_coherent(nvxx_device(device)->dev, PAGE_SIZE, - &dmac->handle, GFP_KERNEL); - if (!dmac->ptr) - return -ENOMEM; - - ret = nvif_object_init(&device->object, 0, NV_DMA_FROM_MEMORY, - &(struct nv_dma_v0) { - .target = NV_DMA_V0_TARGET_PCI_US, - .access = NV_DMA_V0_ACCESS_RD, - .start = dmac->handle + 0x0000, - .limit = dmac->handle + 0x0fff, - }, sizeof(struct nv_dma_v0), &pushbuf); + ret = nvif_mem_init_map(&cli->mmu, NVIF_MEM_COHERENT, 0x1000, + &dmac->push); if (ret) return ret; - args->pushbuf = nvif_handle(&pushbuf); + dmac->ptr = dmac->push.object.map.ptr; + + args->pushbuf = nvif_handle(&dmac->push.object); ret = nv50_chan_create(device, disp, oclass, head, data, size, &dmac->base); - nvif_object_fini(&pushbuf); if (ret) return ret; @@ -574,9 +564,7 @@ static int nv50_core_create(struct nvif_device *device, struct nvif_object *disp, u64 syncbuf, struct nv50_mast *core) { - struct nv50_disp_core_channel_dma_v0 args = { - .pushbuf = 0xb0007d00, - }; + struct nv50_disp_core_channel_dma_v0 args = {}; static const s32 oclass[] = { GP102_DISP_CORE_CHANNEL_DMA, GP100_DISP_CORE_CHANNEL_DMA, @@ -612,7 +600,6 @@ nv50_base_create(struct nvif_device *device, struct nvif_object *disp, int head, u64 syncbuf, struct nv50_sync *base) { struct nv50_disp_base_channel_dma_v0 args = { - .pushbuf = 0xb0007c00 | head, .head = head, }; static const s32 oclass[] = { @@ -643,7 +630,6 @@ nv50_ovly_create(struct nvif_device *device, struct nvif_object *disp, int head, u64 syncbuf, struct nv50_ovly *ovly) { struct nv50_disp_overlay_channel_dma_v0 args = { - .pushbuf = 0xb0007e00 | head, .head = head, }; static const s32 oclass[] = { @@ -1472,9 +1458,8 @@ nv50_base_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, static void * nv50_base_dtor(struct nv50_wndw *wndw) { - struct nv50_disp *disp = nv50_disp(wndw->plane.dev); struct nv50_base *base = nv50_base(wndw); - nv50_dmac_destroy(&base->chan.base, disp->disp); + nv50_dmac_destroy(&base->chan.base); return base; } @@ -2354,11 +2339,10 @@ nv50_head_reset(struct drm_crtc *crtc) static void nv50_head_destroy(struct drm_crtc *crtc) { - struct nv50_disp *disp = nv50_disp(crtc->dev); struct nv50_head *head = nv50_head(crtc); int i; - nv50_dmac_destroy(&head->ovly.base, disp->disp); + nv50_dmac_destroy(&head->ovly.base); nv50_pioc_destroy(&head->oimm.base); for (i = 0; i < ARRAY_SIZE(head->lut.nvbo); i++) @@ -4430,7 +4414,7 @@ nv50_display_destroy(struct drm_device *dev) { struct nv50_disp *disp = nv50_disp(dev); - nv50_dmac_destroy(&disp->mast.base, disp->disp); + nv50_dmac_destroy(&disp->mast.base); nouveau_bo_unmap(disp->sync); if (disp->sync) diff --git a/drivers/gpu/drm/nouveau/nvif/mem.c b/drivers/gpu/drm/nouveau/nvif/mem.c index 0f9382c601458..b6ebb3b586732 100644 --- a/drivers/gpu/drm/nouveau/nvif/mem.c +++ b/drivers/gpu/drm/nouveau/nvif/mem.c @@ -24,6 +24,19 @@ #include +int +nvif_mem_init_map(struct nvif_mmu *mmu, u8 type, u64 size, struct nvif_mem *mem) +{ + int ret = nvif_mem_init(mmu, mmu->mem, NVIF_MEM_MAPPABLE | type, 0, + size, NULL, 0, mem); + if (ret == 0) { + ret = nvif_object_map(&mem->object, NULL, 0); + if (ret) + nvif_mem_fini(mem); + } + return ret; +} + void nvif_mem_fini(struct nvif_mem *mem) { diff --git a/drivers/gpu/drm/nouveau/nvif/mmu.c b/drivers/gpu/drm/nouveau/nvif/mmu.c index 15d0dcbf7ab41..358ac4f3cf91d 100644 --- a/drivers/gpu/drm/nouveau/nvif/mmu.c +++ b/drivers/gpu/drm/nouveau/nvif/mmu.c @@ -36,6 +36,12 @@ nvif_mmu_fini(struct nvif_mmu *mmu) int nvif_mmu_init(struct nvif_object *parent, s32 oclass, struct nvif_mmu *mmu) { + static const struct nvif_mclass mems[] = { + { NVIF_CLASS_MEM_GF100, -1 }, + { NVIF_CLASS_MEM_NV50 , -1 }, + { NVIF_CLASS_MEM_NV04 , -1 }, + {} + }; struct nvif_mmu_v0 args; int ret, i; @@ -54,6 +60,11 @@ nvif_mmu_init(struct nvif_object *parent, s32 oclass, struct nvif_mmu *mmu) mmu->type_nr = args.type_nr; mmu->kind_nr = args.kind_nr; + ret = nvif_mclass(&mmu->object, mems); + if (ret < 0) + goto done; + mmu->mem = mems[ret].oclass; + mmu->heap = kmalloc(sizeof(*mmu->heap) * mmu->heap_nr, GFP_KERNEL); mmu->type = kmalloc(sizeof(*mmu->type) * mmu->type_nr, GFP_KERNEL); if (ret = -ENOMEM, !mmu->heap || !mmu->type) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c index 53c3ed6da9aea..57719f675eec9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c @@ -316,6 +316,7 @@ nv50_disp_chan_dtor(struct nvkm_object *object) struct nv50_disp *disp = chan->disp; if (chan->chid.user >= 0) disp->chan[chan->chid.user] = NULL; + nvkm_memory_unref(&chan->memory); return chan; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h index 2a48243b00aea..391b007a68243 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h @@ -19,6 +19,7 @@ struct nv50_disp_chan { struct nvkm_object object; + struct nvkm_memory *memory; u64 push; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c index 981b98def151e..9e8a9d7a9b68b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -37,7 +38,6 @@ nv50_disp_dmac_new_(const struct nv50_disp_chan_func *func, struct nvkm_object **pobject) { struct nvkm_client *client = oclass->client; - struct nvkm_dmaobj *dmaobj; struct nv50_disp_chan *chan; int ret; @@ -47,24 +47,22 @@ nv50_disp_dmac_new_(const struct nv50_disp_chan_func *func, if (ret) return ret; - dmaobj = nvkm_dmaobj_search(client, push); - if (IS_ERR(dmaobj)) - return PTR_ERR(dmaobj); + chan->memory = nvkm_umem_search(client, push); + if (IS_ERR(chan->memory)) + return PTR_ERR(chan->memory); - if (dmaobj->limit - dmaobj->start != 0xfff) + if (nvkm_memory_size(chan->memory) < 0x1000) return -EINVAL; - switch (dmaobj->target) { - case NV_MEM_TARGET_VRAM: - chan->push = 0x00000001 | dmaobj->start >> 8; - break; - case NV_MEM_TARGET_PCI_NOSNOOP: - chan->push = 0x00000003 | dmaobj->start >> 8; - break; + switch (nvkm_memory_target(chan->memory)) { + case NVKM_MEM_TARGET_VRAM: chan->push = 0x00000001; break; + case NVKM_MEM_TARGET_NCOH: chan->push = 0x00000002; break; + case NVKM_MEM_TARGET_HOST: chan->push = 0x00000003; break; default: return -EINVAL; } + chan->push |= nvkm_memory_addr(chan->memory) >> 8; return 0; } From c5c9127b25b2946369877d16b3c208cf54d4bf54 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 025/165] drm/nouveau/device: implement a generic method to query device-specific properties We have a need to fetch data from GPU-specific sub-devices that is not tied to any particular engine object. This commit provides the framework to support such queries. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/cl0080.h | 16 +++++++ .../drm/nouveau/include/nvkm/core/engine.h | 1 + .../drm/nouveau/include/nvkm/core/subdev.h | 2 + drivers/gpu/drm/nouveau/nvkm/core/engine.c | 15 ++++++ drivers/gpu/drm/nouveau/nvkm/core/subdev.c | 8 ++++ .../gpu/drm/nouveau/nvkm/engine/device/user.c | 47 ++++++++++++++++++- 6 files changed, 88 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl0080.h b/drivers/gpu/drm/nouveau/include/nvif/cl0080.h index 2740278d226b9..51a4af6a77eba 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/cl0080.h +++ b/drivers/gpu/drm/nouveau/include/nvif/cl0080.h @@ -39,9 +39,25 @@ struct nv_device_info_v0 { char name[64]; }; +struct nv_device_info_v1 { + __u8 version; + __u8 count; + __u8 pad02[6]; + struct nv_device_info_v1_data { + __u64 mthd; /* NV_DEVICE_INFO_* (see below). */ + __u64 data; + } data[]; +}; + struct nv_device_time_v0 { __u8 version; __u8 pad01[7]; __u64 time; }; + +#define NV_DEVICE_INFO_UNIT (0xffffffffULL << 32) +#define NV_DEVICE_INFO(n) ((n) | (0x00000000ULL << 32)) + +/* This will be returned for unsupported queries. */ +#define NV_DEVICE_INFO_INVALID ~0ULL #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h b/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h index ebf8473a39fe8..8a2be5b635e22 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h @@ -18,6 +18,7 @@ struct nvkm_engine_func { void *(*dtor)(struct nvkm_engine *); void (*preinit)(struct nvkm_engine *); int (*oneinit)(struct nvkm_engine *); + int (*info)(struct nvkm_engine *, u64 mthd, u64 *data); int (*init)(struct nvkm_engine *); int (*fini)(struct nvkm_engine *, bool suspend); void (*intr)(struct nvkm_engine *); diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h index 63df2290177f3..85a0777c2ce44 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h @@ -17,6 +17,7 @@ struct nvkm_subdev_func { void *(*dtor)(struct nvkm_subdev *); int (*preinit)(struct nvkm_subdev *); int (*oneinit)(struct nvkm_subdev *); + int (*info)(struct nvkm_subdev *, u64 mthd, u64 *data); int (*init)(struct nvkm_subdev *); int (*fini)(struct nvkm_subdev *, bool suspend); void (*intr)(struct nvkm_subdev *); @@ -29,6 +30,7 @@ void nvkm_subdev_del(struct nvkm_subdev **); int nvkm_subdev_preinit(struct nvkm_subdev *); int nvkm_subdev_init(struct nvkm_subdev *); int nvkm_subdev_fini(struct nvkm_subdev *, bool suspend); +int nvkm_subdev_info(struct nvkm_subdev *, u64, u64 *); void nvkm_subdev_intr(struct nvkm_subdev *); /* subdev logging */ diff --git a/drivers/gpu/drm/nouveau/nvkm/core/engine.c b/drivers/gpu/drm/nouveau/nvkm/core/engine.c index 657231c3c098a..d0322ce85172a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/engine.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/engine.c @@ -82,6 +82,20 @@ nvkm_engine_intr(struct nvkm_subdev *subdev) engine->func->intr(engine); } +static int +nvkm_engine_info(struct nvkm_subdev *subdev, u64 mthd, u64 *data) +{ + struct nvkm_engine *engine = nvkm_engine(subdev); + if (engine->func->info) { + if ((engine = nvkm_engine_ref(engine))) { + int ret = engine->func->info(engine, mthd, data); + nvkm_engine_unref(&engine); + return ret; + } + } + return -ENOSYS; +} + static int nvkm_engine_fini(struct nvkm_subdev *subdev, bool suspend) { @@ -150,6 +164,7 @@ nvkm_engine_func = { .preinit = nvkm_engine_preinit, .init = nvkm_engine_init, .fini = nvkm_engine_fini, + .info = nvkm_engine_info, .intr = nvkm_engine_intr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c index c707306ac286f..b96f9e2f237a2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c @@ -92,6 +92,14 @@ nvkm_subdev_intr(struct nvkm_subdev *subdev) subdev->func->intr(subdev); } +int +nvkm_subdev_info(struct nvkm_subdev *subdev, u64 mthd, u64 *data) +{ + if (subdev->func->info) + return subdev->func->info(subdev, mthd, data); + return -ENOSYS; +} + int nvkm_subdev_fini(struct nvkm_subdev *subdev, bool suspend) { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c index 17adcb4e8854a..3526516765f8d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c @@ -39,6 +39,40 @@ struct nvkm_udevice { struct nvkm_device *device; }; +static int +nvkm_udevice_info_subdev(struct nvkm_device *device, u64 mthd, u64 *data) +{ + struct nvkm_subdev *subdev; + enum nvkm_devidx subidx; + + switch (mthd & NV_DEVICE_INFO_UNIT) { + default: + return -EINVAL; + } + + subdev = nvkm_device_subdev(device, subidx); + if (subdev) + return nvkm_subdev_info(subdev, mthd, data); + return -ENODEV; +} + +static void +nvkm_udevice_info_v1(struct nvkm_device *device, + struct nv_device_info_v1_data *args) +{ + if (args->mthd & NV_DEVICE_INFO_UNIT) { + if (nvkm_udevice_info_subdev(device, args->mthd, &args->data)) + args->mthd = NV_DEVICE_INFO_INVALID; + return; + } + + switch (args->mthd) { + default: + args->mthd = NV_DEVICE_INFO_INVALID; + break; + } +} + static int nvkm_udevice_info(struct nvkm_udevice *udev, void *data, u32 size) { @@ -48,10 +82,21 @@ nvkm_udevice_info(struct nvkm_udevice *udev, void *data, u32 size) struct nvkm_instmem *imem = device->imem; union { struct nv_device_info_v0 v0; + struct nv_device_info_v1 v1; } *args = data; - int ret = -ENOSYS; + int ret = -ENOSYS, i; nvif_ioctl(object, "device info size %d\n", size); + if (!(ret = nvif_unpack(ret, &data, &size, args->v1, 1, 1, true))) { + nvif_ioctl(object, "device info vers %d count %d\n", + args->v1.version, args->v1.count); + if (args->v1.count * sizeof(args->v1.data[0]) == size) { + for (i = 0; i < args->v1.count; i++) + nvkm_udevice_info_v1(device, &args->v1.data[i]); + return 0; + } + return -EINVAL; + } else if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { nvif_ioctl(object, "device info vers %d\n", args->v0.version); } else From 6eb01aa8988873167adc5285f4afef310d01b8fb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 026/165] drm/nouveau/device: support querying available engines of a specific type Will be used for fifo runlist selection. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/cl0080.h | 19 ++++++++++++++ .../gpu/drm/nouveau/nvkm/engine/device/user.c | 25 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl0080.h b/drivers/gpu/drm/nouveau/include/nvif/cl0080.h index 51a4af6a77eba..6a54cda9613ec 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/cl0080.h +++ b/drivers/gpu/drm/nouveau/include/nvif/cl0080.h @@ -60,4 +60,23 @@ struct nv_device_time_v0 { /* This will be returned for unsupported queries. */ #define NV_DEVICE_INFO_INVALID ~0ULL + +/* These return a mask of available engines of particular type. */ +#define NV_DEVICE_INFO_ENGINE_SW NV_DEVICE_INFO(0x00000000) +#define NV_DEVICE_INFO_ENGINE_GR NV_DEVICE_INFO(0x00000001) +#define NV_DEVICE_INFO_ENGINE_MPEG NV_DEVICE_INFO(0x00000002) +#define NV_DEVICE_INFO_ENGINE_ME NV_DEVICE_INFO(0x00000003) +#define NV_DEVICE_INFO_ENGINE_CIPHER NV_DEVICE_INFO(0x00000004) +#define NV_DEVICE_INFO_ENGINE_BSP NV_DEVICE_INFO(0x00000005) +#define NV_DEVICE_INFO_ENGINE_VP NV_DEVICE_INFO(0x00000006) +#define NV_DEVICE_INFO_ENGINE_CE NV_DEVICE_INFO(0x00000007) +#define NV_DEVICE_INFO_ENGINE_SEC NV_DEVICE_INFO(0x00000008) +#define NV_DEVICE_INFO_ENGINE_MSVLD NV_DEVICE_INFO(0x00000009) +#define NV_DEVICE_INFO_ENGINE_MSPDEC NV_DEVICE_INFO(0x0000000a) +#define NV_DEVICE_INFO_ENGINE_MSPPP NV_DEVICE_INFO(0x0000000b) +#define NV_DEVICE_INFO_ENGINE_MSENC NV_DEVICE_INFO(0x0000000c) +#define NV_DEVICE_INFO_ENGINE_VIC NV_DEVICE_INFO(0x0000000d) +#define NV_DEVICE_INFO_ENGINE_SEC2 NV_DEVICE_INFO(0x0000000e) +#define NV_DEVICE_INFO_ENGINE_NVDEC NV_DEVICE_INFO(0x0000000f) +#define NV_DEVICE_INFO_ENGINE_NVENC NV_DEVICE_INFO(0x00000010) #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c index 3526516765f8d..42a552d314ef3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c @@ -67,6 +67,31 @@ nvkm_udevice_info_v1(struct nvkm_device *device, } switch (args->mthd) { +#define ENGINE__(A,B,C) NV_DEVICE_INFO_ENGINE_##A: { int _i; \ + for (_i = (B), args->data = 0ULL; _i <= (C); _i++) { \ + if (nvkm_device_engine(device, _i)) \ + args->data |= BIT_ULL(_i); \ + } \ +} +#define ENGINE_A(A) ENGINE__(A, NVKM_ENGINE_##A , NVKM_ENGINE_##A) +#define ENGINE_B(A) ENGINE__(A, NVKM_ENGINE_##A##0, NVKM_ENGINE_##A##_LAST) + case ENGINE_A(SW ); break; + case ENGINE_A(GR ); break; + case ENGINE_A(MPEG ); break; + case ENGINE_A(ME ); break; + case ENGINE_A(CIPHER); break; + case ENGINE_A(BSP ); break; + case ENGINE_A(VP ); break; + case ENGINE_B(CE ); break; + case ENGINE_A(SEC ); break; + case ENGINE_A(MSVLD ); break; + case ENGINE_A(MSPDEC); break; + case ENGINE_A(MSPPP ); break; + case ENGINE_A(MSENC ); break; + case ENGINE_A(VIC ); break; + case ENGINE_A(SEC2 ); break; + case ENGINE_A(NVDEC ); break; + case ENGINE_B(NVENC ); break; default: args->mthd = NV_DEVICE_INFO_INVALID; break; From eb47db4f3bb58b0143a911b29417e89f28e1b0c8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 027/165] drm/nouveau/fifo: support channel count query Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/cl0080.h | 4 +++ drivers/gpu/drm/nouveau/include/nvif/device.h | 1 - drivers/gpu/drm/nouveau/nouveau_chan.c | 25 +++++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_chan.h | 1 + drivers/gpu/drm/nouveau/nouveau_drm.c | 4 +++ drivers/gpu/drm/nouveau/nouveau_drv.h | 6 +++++ drivers/gpu/drm/nouveau/nouveau_fence.c | 11 ++++---- drivers/gpu/drm/nouveau/nouveau_fence.h | 2 -- drivers/gpu/drm/nouveau/nv04_fence.c | 2 -- 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 | 11 +++----- .../gpu/drm/nouveau/nvkm/engine/device/user.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/base.c | 14 +++++++++++ 15 files changed, 64 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl0080.h b/drivers/gpu/drm/nouveau/include/nvif/cl0080.h index 6a54cda9613ec..5af610ea260e8 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/cl0080.h +++ b/drivers/gpu/drm/nouveau/include/nvif/cl0080.h @@ -57,6 +57,7 @@ struct nv_device_time_v0 { #define NV_DEVICE_INFO_UNIT (0xffffffffULL << 32) #define NV_DEVICE_INFO(n) ((n) | (0x00000000ULL << 32)) +#define NV_DEVICE_FIFO(n) ((n) | (0x00000001ULL << 32)) /* This will be returned for unsupported queries. */ #define NV_DEVICE_INFO_INVALID ~0ULL @@ -79,4 +80,7 @@ struct nv_device_time_v0 { #define NV_DEVICE_INFO_ENGINE_SEC2 NV_DEVICE_INFO(0x0000000e) #define NV_DEVICE_INFO_ENGINE_NVDEC NV_DEVICE_INFO(0x0000000f) #define NV_DEVICE_INFO_ENGINE_NVENC NV_DEVICE_INFO(0x00000010) + +/* Returns the number of available channels. */ +#define NV_DEVICE_FIFO_CHANNELS NV_DEVICE_FIFO(0x00000000) #endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/device.h b/drivers/gpu/drm/nouveau/include/nvif/device.h index 6edb6266857e4..216dbd9fa6168 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/device.h +++ b/drivers/gpu/drm/nouveau/include/nvif/device.h @@ -67,6 +67,5 @@ u64 nvif_device_time(struct nvif_device *); #include #include -#define nvxx_fifo(a) nvxx_device(a)->fifo #define nvxx_gr(a) nvxx_device(a)->gr #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index af1116655910c..db69d13f32a71 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -474,3 +474,28 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device, cli->base.super = super; return ret; } + +int +nouveau_channels_init(struct nouveau_drm *drm) +{ + struct { + struct nv_device_info_v1 m; + struct { + struct nv_device_info_v1_data channels; + } v; + } args = { + .m.version = 1, + .m.count = sizeof(args.v) / sizeof(args.v.channels), + .v.channels.mthd = NV_DEVICE_FIFO_CHANNELS, + }; + struct nvif_object *device = &drm->client.device.object; + int ret; + + ret = nvif_object_mthd(device, NV_DEVICE_V0_INFO, &args, sizeof(args)); + if (ret || args.v.channels.mthd == NV_DEVICE_INFO_INVALID) + return -ENODEV; + + drm->chan.nr = args.v.channels.data; + drm->chan.context_base = dma_fence_context_alloc(drm->chan.nr); + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.h b/drivers/gpu/drm/nouveau/nouveau_chan.h index 14607c16a2bd6..64454c2ebd908 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.h +++ b/drivers/gpu/drm/nouveau/nouveau_chan.h @@ -45,6 +45,7 @@ struct nouveau_channel { atomic_t killed; }; +int nouveau_channels_init(struct nouveau_drm *); int nouveau_channel_new(struct nouveau_drm *, struct nvif_device *, u32 arg0, u32 arg1, struct nouveau_channel **); diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index bbbf353682e1c..dddd42592472f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -307,6 +307,10 @@ nouveau_accel_init(struct nouveau_drm *drm) if (nouveau_noaccel) return; + ret = nouveau_channels_init(drm); + if (ret) + return; + /* initialise synchronisation routines */ /*XXX: this is crap, but the fence/channel stuff is a little * backwards in some places. this will be fixed. diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 881b44b89a018..6e1acaec34003 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -170,6 +170,12 @@ struct nouveau_drm { /* synchronisation */ void *fence; + /* Global channel management. */ + struct { + int nr; + u64 context_base; + } chan; + /* context for accelerated drm-internal operations */ struct nouveau_channel *cechan; struct nouveau_channel *channel; diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 503fa94dc06db..412d49bc6e560 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -74,15 +74,14 @@ nouveau_fence_signal(struct nouveau_fence *fence) } static struct nouveau_fence * -nouveau_local_fence(struct dma_fence *fence, struct nouveau_drm *drm) { - struct nouveau_fence_priv *priv = (void*)drm->fence; - +nouveau_local_fence(struct dma_fence *fence, struct nouveau_drm *drm) +{ if (fence->ops != &nouveau_fence_ops_legacy && fence->ops != &nouveau_fence_ops_uevent) return NULL; - if (fence->context < priv->context_base || - fence->context >= priv->context_base + priv->contexts) + if (fence->context < drm->chan.context_base || + fence->context >= drm->chan.context_base + drm->chan.nr) return NULL; return from_fence(fence); @@ -176,7 +175,7 @@ nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_cha INIT_LIST_HEAD(&fctx->flip); INIT_LIST_HEAD(&fctx->pending); spin_lock_init(&fctx->lock); - fctx->context = priv->context_base + chan->chid; + fctx->context = chan->drm->chan.context_base + chan->chid; if (chan == chan->drm->cechan) strcpy(fctx->name, "copy engine channel"); diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h index 5bd8d30d16570..b999e60580460 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.h +++ b/drivers/gpu/drm/nouveau/nouveau_fence.h @@ -55,8 +55,6 @@ struct nouveau_fence_priv { int (*context_new)(struct nouveau_channel *); void (*context_del)(struct nouveau_channel *); - u32 contexts; - u64 context_base; bool uevent; }; diff --git a/drivers/gpu/drm/nouveau/nv04_fence.c b/drivers/gpu/drm/nouveau/nv04_fence.c index fa8f2375c398e..c41e82be48937 100644 --- a/drivers/gpu/drm/nouveau/nv04_fence.c +++ b/drivers/gpu/drm/nouveau/nv04_fence.c @@ -109,7 +109,5 @@ nv04_fence_create(struct nouveau_drm *drm) priv->base.dtor = nv04_fence_destroy; priv->base.context_new = nv04_fence_context_new; priv->base.context_del = nv04_fence_context_del; - priv->base.contexts = 15; - priv->base.context_base = dma_fence_context_alloc(priv->base.contexts); return 0; } diff --git a/drivers/gpu/drm/nouveau/nv10_fence.c b/drivers/gpu/drm/nouveau/nv10_fence.c index 2998bde292112..4476b712dc841 100644 --- a/drivers/gpu/drm/nouveau/nv10_fence.c +++ b/drivers/gpu/drm/nouveau/nv10_fence.c @@ -103,8 +103,6 @@ nv10_fence_create(struct nouveau_drm *drm) priv->base.dtor = nv10_fence_destroy; priv->base.context_new = nv10_fence_context_new; priv->base.context_del = nv10_fence_context_del; - priv->base.contexts = 31; - priv->base.context_base = dma_fence_context_alloc(priv->base.contexts); spin_lock_init(&priv->lock); return 0; } diff --git a/drivers/gpu/drm/nouveau/nv17_fence.c b/drivers/gpu/drm/nouveau/nv17_fence.c index 6477b7069e144..5d613d43b84d2 100644 --- a/drivers/gpu/drm/nouveau/nv17_fence.c +++ b/drivers/gpu/drm/nouveau/nv17_fence.c @@ -125,8 +125,6 @@ nv17_fence_create(struct nouveau_drm *drm) priv->base.resume = nv17_fence_resume; priv->base.context_new = nv17_fence_context_new; priv->base.context_del = nv10_fence_context_del; - priv->base.contexts = 31; - priv->base.context_base = dma_fence_context_alloc(priv->base.contexts); spin_lock_init(&priv->lock); ret = nouveau_bo_new(&drm->client, 4096, 0x1000, TTM_PL_FLAG_VRAM, diff --git a/drivers/gpu/drm/nouveau/nv50_fence.c b/drivers/gpu/drm/nouveau/nv50_fence.c index a369d978e267f..a00ecc3de0535 100644 --- a/drivers/gpu/drm/nouveau/nv50_fence.c +++ b/drivers/gpu/drm/nouveau/nv50_fence.c @@ -78,8 +78,6 @@ nv50_fence_create(struct nouveau_drm *drm) priv->base.resume = nv17_fence_resume; priv->base.context_new = nv50_fence_context_new; priv->base.context_del = nv10_fence_context_del; - priv->base.contexts = 127; - priv->base.context_base = dma_fence_context_alloc(priv->base.contexts); spin_lock_init(&priv->lock); ret = nouveau_bo_new(&drm->client, 4096, 0x1000, TTM_PL_FLAG_VRAM, diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c index 5f0c0c27d5dcf..090664899247a 100644 --- a/drivers/gpu/drm/nouveau/nv84_fence.c +++ b/drivers/gpu/drm/nouveau/nv84_fence.c @@ -141,9 +141,9 @@ nv84_fence_suspend(struct nouveau_drm *drm) struct nv84_fence_priv *priv = drm->fence; int i; - priv->suspend = vmalloc(priv->base.contexts * sizeof(u32)); + priv->suspend = vmalloc(drm->chan.nr * sizeof(u32)); if (priv->suspend) { - for (i = 0; i < priv->base.contexts; i++) + for (i = 0; i < drm->chan.nr; i++) priv->suspend[i] = nouveau_bo_rd32(priv->bo, i*4); } @@ -157,7 +157,7 @@ nv84_fence_resume(struct nouveau_drm *drm) int i; if (priv->suspend) { - for (i = 0; i < priv->base.contexts; i++) + for (i = 0; i < drm->chan.nr; i++) nouveau_bo_wr32(priv->bo, i*4, priv->suspend[i]); vfree(priv->suspend); priv->suspend = NULL; @@ -179,7 +179,6 @@ nv84_fence_destroy(struct nouveau_drm *drm) int nv84_fence_create(struct nouveau_drm *drm) { - struct nvkm_fifo *fifo = nvxx_fifo(&drm->client.device); struct nv84_fence_priv *priv; u32 domain; int ret; @@ -194,8 +193,6 @@ nv84_fence_create(struct nouveau_drm *drm) priv->base.context_new = nv84_fence_context_new; priv->base.context_del = nv84_fence_context_del; - priv->base.contexts = fifo->nr; - priv->base.context_base = dma_fence_context_alloc(priv->base.contexts); priv->base.uevent = true; mutex_init(&priv->mutex); @@ -207,7 +204,7 @@ nv84_fence_create(struct nouveau_drm *drm) * will lose CPU/GPU coherency! */ TTM_PL_FLAG_TT | TTM_PL_FLAG_UNCACHED; - ret = nouveau_bo_new(&drm->client, 16 * priv->base.contexts, 0, + ret = nouveau_bo_new(&drm->client, 16 * drm->chan.nr, 0, domain, 0, 0, NULL, NULL, &priv->bo); if (ret == 0) { ret = nouveau_bo_pin(priv->bo, domain, false); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c index 42a552d314ef3..600bdb8704627 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c @@ -46,6 +46,7 @@ nvkm_udevice_info_subdev(struct nvkm_device *device, u64 mthd, u64 *data) enum nvkm_devidx subidx; switch (mthd & NV_DEVICE_INFO_UNIT) { + case NV_DEVICE_FIFO(0): subidx = NVKM_ENGINE_FIFO; break; default: return -EINVAL; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c index 64f6b7654a08d..49b37a8a94b7d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c @@ -30,6 +30,7 @@ #include #include +#include #include void @@ -270,6 +271,18 @@ nvkm_fifo_fini(struct nvkm_engine *engine, bool suspend) return 0; } +static int +nvkm_fifo_info(struct nvkm_engine *engine, u64 mthd, u64 *data) +{ + struct nvkm_fifo *fifo = nvkm_fifo(engine); + switch (mthd) { + case NV_DEVICE_FIFO_CHANNELS: *data = fifo->nr; return 0; + default: + break; + } + return -ENOSYS; +} + static int nvkm_fifo_oneinit(struct nvkm_engine *engine) { @@ -311,6 +324,7 @@ nvkm_fifo = { .dtor = nvkm_fifo_dtor, .preinit = nvkm_fifo_preinit, .oneinit = nvkm_fifo_oneinit, + .info = nvkm_fifo_info, .init = nvkm_fifo_init, .fini = nvkm_fifo_fini, .intr = nvkm_fifo_intr, From 55b8e85b0b83150a20b17068e3229e64bd174d45 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 028/165] drm/nouveau/fifo/gk104-: accept engine contexts for CE3 and up These can exist on GP100 and newer. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c index 80c87521bebee..68461993394f1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c @@ -62,9 +62,8 @@ gk104_fifo_gpfifo_engine_addr(struct nvkm_engine *engine) { switch (engine->subdev.index) { case NVKM_ENGINE_SW : - case NVKM_ENGINE_CE0 : - case NVKM_ENGINE_CE1 : - case NVKM_ENGINE_CE2 : return 0x0000; + case NVKM_ENGINE_CE0...NVKM_ENGINE_CE_LAST: + return 0; case NVKM_ENGINE_GR : return 0x0210; case NVKM_ENGINE_SEC : return 0x0220; case NVKM_ENGINE_MSPDEC: return 0x0250; From ddc669e25645b32158cc2b6da26faf5dac92fffc Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 029/165] drm/nouveau/fifo/gk104-: allow fault recovery code to be called by other subdevs This will be required to support Volta. Signed-off-by: Ben Skeggs --- .../drm/nouveau/include/nvkm/engine/fifo.h | 2 + .../drm/nouveau/include/nvkm/subdev/fault.h | 13 ++ .../gpu/drm/nouveau/nvkm/engine/fifo/base.c | 6 + .../gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 191 ++++++++++-------- .../gpu/drm/nouveau/nvkm/engine/fifo/gk104.h | 21 +- .../gpu/drm/nouveau/nvkm/engine/fifo/gk110.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/gk208.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/gm107.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/gm200.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/gp100.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/priv.h | 1 + 14 files changed, 141 insertions(+), 101 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h index c17b3a9bf8fbc..0d96edee1e6a4 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h @@ -4,6 +4,7 @@ #include #include #include +struct nvkm_fault_data; #define NVKM_FIFO_CHID_NR 4096 @@ -45,6 +46,7 @@ struct nvkm_fifo { struct nvkm_event kevent; /* channel killed */ }; +void nvkm_fifo_fault(struct nvkm_fifo *, struct nvkm_fault_data *); void nvkm_fifo_pause(struct nvkm_fifo *, unsigned long *); void nvkm_fifo_start(struct nvkm_fifo *, unsigned long *); diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h index 8ca66e5727796..8e9bc30fe65dc 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h @@ -12,5 +12,18 @@ struct nvkm_fault { struct nvkm_event event; }; +struct nvkm_fault_data { + u64 addr; + u64 inst; + u64 time; + u8 engine; + u8 valid; + u8 gpc; + u8 hub; + u8 access; + u8 client; + u8 reason; +}; + int gp100_fault_new(struct nvkm_device *, int, struct nvkm_fault **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c index 49b37a8a94b7d..ed56087b4abe2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c @@ -56,6 +56,12 @@ nvkm_fifo_start(struct nvkm_fifo *fifo, unsigned long *flags) return fifo->func->start(fifo, flags); } +void +nvkm_fifo_fault(struct nvkm_fifo *fifo, struct nvkm_fault_data *info) +{ + return fifo->func->fault(fifo, info); +} + void nvkm_fifo_chan_put(struct nvkm_fifo *fifo, unsigned long flags, struct nvkm_fifo_chan **pchan) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index 84bd703dd8971..b5706b15a64d9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -347,6 +348,90 @@ gk104_fifo_recover_engn(struct gk104_fifo *fifo, int engn) schedule_work(&fifo->recover.work); } +static void +gk104_fifo_fault(struct nvkm_fifo *base, struct nvkm_fault_data *info) +{ + struct gk104_fifo *fifo = gk104_fifo(base); + struct nvkm_subdev *subdev = &fifo->base.engine.subdev; + struct nvkm_device *device = subdev->device; + const struct nvkm_enum *er, *ee, *ec, *ea; + struct nvkm_engine *engine = NULL; + struct nvkm_fifo_chan *chan; + unsigned long flags; + char ct[8] = "HUB/", en[16] = ""; + int engn; + + er = nvkm_enum_find(fifo->func->fault.reason, info->reason); + ee = nvkm_enum_find(fifo->func->fault.engine, info->engine); + if (info->hub) { + ec = nvkm_enum_find(fifo->func->fault.hubclient, info->client); + } else { + ec = nvkm_enum_find(fifo->func->fault.gpcclient, info->client); + snprintf(ct, sizeof(ct), "GPC%d/", info->gpc); + } + ea = nvkm_enum_find(fifo->func->fault.access, info->access); + + if (ee && ee->data2) { + switch (ee->data2) { + case NVKM_SUBDEV_BAR: + nvkm_mask(device, 0x001704, 0x00000000, 0x00000000); + break; + case NVKM_SUBDEV_INSTMEM: + nvkm_mask(device, 0x001714, 0x00000000, 0x00000000); + break; + case NVKM_ENGINE_IFB: + nvkm_mask(device, 0x001718, 0x00000000, 0x00000000); + break; + default: + engine = nvkm_device_engine(device, ee->data2); + break; + } + } + + if (ee == NULL) { + enum nvkm_devidx engidx = nvkm_top_fault(device, info->engine); + if (engidx < NVKM_SUBDEV_NR) { + const char *src = nvkm_subdev_name[engidx]; + char *dst = en; + do { + *dst++ = toupper(*src++); + } while(*src); + engine = nvkm_device_engine(device, engidx); + } + } else { + snprintf(en, sizeof(en), "%s", ee->name); + } + + spin_lock_irqsave(&fifo->base.lock, flags); + chan = nvkm_fifo_chan_inst_locked(&fifo->base, info->inst); + + nvkm_error(subdev, + "fault %02x [%s] at %016llx engine %02x [%s] client %02x " + "[%s%s] reason %02x [%s] on channel %d [%010llx %s]\n", + info->access, ea ? ea->name : "", info->addr, + info->engine, ee ? ee->name : en, + info->client, ct, ec ? ec->name : "", + info->reason, er ? er->name : "", chan ? chan->chid : -1, + info->inst, chan ? chan->object.client->name : "unknown"); + + /* Kill the channel that caused the fault. */ + if (chan) + gk104_fifo_recover_chan(&fifo->base, chan->chid); + + /* Channel recovery will probably have already done this for the + * correct engine(s), but just in case we can't find the channel + * information... + */ + for (engn = 0; engn < fifo->engine_nr && engine; engn++) { + if (fifo->engine[engn].engine == engine) { + gk104_fifo_recover_engn(fifo, engn); + break; + } + } + + spin_unlock_irqrestore(&fifo->base.lock, flags); +} + static const struct nvkm_enum gk104_fifo_bind_reason[] = { { 0x01, "BIND_NOT_UNBOUND" }, @@ -456,88 +541,21 @@ gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit) u32 inst = nvkm_rd32(device, 0x002800 + (unit * 0x10)); u32 valo = nvkm_rd32(device, 0x002804 + (unit * 0x10)); u32 vahi = nvkm_rd32(device, 0x002808 + (unit * 0x10)); - u32 stat = nvkm_rd32(device, 0x00280c + (unit * 0x10)); - u32 gpc = (stat & 0x1f000000) >> 24; - u32 client = (stat & 0x00001f00) >> 8; - u32 write = (stat & 0x00000080); - u32 hub = (stat & 0x00000040); - u32 reason = (stat & 0x0000000f); - const struct nvkm_enum *er, *eu, *ec; - struct nvkm_engine *engine = NULL; - struct nvkm_fifo_chan *chan; - unsigned long flags; - char gpcid[8] = "", en[16] = ""; - int engn; - - er = nvkm_enum_find(fifo->func->fault.reason, reason); - eu = nvkm_enum_find(fifo->func->fault.engine, unit); - if (hub) { - ec = nvkm_enum_find(fifo->func->fault.hubclient, client); - } else { - ec = nvkm_enum_find(fifo->func->fault.gpcclient, client); - snprintf(gpcid, sizeof(gpcid), "GPC%d/", gpc); - } - - if (eu && eu->data2) { - switch (eu->data2) { - case NVKM_SUBDEV_BAR: - nvkm_mask(device, 0x001704, 0x00000000, 0x00000000); - break; - case NVKM_SUBDEV_INSTMEM: - nvkm_mask(device, 0x001714, 0x00000000, 0x00000000); - break; - case NVKM_ENGINE_IFB: - nvkm_mask(device, 0x001718, 0x00000000, 0x00000000); - break; - default: - engine = nvkm_device_engine(device, eu->data2); - break; - } - } - - if (eu == NULL) { - enum nvkm_devidx engidx = nvkm_top_fault(device, unit); - if (engidx < NVKM_SUBDEV_NR) { - const char *src = nvkm_subdev_name[engidx]; - char *dst = en; - do { - *dst++ = toupper(*src++); - } while(*src); - engine = nvkm_device_engine(device, engidx); - } - } else { - snprintf(en, sizeof(en), "%s", eu->name); - } - - spin_lock_irqsave(&fifo->base.lock, flags); - chan = nvkm_fifo_chan_inst_locked(&fifo->base, (u64)inst << 12); - - nvkm_error(subdev, - "%s fault at %010llx engine %02x [%s] client %02x [%s%s] " - "reason %02x [%s] on channel %d [%010llx %s]\n", - write ? "write" : "read", (u64)vahi << 32 | valo, - unit, en, client, gpcid, ec ? ec->name : "", - reason, er ? er->name : "", chan ? chan->chid : -1, - (u64)inst << 12, - chan ? chan->object.client->name : "unknown"); - - - /* Kill the channel that caused the fault. */ - if (chan) - gk104_fifo_recover_chan(&fifo->base, chan->chid); - - /* Channel recovery will probably have already done this for the - * correct engine(s), but just in case we can't find the channel - * information... - */ - for (engn = 0; engn < fifo->engine_nr && engine; engn++) { - if (fifo->engine[engn].engine == engine) { - gk104_fifo_recover_engn(fifo, engn); - break; - } - } - - spin_unlock_irqrestore(&fifo->base.lock, flags); + u32 type = nvkm_rd32(device, 0x00280c + (unit * 0x10)); + struct nvkm_fault_data info; + + info.inst = (u64)inst << 12; + info.addr = ((u64)vahi << 32) | valo; + info.time = 0; + info.engine = unit; + info.valid = 1; + info.gpc = (type & 0x1f000000) >> 24; + info.client = (type & 0x00001f00) >> 8; + info.access = (type & 0x00000080) >> 7; + info.hub = (type & 0x00000040) >> 6; + info.reason = (type & 0x000000ff); + + nvkm_fifo_fault(&fifo->base, &info); } static const struct nvkm_bitfield gk104_fifo_pbdma_intr_0[] = { @@ -897,6 +915,7 @@ gk104_fifo_ = { .init = gk104_fifo_init, .fini = gk104_fifo_fini, .intr = gk104_fifo_intr, + .fault = gk104_fifo_fault, .uevent_init = gk104_fifo_uevent_init, .uevent_fini = gk104_fifo_uevent_fini, .recover_chan = gk104_fifo_recover_chan, @@ -918,6 +937,13 @@ gk104_fifo_new_(const struct gk104_fifo_func *func, struct nvkm_device *device, return nvkm_fifo_ctor(&gk104_fifo_, device, index, nr, &fifo->base); } +const struct nvkm_enum +gk104_fifo_fault_access[] = { + { 0x0, "READ" }, + { 0x1, "WRITE" }, + {} +}; + const struct nvkm_enum gk104_fifo_fault_engine[] = { { 0x00, "GR", NULL, NVKM_ENGINE_GR }, @@ -1035,6 +1061,7 @@ gk104_fifo_fault_gpcclient[] = { static const struct gk104_fifo_func gk104_fifo = { + .fault.access = gk104_fifo_fault_access, .fault.engine = gk104_fifo_fault_engine, .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h index 1579785cf941e..0e8b57275e9dd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h @@ -44,6 +44,7 @@ struct gk104_fifo { struct gk104_fifo_func { struct { + const struct nvkm_enum *access; const struct nvkm_enum *engine; const struct nvkm_enum *reason; const struct nvkm_enum *hubclient; @@ -59,25 +60,7 @@ void gk104_fifo_runlist_insert(struct gk104_fifo *, struct gk104_fifo_chan *); void gk104_fifo_runlist_remove(struct gk104_fifo *, struct gk104_fifo_chan *); void gk104_fifo_runlist_commit(struct gk104_fifo *, int runl); -static inline u64 -gk104_fifo_engine_subdev(int engine) -{ - switch (engine) { - case 0: return (1ULL << NVKM_ENGINE_GR) | - (1ULL << NVKM_ENGINE_SW) | - (1ULL << NVKM_ENGINE_CE2); - case 1: return (1ULL << NVKM_ENGINE_MSPDEC); - case 2: return (1ULL << NVKM_ENGINE_MSPPP); - case 3: return (1ULL << NVKM_ENGINE_MSVLD); - case 4: return (1ULL << NVKM_ENGINE_CE0); - case 5: return (1ULL << NVKM_ENGINE_CE1); - case 6: return (1ULL << NVKM_ENGINE_MSENC); - default: - WARN_ON(1); - return 0; - } -} - +extern const struct nvkm_enum gk104_fifo_fault_access[]; extern const struct nvkm_enum gk104_fifo_fault_engine[]; extern const struct nvkm_enum gk104_fifo_fault_reason[]; extern const struct nvkm_enum gk104_fifo_fault_hubclient[]; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c index b2f8ab7bf8471..ad792b6830e57 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c @@ -26,6 +26,7 @@ static const struct gk104_fifo_func gk110_fifo = { + .fault.access = gk104_fifo_fault_access, .fault.engine = gk104_fifo_fault_engine, .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c index 160617d376e48..5402d22462e86 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c @@ -26,6 +26,7 @@ static const struct gk104_fifo_func gk208_fifo = { + .fault.access = gk104_fifo_fault_access, .fault.engine = gk104_fifo_fault_engine, .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c index be9f5c16ed7dd..0d7f9f59f80c8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c @@ -24,6 +24,7 @@ static const struct gk104_fifo_func gk20a_fifo = { + .fault.access = gk104_fifo_fault_access, .fault.engine = gk104_fifo_fault_engine, .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c index 29c080683b32c..58a46ee5ee440 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c @@ -49,6 +49,7 @@ gm107_fifo_fault_engine[] = { static const struct gk104_fifo_func gm107_fifo = { + .fault.access = gk104_fifo_fault_access, .fault.engine = gm107_fifo_fault_engine, .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c index b069f785c5d8b..f84d5398aebeb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c @@ -26,6 +26,7 @@ static const struct gk104_fifo_func gm200_fifo = { + .fault.access = gk104_fifo_fault_access, .fault.engine = gm107_fifo_fault_engine, .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c index 2ed87c2e82996..66399b9572a68 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c @@ -24,6 +24,7 @@ static const struct gk104_fifo_func gm20b_fifo = { + .fault.access = gk104_fifo_fault_access, .fault.engine = gm107_fifo_fault_engine, .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c index 41f16cf5a918c..2b8a6cff7a686 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c @@ -50,6 +50,7 @@ gp100_fifo_fault_engine[] = { static const struct gk104_fifo_func gp100_fifo = { + .fault.access = gk104_fifo_fault_access, .fault.engine = gp100_fifo_fault_engine, .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c index 4af96c3e69fff..71b8d93b4368e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c @@ -24,6 +24,7 @@ static const struct gk104_fifo_func gp10b_fifo = { + .fault.access = gk104_fifo_fault_access, .fault.engine = gp100_fifo_fault_engine, .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h index ae76b1aaccd46..df74b54773b91 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h @@ -21,6 +21,7 @@ struct nvkm_fifo_func { void (*init)(struct nvkm_fifo *); void (*fini)(struct nvkm_fifo *); void (*intr)(struct nvkm_fifo *); + void (*fault)(struct nvkm_fifo *, struct nvkm_fault_data *); void (*pause)(struct nvkm_fifo *, unsigned long *); void (*start)(struct nvkm_fifo *, unsigned long *); void (*uevent_init)(struct nvkm_fifo *); From cc36205085bb6e3a4eed1edbe413fd2235cadb27 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 030/165] drm/nouveau/fifo/gk104-: support querying engines available on each runlist Will be used to improve channel runlist selection. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/cl0080.h | 7 ++ drivers/gpu/drm/nouveau/include/nvif/device.h | 5 + drivers/gpu/drm/nouveau/include/nvif/fifo.h | 18 ++++ drivers/gpu/drm/nouveau/nvif/Kbuild | 1 + drivers/gpu/drm/nouveau/nvif/device.c | 3 + drivers/gpu/drm/nouveau/nvif/fifo.c | 99 +++++++++++++++++++ .../gpu/drm/nouveau/nvkm/engine/fifo/base.c | 2 + .../gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 30 ++++++ .../gpu/drm/nouveau/nvkm/engine/fifo/priv.h | 1 + 9 files changed, 166 insertions(+) create mode 100644 drivers/gpu/drm/nouveau/include/nvif/fifo.h create mode 100644 drivers/gpu/drm/nouveau/nvif/fifo.c diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl0080.h b/drivers/gpu/drm/nouveau/include/nvif/cl0080.h index 5af610ea260e8..49c1c90d2bde0 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/cl0080.h +++ b/drivers/gpu/drm/nouveau/include/nvif/cl0080.h @@ -83,4 +83,11 @@ struct nv_device_time_v0 { /* Returns the number of available channels. */ #define NV_DEVICE_FIFO_CHANNELS NV_DEVICE_FIFO(0x00000000) + +/* Returns a mask of available runlists. */ +#define NV_DEVICE_FIFO_RUNLISTS NV_DEVICE_FIFO(0x00000001) + +/* These return a mask of engines available on a particular runlist. */ +#define NV_DEVICE_FIFO_RUNLIST_ENGINES(n) ((n) + NV_DEVICE_FIFO(0x00000010)) +#define NV_DEVICE_FIFO_RUNLIST_ENGINES__SIZE 64 #endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/device.h b/drivers/gpu/drm/nouveau/include/nvif/device.h index 216dbd9fa6168..76fe21e395de4 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/device.h +++ b/drivers/gpu/drm/nouveau/include/nvif/device.h @@ -8,6 +8,11 @@ struct nvif_device { struct nvif_object object; struct nv_device_info_v0 info; + + struct nvif_fifo_runlist { + u64 engines; + } *runlist; + int runlists; }; int nvif_device_init(struct nvif_object *, u32 handle, s32 oclass, void *, u32, diff --git a/drivers/gpu/drm/nouveau/include/nvif/fifo.h b/drivers/gpu/drm/nouveau/include/nvif/fifo.h new file mode 100644 index 0000000000000..e9468c9f9abfd --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/fifo.h @@ -0,0 +1,18 @@ +#ifndef __NVIF_FIFO_H__ +#define __NVIF_FIFO_H__ +#include + +/* Returns mask of runlists that support a NV_DEVICE_INFO_ENGINE_* type. */ +u64 nvif_fifo_runlist(struct nvif_device *, u64 engine); + +/* CE-supporting runlists (excluding GRCE, if others exist). */ +static inline u64 +nvif_fifo_runlist_ce(struct nvif_device *device) +{ + u64 runmgr = nvif_fifo_runlist(device, NV_DEVICE_INFO_ENGINE_GR); + u64 runmce = nvif_fifo_runlist(device, NV_DEVICE_INFO_ENGINE_CE); + if (runmce && !(runmce &= ~runmgr)) + runmce = runmgr; + return runmce; +} +#endif diff --git a/drivers/gpu/drm/nouveau/nvif/Kbuild b/drivers/gpu/drm/nouveau/nvif/Kbuild index f1675a4ab6fa5..c817b02b7acf2 100644 --- a/drivers/gpu/drm/nouveau/nvif/Kbuild +++ b/drivers/gpu/drm/nouveau/nvif/Kbuild @@ -2,6 +2,7 @@ nvif-y := nvif/object.o nvif-y += nvif/client.o nvif-y += nvif/device.o nvif-y += nvif/driver.o +nvif-y += nvif/fifo.o nvif-y += nvif/mem.o nvif-y += nvif/mmu.o nvif-y += nvif/notify.o diff --git a/drivers/gpu/drm/nouveau/nvif/device.c b/drivers/gpu/drm/nouveau/nvif/device.c index 252d8c33215bb..ca5eb3dde70a0 100644 --- a/drivers/gpu/drm/nouveau/nvif/device.c +++ b/drivers/gpu/drm/nouveau/nvif/device.c @@ -37,6 +37,8 @@ nvif_device_time(struct nvif_device *device) void nvif_device_fini(struct nvif_device *device) { + kfree(device->runlist); + device->runlist = NULL; nvif_object_fini(&device->object); } @@ -46,6 +48,7 @@ nvif_device_init(struct nvif_object *parent, u32 handle, s32 oclass, { int ret = nvif_object_init(parent, handle, oclass, data, size, &device->object); + device->runlist = NULL; if (ret == 0) { device->info.version = 0; ret = nvif_object_mthd(&device->object, NV_DEVICE_V0_INFO, diff --git a/drivers/gpu/drm/nouveau/nvif/fifo.c b/drivers/gpu/drm/nouveau/nvif/fifo.c new file mode 100644 index 0000000000000..99d4fd17543c4 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvif/fifo.c @@ -0,0 +1,99 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 + +static int +nvif_fifo_runlists(struct nvif_device *device) +{ + struct nvif_object *object = &device->object; + struct { + struct nv_device_info_v1 m; + struct { + struct nv_device_info_v1_data runlists; + struct nv_device_info_v1_data runlist[64]; + } v; + } *a; + int ret, i; + + if (device->runlist) + return 0; + + if (!(a = kmalloc(sizeof(*a), GFP_KERNEL))) + return -ENOMEM; + a->m.version = 1; + a->m.count = sizeof(a->v) / sizeof(a->v.runlists); + a->v.runlists.mthd = NV_DEVICE_FIFO_RUNLISTS; + for (i = 0; i < ARRAY_SIZE(a->v.runlist); i++) + a->v.runlist[i].mthd = NV_DEVICE_FIFO_RUNLIST_ENGINES(i); + + ret = nvif_object_mthd(object, NV_DEVICE_V0_INFO, a, sizeof(*a)); + if (ret) + goto done; + + device->runlists = fls64(a->v.runlists.data); + device->runlist = kzalloc(sizeof(*device->runlist) * + device->runlists, GFP_KERNEL); + if (!device->runlist) { + ret = -ENOMEM; + goto done; + } + + for (i = 0; i < device->runlists; i++) { + if (a->v.runlists.data & BIT_ULL(i)) + device->runlist[i].engines = a->v.runlist[i].data; + } + +done: + kfree(a); + return ret; +} + +u64 +nvif_fifo_runlist(struct nvif_device *device, u64 engine) +{ + struct nvif_object *object = &device->object; + struct { + struct nv_device_info_v1 m; + struct { + struct nv_device_info_v1_data engine; + } v; + } a = { + .m.version = 1, + .m.count = sizeof(a.v) / sizeof(a.v.engine), + .v.engine.mthd = engine, + }; + u64 runm = 0; + int ret, i; + + if ((ret = nvif_fifo_runlists(device))) + return runm; + + ret = nvif_object_mthd(object, NV_DEVICE_V0_INFO, &a, sizeof(a)); + if (ret == 0) { + for (i = 0; i < device->runlists; i++) { + if (device->runlist[i].engines & a.v.engine.data) + runm |= BIT_ULL(i); + } + } + + return runm; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c index ed56087b4abe2..1642d8ea68f1c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c @@ -284,6 +284,8 @@ nvkm_fifo_info(struct nvkm_engine *engine, u64 mthd, u64 *data) switch (mthd) { case NV_DEVICE_FIFO_CHANNELS: *data = fifo->nr; return 0; default: + if (fifo->func->info) + return fifo->func->info(fifo, mthd, data); break; } return -ENOSYS; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index b5706b15a64d9..b6c23cf43f832 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -33,6 +33,7 @@ #include #include +#include struct gk104_fifo_engine_status { bool busy; @@ -783,6 +784,34 @@ gk104_fifo_fini(struct nvkm_fifo *base) nvkm_mask(device, 0x002140, 0x10000000, 0x10000000); } +static int +gk104_fifo_info(struct nvkm_fifo *base, u64 mthd, u64 *data) +{ + struct gk104_fifo *fifo = gk104_fifo(base); + switch (mthd) { + case NV_DEVICE_FIFO_RUNLISTS: + *data = (1ULL << fifo->runlist_nr) - 1; + return 0; + case NV_DEVICE_FIFO_RUNLIST_ENGINES(0)... + NV_DEVICE_FIFO_RUNLIST_ENGINES(63): { + int runl = mthd - NV_DEVICE_FIFO_RUNLIST_ENGINES(0), engn; + if (runl < fifo->runlist_nr) { + unsigned long engm = fifo->runlist[runl].engm; + struct nvkm_engine *engine; + *data = 0; + for_each_set_bit(engn, &engm, fifo->engine_nr) { + if ((engine = fifo->engine[engn].engine)) + *data |= BIT_ULL(engine->subdev.index); + } + return 0; + } + } + return -EINVAL; + default: + return -EINVAL; + } +} + static int gk104_fifo_oneinit(struct nvkm_fifo *base) { @@ -912,6 +941,7 @@ static const struct nvkm_fifo_func gk104_fifo_ = { .dtor = gk104_fifo_dtor, .oneinit = gk104_fifo_oneinit, + .info = gk104_fifo_info, .init = gk104_fifo_init, .fini = gk104_fifo_fini, .intr = gk104_fifo_intr, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h index df74b54773b91..f9b4e9d2c08ab 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h @@ -18,6 +18,7 @@ struct nvkm_fifo_chan_oclass; struct nvkm_fifo_func { void *(*dtor)(struct nvkm_fifo *); int (*oneinit)(struct nvkm_fifo *); + int (*info)(struct nvkm_fifo *, u64 mthd, u64 *data); void (*init)(struct nvkm_fifo *); void (*fini)(struct nvkm_fifo *); void (*intr)(struct nvkm_fifo *); From a7cf01809bf23b95413d8047bd91cdc3cedd1ca1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 031/165] drm/nouveau/fifo/gk104-: require explicit runlist selection for channel allocation We didn't used to be aware that runlist/engine IDs weren't the same thing, or that there was such variability in configuration between GPUs. By exposing this information to a client, and giving it explicit control of which runlist it's allocating a channel on, we're able to make better choices. The immediate effect of this is that on GPUs where CE0 is the "GRCE", we will now be allocating a copy engine running asynchronously to GR for BO migrations - as intended. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/cla06f.h | 18 +--- drivers/gpu/drm/nouveau/nouveau_abi16.c | 35 ++++---- drivers/gpu/drm/nouveau/nouveau_chan.c | 4 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 8 +- .../nouveau/nvkm/engine/fifo/gpfifogk104.c | 83 ++++--------------- 5 files changed, 43 insertions(+), 105 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvif/cla06f.h b/drivers/gpu/drm/nouveau/include/nvif/cla06f.h index 56f5bd81e480b..fbfcffc5feb2b 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/cla06f.h +++ b/drivers/gpu/drm/nouveau/include/nvif/cla06f.h @@ -4,25 +4,11 @@ struct kepler_channel_gpfifo_a_v0 { __u8 version; - __u8 pad01[5]; + __u8 pad01[1]; __u16 chid; -#define NVA06F_V0_ENGINE_SW 0x00000001 -#define NVA06F_V0_ENGINE_GR 0x00000002 -#define NVA06F_V0_ENGINE_SEC 0x00000004 -#define NVA06F_V0_ENGINE_MSVLD 0x00000010 -#define NVA06F_V0_ENGINE_MSPDEC 0x00000020 -#define NVA06F_V0_ENGINE_MSPPP 0x00000040 -#define NVA06F_V0_ENGINE_MSENC 0x00000080 -#define NVA06F_V0_ENGINE_VIC 0x00000100 -#define NVA06F_V0_ENGINE_NVDEC 0x00000200 -#define NVA06F_V0_ENGINE_NVENC0 0x00000400 -#define NVA06F_V0_ENGINE_NVENC1 0x00000800 -#define NVA06F_V0_ENGINE_CE0 0x00010000 -#define NVA06F_V0_ENGINE_CE1 0x00020000 -#define NVA06F_V0_ENGINE_CE2 0x00040000 - __u32 engines; __u32 ilength; __u64 ioffset; + __u64 runlist; __u64 vmm; }; diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index ece650a0c5f9f..ea2472770b21b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -256,6 +257,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv); struct nouveau_abi16_chan *chan; struct nvif_device *device; + u64 engine; int ret; if (unlikely(!abi16)) @@ -268,25 +270,26 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) /* hack to allow channel engine type specification on kepler */ if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) { - if (init->fb_ctxdma_handle != ~0) - init->fb_ctxdma_handle = NVA06F_V0_ENGINE_GR; - else { - init->fb_ctxdma_handle = 0; -#define _(A,B) if (init->tt_ctxdma_handle & (A)) init->fb_ctxdma_handle |= (B) - _(0x01, NVA06F_V0_ENGINE_GR); - _(0x02, NVA06F_V0_ENGINE_MSPDEC); - _(0x04, NVA06F_V0_ENGINE_MSPPP); - _(0x08, NVA06F_V0_ENGINE_MSVLD); - _(0x10, NVA06F_V0_ENGINE_CE0); - _(0x20, NVA06F_V0_ENGINE_CE1); - _(0x40, NVA06F_V0_ENGINE_MSENC); -#undef _ + if (init->fb_ctxdma_handle == ~0) { + switch (init->tt_ctxdma_handle) { + case 0x01: engine = NV_DEVICE_INFO_ENGINE_GR ; break; + case 0x02: engine = NV_DEVICE_INFO_ENGINE_MSPDEC; break; + case 0x04: engine = NV_DEVICE_INFO_ENGINE_MSPPP ; break; + case 0x08: engine = NV_DEVICE_INFO_ENGINE_MSVLD ; break; + case 0x30: engine = NV_DEVICE_INFO_ENGINE_CE ; break; + default: + return nouveau_abi16_put(abi16, -ENOSYS); + } + } else { + engine = NV_DEVICE_INFO_ENGINE_GR; } - /* allow flips to be executed if this is a graphics channel */ + if (engine != NV_DEVICE_INFO_ENGINE_CE) + engine = nvif_fifo_runlist(device, engine); + else + engine = nvif_fifo_runlist_ce(device); + init->fb_ctxdma_handle = engine; init->tt_ctxdma_handle = 0; - if (init->fb_ctxdma_handle == NVA06F_V0_ENGINE_GR) - init->tt_ctxdma_handle = 1; } if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index db69d13f32a71..67950a5c56ce9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -214,7 +214,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, static int nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, - u32 engine, struct nouveau_channel **pchan) + u64 runlist, struct nouveau_channel **pchan) { struct nouveau_cli *cli = (void *)device->object.client; static const u16 oclasses[] = { PASCAL_CHANNEL_GPFIFO_A, @@ -245,9 +245,9 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, do { if (oclass[0] >= KEPLER_CHANNEL_GPFIFO_A) { args.kepler.version = 0; - args.kepler.engines = engine; args.kepler.ilength = 0x02000; args.kepler.ioffset = 0x10000 + chan->push.addr; + args.kepler.runlist = runlist; args.kepler.vmm = nvif_handle(&cli->vmm.vmm.object); size = sizeof(args.kepler); } else diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index dddd42592472f..6caece4f2f5f6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -358,13 +359,12 @@ nouveau_accel_init(struct nouveau_drm *drm) if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) { ret = nouveau_channel_new(drm, &drm->client.device, - NVA06F_V0_ENGINE_CE0 | - NVA06F_V0_ENGINE_CE1, - 0, &drm->cechan); + nvif_fifo_runlist_ce(device), 0, + &drm->cechan); if (ret) NV_ERROR(drm, "failed to create ce channel, %d\n", ret); - arg0 = NVA06F_V0_ENGINE_GR; + arg0 = nvif_fifo_runlist(device, NV_DEVICE_INFO_ENGINE_GR); arg1 = 1; } else if (device->info.chipset >= 0xa3 && diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c index 68461993394f1..e331ab1b702b2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c @@ -222,62 +222,30 @@ gk104_fifo_gpfifo_func = { .engine_fini = gk104_fifo_gpfifo_engine_fini, }; -struct gk104_fifo_chan_func { - u32 engine; - u64 subdev; -}; - static int -gk104_fifo_gpfifo_new_(const struct gk104_fifo_chan_func *func, - struct gk104_fifo *fifo, u32 *engmask, u16 *chid, +gk104_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid, u64 vmm, u64 ioffset, u64 ilength, const struct nvkm_oclass *oclass, struct nvkm_object **pobject) { struct gk104_fifo_chan *chan; - int runlist = -1, ret = -ENOSYS, i, j; - u32 engines = 0, present = 0; + int runlist = ffs(*runlists) -1, ret, i; + unsigned long engm; u64 subdevs = 0; u64 usermem; - if (!vmm) + if (!vmm || runlist < 0 || runlist >= fifo->runlist_nr) return -EINVAL; + *runlists = BIT_ULL(runlist); - /* Determine which downstream engines are present */ - for (i = 0; i < fifo->engine_nr; i++) { - struct nvkm_engine *engine = fifo->engine[i].engine; - if (engine) { - u64 submask = BIT_ULL(engine->subdev.index); - for (j = 0; func[j].subdev; j++) { - if (func[j].subdev & submask) { - present |= func[j].engine; - break; - } - } - - if (!func[j].subdev) - continue; - - if (runlist < 0 && (*engmask & present)) - runlist = fifo->engine[i].runl; - if (runlist == fifo->engine[i].runl) { - engines |= func[j].engine; - subdevs |= func[j].subdev; - } - } + engm = fifo->runlist[runlist].engm; + for_each_set_bit(i, &engm, fifo->engine_nr) { + if (fifo->engine[i].engine) + subdevs |= BIT_ULL(fifo->engine[i].engine->subdev.index); } - /* Just an engine mask query? All done here! */ - if (!*engmask) { - *engmask = present; - return nvkm_object_new(oclass, NULL, 0, pobject); - } - - /* No runlist? No supported engines. */ - *engmask = present; - if (runlist < 0) - return -ENODEV; - *engmask = engines; + if (subdevs & BIT_ULL(NVKM_ENGINE_GR)) + subdevs |= BIT_ULL(NVKM_ENGINE_SW); /* Allocate the channel. */ if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) @@ -327,26 +295,6 @@ gk104_fifo_gpfifo_new_(const struct gk104_fifo_chan_func *func, return 0; } -static const struct gk104_fifo_chan_func -gk104_fifo_gpfifo[] = { - { NVA06F_V0_ENGINE_SW | NVA06F_V0_ENGINE_GR, - BIT_ULL(NVKM_ENGINE_SW) | BIT_ULL(NVKM_ENGINE_GR) - }, - { NVA06F_V0_ENGINE_SEC , BIT_ULL(NVKM_ENGINE_SEC ) }, - { NVA06F_V0_ENGINE_MSVLD , BIT_ULL(NVKM_ENGINE_MSVLD ) }, - { NVA06F_V0_ENGINE_MSPDEC, BIT_ULL(NVKM_ENGINE_MSPDEC) }, - { NVA06F_V0_ENGINE_MSPPP , BIT_ULL(NVKM_ENGINE_MSPPP ) }, - { NVA06F_V0_ENGINE_MSENC , BIT_ULL(NVKM_ENGINE_MSENC ) }, - { NVA06F_V0_ENGINE_VIC , BIT_ULL(NVKM_ENGINE_VIC ) }, - { NVA06F_V0_ENGINE_NVDEC , BIT_ULL(NVKM_ENGINE_NVDEC ) }, - { NVA06F_V0_ENGINE_NVENC0, BIT_ULL(NVKM_ENGINE_NVENC0) }, - { NVA06F_V0_ENGINE_NVENC1, BIT_ULL(NVKM_ENGINE_NVENC1) }, - { NVA06F_V0_ENGINE_CE0 , BIT_ULL(NVKM_ENGINE_CE0 ) }, - { NVA06F_V0_ENGINE_CE1 , BIT_ULL(NVKM_ENGINE_CE1 ) }, - { NVA06F_V0_ENGINE_CE2 , BIT_ULL(NVKM_ENGINE_CE2 ) }, - {} -}; - int gk104_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, void *data, u32 size, struct nvkm_object **pobject) @@ -361,11 +309,12 @@ gk104_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, nvif_ioctl(parent, "create channel gpfifo size %d\n", size); if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { nvif_ioctl(parent, "create channel gpfifo vers %d vmm %llx " - "ioffset %016llx ilength %08x engine %08x\n", + "ioffset %016llx ilength %08x " + "runlist %016llx\n", args->v0.version, args->v0.vmm, args->v0.ioffset, - args->v0.ilength, args->v0.engines); - return gk104_fifo_gpfifo_new_(gk104_fifo_gpfifo, fifo, - &args->v0.engines, + args->v0.ilength, args->v0.runlist); + return gk104_fifo_gpfifo_new_(fifo, + &args->v0.runlist, &args->v0.chid, args->v0.vmm, args->v0.ioffset, From f9360c3aa61f792de3c839c63bfadf8640255d8c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 032/165] drm/nouveau/fifo/gk104-: simplify definition of channel classes Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/fifo/Kbuild | 3 -- .../gpu/drm/nouveau/nvkm/engine/fifo/base.c | 24 +++++++++---- .../drm/nouveau/nvkm/engine/fifo/changk104.h | 7 +--- .../gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 28 ++++++++++----- .../gpu/drm/nouveau/nvkm/engine/fifo/gk104.h | 6 +++- .../gpu/drm/nouveau/nvkm/engine/fifo/gk110.c | 7 ++-- .../gpu/drm/nouveau/nvkm/engine/fifo/gk208.c | 7 ++-- .../gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c | 7 ++-- .../gpu/drm/nouveau/nvkm/engine/fifo/gm107.c | 7 ++-- .../gpu/drm/nouveau/nvkm/engine/fifo/gm200.c | 7 ++-- .../gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c | 7 ++-- .../gpu/drm/nouveau/nvkm/engine/fifo/gp100.c | 7 ++-- .../gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c | 7 ++-- .../nouveau/nvkm/engine/fifo/gpfifogk104.c | 11 +----- .../nouveau/nvkm/engine/fifo/gpfifogk110.c | 34 ------------------- .../nouveau/nvkm/engine/fifo/gpfifogm200.c | 34 ------------------- .../nouveau/nvkm/engine/fifo/gpfifogp100.c | 34 ------------------- .../gpu/drm/nouveau/nvkm/engine/fifo/priv.h | 5 +-- 18 files changed, 71 insertions(+), 171 deletions(-) delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk110.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogm200.c delete mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogp100.c diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild index 64e51838edf85..b888ea64df210 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild @@ -31,6 +31,3 @@ nvkm-y += nvkm/engine/fifo/gpfifonv50.o nvkm-y += nvkm/engine/fifo/gpfifog84.o nvkm-y += nvkm/engine/fifo/gpfifogf100.o nvkm-y += nvkm/engine/fifo/gpfifogk104.o -nvkm-y += nvkm/engine/fifo/gpfifogk110.o -nvkm-y += nvkm/engine/fifo/gpfifogm200.o -nvkm-y += nvkm/engine/fifo/gpfifogp100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c index 1642d8ea68f1c..c773caf21f6be 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c @@ -215,6 +215,20 @@ nvkm_fifo_uevent(struct nvkm_fifo *fifo) nvkm_event_send(&fifo->uevent, 1, 0, &rep, sizeof(rep)); } +static int +nvkm_fifo_class_new_(struct nvkm_device *device, + const struct nvkm_oclass *oclass, void *data, u32 size, + struct nvkm_object **pobject) +{ + struct nvkm_fifo *fifo = nvkm_fifo(oclass->engine); + return fifo->func->class_new(fifo, oclass, data, size, pobject); +} + +static const struct nvkm_device_oclass +nvkm_fifo_class_ = { + .ctor = nvkm_fifo_class_new_, +}; + static int nvkm_fifo_class_new(struct nvkm_device *device, const struct nvkm_oclass *oclass, void *data, u32 size, @@ -239,13 +253,9 @@ nvkm_fifo_class_get(struct nvkm_oclass *oclass, int index, int c = 0; if (fifo->func->class_get) { - int ret = fifo->func->class_get(fifo, index, &sclass); - if (ret == 0) { - oclass->base = sclass->base; - oclass->engn = sclass; - *class = &nvkm_fifo_class; - return 0; - } + int ret = fifo->func->class_get(fifo, index, oclass); + if (ret == 0) + *class = &nvkm_fifo_class_; return ret; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h index 1208e3d9dbe28..08b4415f0e24e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h @@ -19,11 +19,6 @@ struct gk104_fifo_chan { } engn[NVKM_SUBDEV_NR]; }; -int gk104_fifo_gpfifo_new(struct nvkm_fifo *, const struct nvkm_oclass *, +int gk104_fifo_gpfifo_new(struct gk104_fifo *, const struct nvkm_oclass *, void *data, u32 size, struct nvkm_object **); - -extern const struct nvkm_fifo_chan_oclass gk104_fifo_gpfifo_oclass; -extern const struct nvkm_fifo_chan_oclass gk110_fifo_gpfifo_oclass; -extern const struct nvkm_fifo_chan_oclass gm200_fifo_gpfifo_oclass; -extern const struct nvkm_fifo_chan_oclass gp100_fifo_gpfifo_oclass; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index b6c23cf43f832..316b2b1d08e83 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -94,16 +94,30 @@ gk104_fifo_engine_status(struct gk104_fifo *fifo, int engn, status->chan == &status->next ? "*" : " "); } +static int +gk104_fifo_class_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, + void *argv, u32 argc, struct nvkm_object **pobject) +{ + struct gk104_fifo *fifo = gk104_fifo(base); + if (oclass->engn == &fifo->func->chan) { + const struct gk104_fifo_chan_user *user = oclass->engn; + return user->ctor(fifo, oclass, argv, argc, pobject); + } + WARN_ON(1); + return -EINVAL; +} + static int gk104_fifo_class_get(struct nvkm_fifo *base, int index, - const struct nvkm_fifo_chan_oclass **psclass) + struct nvkm_oclass *oclass) { struct gk104_fifo *fifo = gk104_fifo(base); int c = 0; - while ((*psclass = fifo->func->chan[c])) { - if (c++ == index) - return 0; + if (fifo->func->chan.ctor && c++ == index) { + oclass->base = fifo->func->chan.user; + oclass->engn = &fifo->func->chan; + return 0; } return c; @@ -950,6 +964,7 @@ gk104_fifo_ = { .uevent_fini = gk104_fifo_uevent_fini, .recover_chan = gk104_fifo_recover_chan, .class_get = gk104_fifo_class_get, + .class_new = gk104_fifo_class_new, }; int @@ -1096,10 +1111,7 @@ gk104_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .chan = { - &gk104_fifo_gpfifo_oclass, - NULL - }, + .chan = {{0,0,KEPLER_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h index 0e8b57275e9dd..41f1f367eaebb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h @@ -51,7 +51,11 @@ struct gk104_fifo_func { const struct nvkm_enum *gpcclient; } fault; - const struct nvkm_fifo_chan_oclass *chan[]; + struct gk104_fifo_chan_user { + struct nvkm_sclass user; + int (*ctor)(struct gk104_fifo *, const struct nvkm_oclass *, + void *, u32, struct nvkm_object **); + } chan; }; int gk104_fifo_new_(const struct gk104_fifo_func *, struct nvkm_device *, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c index ad792b6830e57..9611bf1ad0b0a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c @@ -24,6 +24,8 @@ #include "gk104.h" #include "changk104.h" +#include + static const struct gk104_fifo_func gk110_fifo = { .fault.access = gk104_fifo_fault_access, @@ -31,10 +33,7 @@ gk110_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .chan = { - &gk110_fifo_gpfifo_oclass, - NULL - }, + .chan = {{0,0,KEPLER_CHANNEL_GPFIFO_B}, gk104_fifo_gpfifo_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c index 5402d22462e86..fabc690ddd56e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c @@ -24,6 +24,8 @@ #include "gk104.h" #include "changk104.h" +#include + static const struct gk104_fifo_func gk208_fifo = { .fault.access = gk104_fifo_fault_access, @@ -31,10 +33,7 @@ gk208_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .chan = { - &gk104_fifo_gpfifo_oclass, - NULL - }, + .chan = {{0,0,KEPLER_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c index 0d7f9f59f80c8..dee1bd76882a4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c @@ -22,6 +22,8 @@ #include "gk104.h" #include "changk104.h" +#include + static const struct gk104_fifo_func gk20a_fifo = { .fault.access = gk104_fifo_fault_access, @@ -29,10 +31,7 @@ gk20a_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .chan = { - &gk104_fifo_gpfifo_oclass, - NULL - }, + .chan = {{0,0,KEPLER_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c index 58a46ee5ee440..09f97827167ab 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c @@ -24,6 +24,8 @@ #include "gk104.h" #include "changk104.h" +#include + const struct nvkm_enum gm107_fifo_fault_engine[] = { { 0x01, "DISPLAY" }, @@ -54,10 +56,7 @@ gm107_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .chan = { - &gk110_fifo_gpfifo_oclass, - NULL - }, + .chan = {{0,0,KEPLER_CHANNEL_GPFIFO_B}, gk104_fifo_gpfifo_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c index f84d5398aebeb..052b7c2c5d764 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c @@ -24,6 +24,8 @@ #include "gk104.h" #include "changk104.h" +#include + static const struct gk104_fifo_func gm200_fifo = { .fault.access = gk104_fifo_fault_access, @@ -31,10 +33,7 @@ gm200_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .chan = { - &gm200_fifo_gpfifo_oclass, - NULL - }, + .chan = {{0,0,MAXWELL_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c index 66399b9572a68..844787c6fb62b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c @@ -22,6 +22,8 @@ #include "gk104.h" #include "changk104.h" +#include + static const struct gk104_fifo_func gm20b_fifo = { .fault.access = gk104_fifo_fault_access, @@ -29,10 +31,7 @@ gm20b_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .chan = { - &gm200_fifo_gpfifo_oclass, - NULL - }, + .chan = {{0,0,MAXWELL_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c index 2b8a6cff7a686..2e31847e2e4fd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c @@ -24,6 +24,8 @@ #include "gk104.h" #include "changk104.h" +#include + const struct nvkm_enum gp100_fifo_fault_engine[] = { { 0x01, "DISPLAY" }, @@ -55,10 +57,7 @@ gp100_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .chan = { - &gp100_fifo_gpfifo_oclass, - NULL - }, + .chan = {{0,0,PASCAL_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c index 71b8d93b4368e..38ab6e17ec157 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c @@ -22,6 +22,8 @@ #include "gk104.h" #include "changk104.h" +#include + static const struct gk104_fifo_func gp10b_fifo = { .fault.access = gk104_fifo_fault_access, @@ -29,10 +31,7 @@ gp10b_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .chan = { - &gp100_fifo_gpfifo_oclass, - NULL - }, + .chan = {{0,0,PASCAL_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c index e331ab1b702b2..f7a4e0e86b23a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c @@ -296,14 +296,13 @@ gk104_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid, } int -gk104_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, +gk104_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass, void *data, u32 size, struct nvkm_object **pobject) { struct nvkm_object *parent = oclass->parent; union { struct kepler_channel_gpfifo_a_v0 v0; } *args = data; - struct gk104_fifo *fifo = gk104_fifo(base); int ret = -ENOSYS; nvif_ioctl(parent, "create channel gpfifo size %d\n", size); @@ -324,11 +323,3 @@ gk104_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, return ret; } - -const struct nvkm_fifo_chan_oclass -gk104_fifo_gpfifo_oclass = { - .base.oclass = KEPLER_CHANNEL_GPFIFO_A, - .base.minver = 0, - .base.maxver = 0, - .ctor = gk104_fifo_gpfifo_new, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk110.c deleted file mode 100644 index a9aa69c82e8e0..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk110.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2016 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "changk104.h" - -#include - -const struct nvkm_fifo_chan_oclass -gk110_fifo_gpfifo_oclass = { - .base.oclass = KEPLER_CHANNEL_GPFIFO_B, - .base.minver = 0, - .base.maxver = 0, - .ctor = gk104_fifo_gpfifo_new, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogm200.c deleted file mode 100644 index a13315147391a..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogm200.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2015 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "changk104.h" - -#include - -const struct nvkm_fifo_chan_oclass -gm200_fifo_gpfifo_oclass = { - .base.oclass = MAXWELL_CHANNEL_GPFIFO_A, - .base.minver = 0, - .base.maxver = 0, - .ctor = gk104_fifo_gpfifo_new, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogp100.c deleted file mode 100644 index 1530a9217aea2..0000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogp100.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2016 Red Hat Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Authors: Ben Skeggs - */ -#include "changk104.h" - -#include - -const struct nvkm_fifo_chan_oclass -gp100_fifo_gpfifo_oclass = { - .base.oclass = PASCAL_CHANNEL_GPFIFO_A, - .base.minver = 0, - .base.maxver = 0, - .ctor = gk104_fifo_gpfifo_new, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h index f9b4e9d2c08ab..d5acbba293f44 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h @@ -28,8 +28,9 @@ struct nvkm_fifo_func { void (*uevent_init)(struct nvkm_fifo *); void (*uevent_fini)(struct nvkm_fifo *); void (*recover_chan)(struct nvkm_fifo *, int chid); - int (*class_get)(struct nvkm_fifo *, int index, - const struct nvkm_fifo_chan_oclass **); + int (*class_get)(struct nvkm_fifo *, int index, struct nvkm_oclass *); + int (*class_new)(struct nvkm_fifo *, const struct nvkm_oclass *, + void *, u32, struct nvkm_object **); const struct nvkm_fifo_chan_oclass *chan[]; }; From 665870837a764fc7ba6f0e1291291e86f909c29b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 033/165] drm/nouveau/fifo/gk104-: add interfaces to support different runlist layouts This will be required to support features on newer hardware. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 40 ++++++++++++------- .../gpu/drm/nouveau/nvkm/engine/fifo/gk104.h | 10 +++++ .../gpu/drm/nouveau/nvkm/engine/fifo/gk110.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/gk208.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/gm107.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/gm200.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/gp100.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c | 1 + 10 files changed, 44 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index 316b2b1d08e83..afb3ed06ec89e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -140,6 +140,7 @@ gk104_fifo_uevent_init(struct nvkm_fifo *fifo) void gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl) { + const struct gk104_fifo_runlist_func *func = fifo->func->runlist; struct gk104_fifo_chan *chan; struct nvkm_subdev *subdev = &fifo->base.engine.subdev; struct nvkm_device *device = subdev->device; @@ -153,9 +154,7 @@ gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl) nvkm_kmap(mem); list_for_each_entry(chan, &fifo->runlist[runl].chan, head) { - nvkm_wo32(mem, (nr * 8) + 0, chan->base.chid); - nvkm_wo32(mem, (nr * 8) + 4, 0x00000000); - nr++; + func->chan(chan, mem, nr++ * func->size); } nvkm_done(mem); @@ -196,6 +195,20 @@ gk104_fifo_runlist_insert(struct gk104_fifo *fifo, struct gk104_fifo_chan *chan) mutex_unlock(&fifo->base.engine.subdev.mutex); } +void +gk104_fifo_runlist_chan(struct gk104_fifo_chan *chan, + struct nvkm_memory *memory, u32 offset) +{ + nvkm_wo32(memory, offset + 0, chan->base.chid); + nvkm_wo32(memory, offset + 4, 0x00000000); +} + +const struct gk104_fifo_runlist_func +gk104_fifo_runlist = { + .size = 8, + .chan = gk104_fifo_runlist_chan, +}; + static void gk104_fifo_recover_work(struct work_struct *w) { @@ -874,17 +887,15 @@ gk104_fifo_oneinit(struct nvkm_fifo *base) kfree(map); for (i = 0; i < fifo->runlist_nr; i++) { - ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, - 0x8000, 0x1000, false, - &fifo->runlist[i].mem[0]); - if (ret) - return ret; - - ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, - 0x8000, 0x1000, false, - &fifo->runlist[i].mem[1]); - if (ret) - return ret; + for (j = 0; j < ARRAY_SIZE(fifo->runlist[i].mem); j++) { + ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, + fifo->base.nr * 2/* TSG+chan */ * + fifo->func->runlist->size, + 0x1000, false, + &fifo->runlist[i].mem[j]); + if (ret) + return ret; + } init_waitqueue_head(&fifo->runlist[i].wait); INIT_LIST_HEAD(&fifo->runlist[i].chan); @@ -1111,6 +1122,7 @@ gk104_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, + .runlist = &gk104_fifo_runlist, .chan = {{0,0,KEPLER_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h index 41f1f367eaebb..c32ea45f94564 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h @@ -51,6 +51,12 @@ struct gk104_fifo_func { const struct nvkm_enum *gpcclient; } fault; + const struct gk104_fifo_runlist_func { + u8 size; + void (*chan)(struct gk104_fifo_chan *, + struct nvkm_memory *, u32 offset); + } *runlist; + struct gk104_fifo_chan_user { struct nvkm_sclass user; int (*ctor)(struct gk104_fifo *, const struct nvkm_oclass *, @@ -65,10 +71,14 @@ void gk104_fifo_runlist_remove(struct gk104_fifo *, struct gk104_fifo_chan *); void gk104_fifo_runlist_commit(struct gk104_fifo *, int runl); extern const struct nvkm_enum gk104_fifo_fault_access[]; + extern const struct nvkm_enum gk104_fifo_fault_engine[]; extern const struct nvkm_enum gk104_fifo_fault_reason[]; extern const struct nvkm_enum gk104_fifo_fault_hubclient[]; extern const struct nvkm_enum gk104_fifo_fault_gpcclient[]; +extern const struct gk104_fifo_runlist_func gk104_fifo_runlist; +void gk104_fifo_runlist_chan(struct gk104_fifo_chan *, + struct nvkm_memory *, u32); extern const struct nvkm_enum gm107_fifo_fault_engine[]; extern const struct nvkm_enum gp100_fifo_fault_engine[]; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c index 9611bf1ad0b0a..f7e1604795582 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c @@ -33,6 +33,7 @@ gk110_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, + .runlist = &gk104_fifo_runlist, .chan = {{0,0,KEPLER_CHANNEL_GPFIFO_B}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c index fabc690ddd56e..ff936ab6bf870 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c @@ -33,6 +33,7 @@ gk208_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, + .runlist = &gk104_fifo_runlist, .chan = {{0,0,KEPLER_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c index dee1bd76882a4..cb78d4df91822 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c @@ -31,6 +31,7 @@ gk20a_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, + .runlist = &gk104_fifo_runlist, .chan = {{0,0,KEPLER_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c index 09f97827167ab..f749d93a51c18 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c @@ -56,6 +56,7 @@ gm107_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, + .runlist = &gk104_fifo_runlist, .chan = {{0,0,KEPLER_CHANNEL_GPFIFO_B}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c index 052b7c2c5d764..3b97bd48697d3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c @@ -33,6 +33,7 @@ gm200_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, + .runlist = &gk104_fifo_runlist, .chan = {{0,0,MAXWELL_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c index 844787c6fb62b..c7e11a40f016d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c @@ -31,6 +31,7 @@ gm20b_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, + .runlist = &gk104_fifo_runlist, .chan = {{0,0,MAXWELL_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c index 2e31847e2e4fd..5c0cc40f7e3e0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c @@ -57,6 +57,7 @@ gp100_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, + .runlist = &gk104_fifo_runlist, .chan = {{0,0,PASCAL_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c index 38ab6e17ec157..fe3a8fad86208 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c @@ -31,6 +31,7 @@ gp10b_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, + .runlist = &gk104_fifo_runlist, .chan = {{0,0,PASCAL_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; From 4f2fc25c0f8bcc8db1b8a7b21e88c3d7f35c5acb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 034/165] drm/nouveau/fifo/gk104-: poll for runlist update completion Newer HW doesn't appear to send this event, which will cause long delays in runlist updates if they don't complete immediately. RM doesn't use these events anywhere, and an NVGPU commit message notes that polling is the preferred method even on HW that supports the event. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index afb3ed06ec89e..2b8e0d3d2d96c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -170,10 +170,10 @@ gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl) (target << 28)); nvkm_wr32(device, 0x002274, (runl << 20) | nr); - if (wait_event_timeout(fifo->runlist[runl].wait, - !(nvkm_rd32(device, 0x002284 + (runl * 0x08)) - & 0x00100000), - msecs_to_jiffies(2000)) == 0) + if (nvkm_msec(device, 2000, + if (!(nvkm_rd32(device, 0x002284 + (runl * 0x08)) & 0x00100000)) + break; + ) < 0) nvkm_error(subdev, "runlist %d update timeout\n", runl); unlock: mutex_unlock(&subdev->mutex); From 8c4e9f9dffb96a891d31e108b47f081233cb3e81 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 035/165] drm/nouveau/fifo/gk110-: support writing channel group runlist entries Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/fifo/cgrp.h | 11 ++++++++ .../drm/nouveau/nvkm/engine/fifo/changk104.h | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 26 +++++++++++++++++-- .../gpu/drm/nouveau/nvkm/engine/fifo/gk104.h | 9 ++++++- .../gpu/drm/nouveau/nvkm/engine/fifo/gk110.c | 21 ++++++++++++++- .../gpu/drm/nouveau/nvkm/engine/fifo/gk208.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/gm107.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/gm200.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/gp100.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c | 2 +- 12 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/cgrp.h diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/cgrp.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/cgrp.h new file mode 100644 index 0000000000000..d0ac60b067206 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/cgrp.h @@ -0,0 +1,11 @@ +#ifndef __NVKM_FIFO_CGRP_H__ +#define __NVKM_FIFO_CGRP_H__ +#include "priv.h" + +struct nvkm_fifo_cgrp { + int id; + struct list_head head; + struct list_head chan; + int chan_nr; +}; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h index 08b4415f0e24e..391e864c2a4a9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h @@ -10,6 +10,7 @@ struct gk104_fifo_chan { struct gk104_fifo *fifo; int runl; + struct nvkm_fifo_cgrp *cgrp; struct list_head head; bool killed; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index 2b8e0d3d2d96c..bc87f18c30928 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "gk104.h" +#include "cgrp.h" #include "changk104.h" #include @@ -145,6 +146,7 @@ gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl) struct nvkm_subdev *subdev = &fifo->base.engine.subdev; struct nvkm_device *device = subdev->device; struct nvkm_memory *mem; + struct nvkm_fifo_cgrp *cgrp; int nr = 0; int target; @@ -156,6 +158,13 @@ gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl) list_for_each_entry(chan, &fifo->runlist[runl].chan, head) { func->chan(chan, mem, nr++ * func->size); } + + list_for_each_entry(cgrp, &fifo->runlist[runl].cgrp, head) { + func->cgrp(cgrp, mem, nr++ * func->size); + list_for_each_entry(chan, &cgrp->chan, head) { + func->chan(chan, mem, nr++ * func->size); + } + } nvkm_done(mem); switch (nvkm_memory_target(mem)) { @@ -182,16 +191,28 @@ gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl) void gk104_fifo_runlist_remove(struct gk104_fifo *fifo, struct gk104_fifo_chan *chan) { + struct nvkm_fifo_cgrp *cgrp = chan->cgrp; mutex_lock(&fifo->base.engine.subdev.mutex); - list_del_init(&chan->head); + if (!list_empty(&chan->head)) { + list_del_init(&chan->head); + if (cgrp && !--cgrp->chan_nr) + list_del_init(&cgrp->head); + } mutex_unlock(&fifo->base.engine.subdev.mutex); } void gk104_fifo_runlist_insert(struct gk104_fifo *fifo, struct gk104_fifo_chan *chan) { + struct nvkm_fifo_cgrp *cgrp = chan->cgrp; mutex_lock(&fifo->base.engine.subdev.mutex); - list_add_tail(&chan->head, &fifo->runlist[chan->runl].chan); + if (cgrp) { + if (!cgrp->chan_nr++) + list_add_tail(&cgrp->head, &fifo->runlist[chan->runl].cgrp); + list_add_tail(&chan->head, &cgrp->chan); + } else { + list_add_tail(&chan->head, &fifo->runlist[chan->runl].chan); + } mutex_unlock(&fifo->base.engine.subdev.mutex); } @@ -898,6 +919,7 @@ gk104_fifo_oneinit(struct nvkm_fifo *base) } init_waitqueue_head(&fifo->runlist[i].wait); + INIT_LIST_HEAD(&fifo->runlist[i].cgrp); INIT_LIST_HEAD(&fifo->runlist[i].chan); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h index c32ea45f94564..dfb3da84c9d1c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h @@ -3,6 +3,7 @@ #define __GK104_FIFO_H__ #define gk104_fifo(p) container_of((p), struct gk104_fifo, base) #include "priv.h" +struct nvkm_fifo_cgrp; #include #include @@ -31,6 +32,7 @@ struct gk104_fifo { struct nvkm_memory *mem[2]; int next; wait_queue_head_t wait; + struct list_head cgrp; struct list_head chan; u32 engm; } runlist[16]; @@ -53,6 +55,8 @@ struct gk104_fifo_func { const struct gk104_fifo_runlist_func { u8 size; + void (*cgrp)(struct nvkm_fifo_cgrp *, + struct nvkm_memory *, u32 offset); void (*chan)(struct gk104_fifo_chan *, struct nvkm_memory *, u32 offset); } *runlist; @@ -71,7 +75,6 @@ void gk104_fifo_runlist_remove(struct gk104_fifo *, struct gk104_fifo_chan *); void gk104_fifo_runlist_commit(struct gk104_fifo *, int runl); extern const struct nvkm_enum gk104_fifo_fault_access[]; - extern const struct nvkm_enum gk104_fifo_fault_engine[]; extern const struct nvkm_enum gk104_fifo_fault_reason[]; extern const struct nvkm_enum gk104_fifo_fault_hubclient[]; @@ -80,6 +83,10 @@ extern const struct gk104_fifo_runlist_func gk104_fifo_runlist; void gk104_fifo_runlist_chan(struct gk104_fifo_chan *, struct nvkm_memory *, u32); +extern const struct gk104_fifo_runlist_func gk110_fifo_runlist; +void gk110_fifo_runlist_cgrp(struct nvkm_fifo_cgrp *, + struct nvkm_memory *, u32); + extern const struct nvkm_enum gm107_fifo_fault_engine[]; extern const struct nvkm_enum gp100_fifo_fault_engine[]; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c index f7e1604795582..ac7655a130fbd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c @@ -22,10 +22,29 @@ * Authors: Ben Skeggs */ #include "gk104.h" +#include "cgrp.h" #include "changk104.h" +#include + #include +void +gk110_fifo_runlist_cgrp(struct nvkm_fifo_cgrp *cgrp, + struct nvkm_memory *memory, u32 offset) +{ + nvkm_wo32(memory, offset + 0, (cgrp->chan_nr << 26) | (128 << 18) | + (3 << 14) | 0x00002000 | cgrp->id); + nvkm_wo32(memory, offset + 4, 0x00000000); +} + +const struct gk104_fifo_runlist_func +gk110_fifo_runlist = { + .size = 8, + .cgrp = gk110_fifo_runlist_cgrp, + .chan = gk104_fifo_runlist_chan, +}; + static const struct gk104_fifo_func gk110_fifo = { .fault.access = gk104_fifo_fault_access, @@ -33,7 +52,7 @@ gk110_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .runlist = &gk104_fifo_runlist, + .runlist = &gk110_fifo_runlist, .chan = {{0,0,KEPLER_CHANNEL_GPFIFO_B}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c index ff936ab6bf870..b7385cd70b25e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c @@ -33,7 +33,7 @@ gk208_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .runlist = &gk104_fifo_runlist, + .runlist = &gk110_fifo_runlist, .chan = {{0,0,KEPLER_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c index cb78d4df91822..15cc80c02649f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c @@ -31,7 +31,7 @@ gk20a_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .runlist = &gk104_fifo_runlist, + .runlist = &gk110_fifo_runlist, .chan = {{0,0,KEPLER_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c index f749d93a51c18..99b89f6ae34bb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c @@ -56,7 +56,7 @@ gm107_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .runlist = &gk104_fifo_runlist, + .runlist = &gk110_fifo_runlist, .chan = {{0,0,KEPLER_CHANNEL_GPFIFO_B}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c index 3b97bd48697d3..16fd8de135a7b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c @@ -33,7 +33,7 @@ gm200_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .runlist = &gk104_fifo_runlist, + .runlist = &gk110_fifo_runlist, .chan = {{0,0,MAXWELL_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c index c7e11a40f016d..bfa5fa5bc5e52 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c @@ -31,7 +31,7 @@ gm20b_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .runlist = &gk104_fifo_runlist, + .runlist = &gk110_fifo_runlist, .chan = {{0,0,MAXWELL_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c index 5c0cc40f7e3e0..c2852943fc3c1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c @@ -57,7 +57,7 @@ gp100_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .runlist = &gk104_fifo_runlist, + .runlist = &gk110_fifo_runlist, .chan = {{0,0,PASCAL_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c index fe3a8fad86208..29a4029694def 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c @@ -31,7 +31,7 @@ gp10b_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .runlist = &gk104_fifo_runlist, + .runlist = &gk110_fifo_runlist, .chan = {{0,0,PASCAL_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; From 79bb4b617f965736d2e1c616235302c1d0e823b2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 036/165] drm/nouveau/fifo/gk208-: write pbdma timeout regs during initialisation Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 3 +++ drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h | 4 ++++ drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c | 11 +++++++++++ drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c | 1 + 9 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index bc87f18c30928..5c22ce9165308 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -962,6 +962,9 @@ gk104_fifo_init(struct nvkm_fifo *base) nvkm_wr32(device, 0x002254, 0x10000000 | fifo->user.bar->addr >> 12); + if (fifo->func->init_pbdma_timeout) + fifo->func->init_pbdma_timeout(fifo); + nvkm_wr32(device, 0x002100, 0xffffffff); nvkm_wr32(device, 0x002140, 0x7fffffff); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h index dfb3da84c9d1c..e232cee1b83c4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h @@ -45,6 +45,8 @@ struct gk104_fifo { }; struct gk104_fifo_func { + void (*init_pbdma_timeout)(struct gk104_fifo *); + struct { const struct nvkm_enum *access; const struct nvkm_enum *engine; @@ -87,6 +89,8 @@ extern const struct gk104_fifo_runlist_func gk110_fifo_runlist; void gk110_fifo_runlist_cgrp(struct nvkm_fifo_cgrp *, struct nvkm_memory *, u32); +void gk208_fifo_init_pbdma_timeout(struct gk104_fifo *); + extern const struct nvkm_enum gm107_fifo_fault_engine[]; extern const struct nvkm_enum gp100_fifo_fault_engine[]; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c index b7385cd70b25e..5ea7e452cc660 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c @@ -26,8 +26,19 @@ #include +void +gk208_fifo_init_pbdma_timeout(struct gk104_fifo *fifo) +{ + struct nvkm_device *device = fifo->base.engine.subdev.device; + int i; + + for (i = 0; i < fifo->pbdma_nr; i++) + nvkm_wr32(device, 0x04012c + (i * 0x2000), 0x0000ffff); +} + static const struct gk104_fifo_func gk208_fifo = { + .init_pbdma_timeout = gk208_fifo_init_pbdma_timeout, .fault.access = gk104_fifo_fault_access, .fault.engine = gk104_fifo_fault_engine, .fault.reason = gk104_fifo_fault_reason, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c index 15cc80c02649f..535a0eb67a5fc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c @@ -26,6 +26,7 @@ static const struct gk104_fifo_func gk20a_fifo = { + .init_pbdma_timeout = gk208_fifo_init_pbdma_timeout, .fault.access = gk104_fifo_fault_access, .fault.engine = gk104_fifo_fault_engine, .fault.reason = gk104_fifo_fault_reason, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c index 99b89f6ae34bb..a28f5d213d6e1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c @@ -51,6 +51,7 @@ gm107_fifo_fault_engine[] = { static const struct gk104_fifo_func gm107_fifo = { + .init_pbdma_timeout = gk208_fifo_init_pbdma_timeout, .fault.access = gk104_fifo_fault_access, .fault.engine = gm107_fifo_fault_engine, .fault.reason = gk104_fifo_fault_reason, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c index 16fd8de135a7b..0bd87a0b25e8a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c @@ -28,6 +28,7 @@ static const struct gk104_fifo_func gm200_fifo = { + .init_pbdma_timeout = gk208_fifo_init_pbdma_timeout, .fault.access = gk104_fifo_fault_access, .fault.engine = gm107_fifo_fault_engine, .fault.reason = gk104_fifo_fault_reason, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c index bfa5fa5bc5e52..32a8e3deb87d3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c @@ -26,6 +26,7 @@ static const struct gk104_fifo_func gm20b_fifo = { + .init_pbdma_timeout = gk208_fifo_init_pbdma_timeout, .fault.access = gk104_fifo_fault_access, .fault.engine = gm107_fifo_fault_engine, .fault.reason = gk104_fifo_fault_reason, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c index c2852943fc3c1..69b201f29cd56 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c @@ -52,6 +52,7 @@ gp100_fifo_fault_engine[] = { static const struct gk104_fifo_func gp100_fifo = { + .init_pbdma_timeout = gk208_fifo_init_pbdma_timeout, .fault.access = gk104_fifo_fault_access, .fault.engine = gp100_fifo_fault_engine, .fault.reason = gk104_fifo_fault_reason, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c index 29a4029694def..fac7be50376c7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c @@ -26,6 +26,7 @@ static const struct gk104_fifo_func gp10b_fifo = { + .init_pbdma_timeout = gk208_fifo_init_pbdma_timeout, .fault.access = gk104_fifo_fault_access, .fault.engine = gp100_fifo_fault_engine, .fault.reason = gk104_fifo_fault_reason, From eda12417d3daf6cb37f41e9b1c46854e7dd75e91 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 037/165] drm/nouveau/fifo/gm107-: write instance address in channel runlist entry RM does this for some reason. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/fifo/gk104.h | 2 ++ .../gpu/drm/nouveau/nvkm/engine/fifo/gm107.c | 19 ++++++++++++++++++- .../gpu/drm/nouveau/nvkm/engine/fifo/gm200.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/gp100.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c | 2 +- 6 files changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h index e232cee1b83c4..1d70a5dc07622 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h @@ -92,5 +92,7 @@ void gk110_fifo_runlist_cgrp(struct nvkm_fifo_cgrp *, void gk208_fifo_init_pbdma_timeout(struct gk104_fifo *); extern const struct nvkm_enum gm107_fifo_fault_engine[]; +extern const struct gk104_fifo_runlist_func gm107_fifo_runlist; + extern const struct nvkm_enum gp100_fifo_fault_engine[]; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c index a28f5d213d6e1..79ae19b1db673 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c @@ -24,8 +24,25 @@ #include "gk104.h" #include "changk104.h" +#include + #include +static void +gm107_fifo_runlist_chan(struct gk104_fifo_chan *chan, + struct nvkm_memory *memory, u32 offset) +{ + nvkm_wo32(memory, offset + 0, chan->base.chid); + nvkm_wo32(memory, offset + 4, chan->base.inst->addr >> 12); +} + +const struct gk104_fifo_runlist_func +gm107_fifo_runlist = { + .size = 8, + .cgrp = gk110_fifo_runlist_cgrp, + .chan = gm107_fifo_runlist_chan, +}; + const struct nvkm_enum gm107_fifo_fault_engine[] = { { 0x01, "DISPLAY" }, @@ -57,7 +74,7 @@ gm107_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .runlist = &gk110_fifo_runlist, + .runlist = &gm107_fifo_runlist, .chan = {{0,0,KEPLER_CHANNEL_GPFIFO_B}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c index 0bd87a0b25e8a..49565faa854d0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c @@ -34,7 +34,7 @@ gm200_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .runlist = &gk110_fifo_runlist, + .runlist = &gm107_fifo_runlist, .chan = {{0,0,MAXWELL_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c index 32a8e3deb87d3..46736513bd11a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c @@ -32,7 +32,7 @@ gm20b_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .runlist = &gk110_fifo_runlist, + .runlist = &gm107_fifo_runlist, .chan = {{0,0,MAXWELL_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c index 69b201f29cd56..f137baed7a614 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c @@ -58,7 +58,7 @@ gp100_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .runlist = &gk110_fifo_runlist, + .runlist = &gm107_fifo_runlist, .chan = {{0,0,PASCAL_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c index fac7be50376c7..787e911d95996 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c @@ -32,7 +32,7 @@ gp10b_fifo = { .fault.reason = gk104_fifo_fault_reason, .fault.hubclient = gk104_fifo_fault_hubclient, .fault.gpcclient = gk104_fifo_fault_gpcclient, - .runlist = &gk110_fifo_runlist, + .runlist = &gm107_fifo_runlist, .chan = {{0,0,PASCAL_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, }; From 334cc26d4db10ae7d8f18de27869b95fe84c7d28 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 038/165] drm/nouveau/fifo/gp100-: force individual channels into a channel group RM does this for some reason, and is enforced in HW on Volta. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 37 +++++++++++++++---- .../gpu/drm/nouveau/nvkm/engine/fifo/gk104.h | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/gp100.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c | 1 + .../nouveau/nvkm/engine/fifo/gpfifogk104.c | 28 ++++++++++++-- 5 files changed, 57 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index 5c22ce9165308..767e0ab44cb83 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -285,6 +285,32 @@ gk104_fifo_recover_runl(struct gk104_fifo *fifo, int runl) schedule_work(&fifo->recover.work); } +static struct gk104_fifo_chan * +gk104_fifo_recover_chid(struct gk104_fifo *fifo, int runl, int chid) +{ + struct gk104_fifo_chan *chan; + struct nvkm_fifo_cgrp *cgrp; + + list_for_each_entry(chan, &fifo->runlist[runl].chan, head) { + if (chan->base.chid == chid) { + list_del_init(&chan->head); + return chan; + } + } + + list_for_each_entry(cgrp, &fifo->runlist[runl].cgrp, head) { + if (cgrp->id == chid) { + chan = list_first_entry(&cgrp->chan, typeof(*chan), head); + list_del_init(&chan->head); + if (!--cgrp->chan_nr) + list_del_init(&cgrp->head); + return chan; + } + } + + return NULL; +} + static void gk104_fifo_recover_chan(struct nvkm_fifo *base, int chid) { @@ -302,13 +328,10 @@ gk104_fifo_recover_chan(struct nvkm_fifo *base, int chid) return; /* Lookup SW state for channel, and mark it as dead. */ - list_for_each_entry(chan, &fifo->runlist[runl].chan, head) { - if (chan->base.chid == chid) { - list_del_init(&chan->head); - chan->killed = true; - nvkm_fifo_kevent(&fifo->base, chid); - break; - } + chan = gk104_fifo_recover_chid(fifo, runl, chid); + if (chan) { + chan->killed = true; + nvkm_fifo_kevent(&fifo->base, chid); } /* Disable channel. */ diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h index 1d70a5dc07622..1d182d8d2fcee 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h @@ -68,6 +68,7 @@ struct gk104_fifo_func { int (*ctor)(struct gk104_fifo *, const struct nvkm_oclass *, void *, u32, struct nvkm_object **); } chan; + bool cgrp_force; }; int gk104_fifo_new_(const struct gk104_fifo_func *, struct nvkm_device *, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c index f137baed7a614..e2f8f9087d7c8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c @@ -60,6 +60,7 @@ gp100_fifo = { .fault.gpcclient = gk104_fifo_fault_gpcclient, .runlist = &gm107_fifo_runlist, .chan = {{0,0,PASCAL_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, + .cgrp_force = true, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c index 787e911d95996..7733bf7c6545c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp10b.c @@ -34,6 +34,7 @@ gp10b_fifo = { .fault.gpcclient = gk104_fifo_fault_gpcclient, .runlist = &gm107_fifo_runlist, .chan = {{0,0,PASCAL_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, + .cgrp_force = true, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c index f7a4e0e86b23a..60e7d72d6e461 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "changk104.h" +#include "cgrp.h" #include #include @@ -40,16 +41,21 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan) struct nvkm_subdev *subdev = &fifo->base.engine.subdev; struct nvkm_device *device = subdev->device; struct nvkm_client *client = chan->base.object.client; + struct nvkm_fifo_cgrp *cgrp = chan->cgrp; int ret = 0; mutex_lock(&subdev->mutex); - nvkm_wr32(device, 0x002634, chan->base.chid); + if (cgrp) + nvkm_wr32(device, 0x002634, cgrp->id | 0x01000000); + else + nvkm_wr32(device, 0x002634, chan->base.chid); if (nvkm_msec(device, 2000, if (!(nvkm_rd32(device, 0x002634) & 0x00100000)) break; ) < 0) { - nvkm_error(subdev, "channel %d [%s] kick timeout\n", - chan->base.chid, client->name); + nvkm_error(subdev, "%s %d [%s] kick timeout\n", + cgrp ? "tsg" : "channel", + cgrp ? cgrp->id : chan->base.chid, client->name); nvkm_fifo_recover_chan(&fifo->base, chan->base.chid); ret = -ETIMEDOUT; } @@ -207,7 +213,9 @@ gk104_fifo_gpfifo_init(struct nvkm_fifo_chan *base) static void * gk104_fifo_gpfifo_dtor(struct nvkm_fifo_chan *base) { - return gk104_fifo_chan(base); + struct gk104_fifo_chan *chan = gk104_fifo_chan(base); + kfree(chan->cgrp); + return chan; } static const struct nvkm_fifo_chan_func @@ -264,6 +272,18 @@ gk104_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid, *chid = chan->base.chid; + /* Hack to support GPUs where even individual channels should be + * part of a channel group. + */ + if (fifo->func->cgrp_force) { + if (!(chan->cgrp = kmalloc(sizeof(*chan->cgrp), GFP_KERNEL))) + return -ENOMEM; + chan->cgrp->id = chan->base.chid; + INIT_LIST_HEAD(&chan->cgrp->head); + INIT_LIST_HEAD(&chan->cgrp->chan); + chan->cgrp->chan_nr = 0; + } + /* Clear channel control registers. */ usermem = chan->base.chid * 0x200; ilength = order_base_2(ilength / 8); From 1246f1dc224a2c4ab61a1454cff669918b92e9da Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 039/165] drm/nouveau/gr/gf100-: virtualise init_gpc_mmu + apply fixes from traces Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 21 +++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 2f8dc107047dc..5be4111b06686 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1920,7 +1920,7 @@ gf100_gr_init_gpc_mmu(struct gf100_gr *gr) struct nvkm_fb *fb = device->fb; nvkm_wr32(device, 0x418880, nvkm_rd32(device, 0x100c80) & 0x00000001); - nvkm_wr32(device, 0x4188a4, 0x00000000); + nvkm_wr32(device, 0x4188a4, 0x03000000); nvkm_wr32(device, 0x418888, 0x00000000); nvkm_wr32(device, 0x41888c, 0x00000000); nvkm_wr32(device, 0x418890, 0x00000000); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index 2c67fac576d1f..5ea74f62cee4f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -308,22 +308,30 @@ gm107_gr_init_bios(struct gf100_gr *gr) } } +static void +gm107_gr_init_gpc_mmu(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + struct nvkm_fb *fb = device->fb; + + nvkm_wr32(device, GPC_BCAST(0x0880), 0x00000000); + nvkm_wr32(device, GPC_BCAST(0x0890), 0x00000000); + nvkm_wr32(device, GPC_BCAST(0x0894), 0x00000000); + nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(fb->mmu_wr) >> 8); + nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(fb->mmu_rd) >> 8); +} + static int gm107_gr_init(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; - struct nvkm_fb *fb = device->fb; const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); u32 data[TPC_MAX / 8] = {}; u8 tpcnr[GPC_MAX]; int gpc, tpc, rop; int i; - nvkm_wr32(device, GPC_BCAST(0x0880), 0x00000000); - nvkm_wr32(device, GPC_BCAST(0x0890), 0x00000000); - nvkm_wr32(device, GPC_BCAST(0x0894), 0x00000000); - nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(fb->mmu_wr) >> 8); - nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(fb->mmu_rd) >> 8); + gr->func->init_gpc_mmu(gr); gf100_gr_mmio(gr, gr->func->mmio); @@ -442,6 +450,7 @@ gm107_gr_gpccs_ucode = { static const struct gf100_gr_func gm107_gr = { .init = gm107_gr_init, + .init_gpc_mmu = gm107_gr_init_gpc_mmu, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gm107_gr_pack_mmio, From 6f63a5fb1ec37cd55d7c886ac7d76f95a4cea2ce Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 040/165] drm/nouveau/gr/gf100-: support firmware-provided sw_nonctx everywhere Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 5be4111b06686..eb50cfc1b53fc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1941,7 +1941,10 @@ gf100_gr_init(struct gf100_gr *gr) gr->func->init_gpc_mmu(gr); - gf100_gr_mmio(gr, gr->func->mmio); + if (gr->fuc_sw_nonctx) + gf100_gr_mmio(gr, gr->fuc_sw_nonctx); + else + gf100_gr_mmio(gr, gr->func->mmio); nvkm_mask(device, TPC_UNIT(0, 0, 0x05c), 0x00000001, 0x00000001); From 8b058ca5186535163bdcc55d81a9f341c71139f6 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 041/165] drm/nouveau/gr/gf100-: virtualise r405a14 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 3 +++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c | 7 +++++++ 3 files changed, 11 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index eb50cfc1b53fc..d127c6a7363cb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1946,6 +1946,9 @@ gf100_gr_init(struct gf100_gr *gr) else gf100_gr_mmio(gr, gr->func->mmio); + if (gr->func->init_r405a14) + gr->func->init_r405a14(gr); + nvkm_mask(device, TPC_UNIT(0, 0, 0x05c), 0x00000001, 0x00000001); memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index c8ec3fd971559..d940a1a239e8d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -122,6 +122,7 @@ struct gf100_gr_func { void (*dtor)(struct gf100_gr *); int (*init)(struct gf100_gr *); void (*init_gpc_mmu)(struct gf100_gr *); + void (*init_r405a14)(struct gf100_gr *); void (*init_rop_active_fbps)(struct gf100_gr *); void (*init_ppc_exceptions)(struct gf100_gr *); void (*init_swdx_pes_mask)(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c index cc152eb741235..3a59dea5ad7a2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c @@ -103,10 +103,17 @@ gf108_gr_pack_mmio[] = { * PGRAPH engine/subdev functions ******************************************************************************/ +static void +gf108_gr_init_r405a14(struct gf100_gr *gr) +{ + nvkm_wr32(gr->base.engine.subdev.device, 0x405a14, 0x80000000); +} + static const struct gf100_gr_func gf108_gr = { .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, + .init_r405a14 = gf108_gr_init_r405a14, .mmio = gf108_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, From cd9662f89e2cd953ce9b2fcf02fdaae847592bd1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 042/165] drm/nouveau/gr/gf100-: support clkgate_pack everywhere Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index d127c6a7363cb..eaf32f79ee470 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -1949,6 +1950,9 @@ gf100_gr_init(struct gf100_gr *gr) if (gr->func->init_r405a14) gr->func->init_r405a14(gr); + if (gr->func->clkgate_pack) + nvkm_therm_clkgate_init(device->therm, gr->func->clkgate_pack); + nvkm_mask(device, TPC_UNIT(0, 0, 0x05c), 0x00000001, 0x00000001); memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); From a37279e94c91e3b30ee50dfd96f8f33f3be43f17 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 043/165] drm/nouveau/gr/gf100-: virtualise init_bios Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 3 +++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c | 5 +++-- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index eaf32f79ee470..6ecb4a05096d5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1953,6 +1953,9 @@ gf100_gr_init(struct gf100_gr *gr) if (gr->func->clkgate_pack) nvkm_therm_clkgate_init(device->therm, gr->func->clkgate_pack); + if (gr->func->init_bios) + gr->func->init_bios(gr); + nvkm_mask(device, TPC_UNIT(0, 0, 0x05c), 0x00000001, 0x00000001); memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index d940a1a239e8d..1320befd4f10c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -123,6 +123,7 @@ struct gf100_gr_func { int (*init)(struct gf100_gr *); void (*init_gpc_mmu)(struct gf100_gr *); void (*init_r405a14)(struct gf100_gr *); + void (*init_bios)(struct gf100_gr *); void (*init_rop_active_fbps)(struct gf100_gr *); void (*init_ppc_exceptions)(struct gf100_gr *); void (*init_swdx_pes_mask)(struct gf100_gr *); @@ -151,7 +152,6 @@ void gk104_gr_init_ppc_exceptions(struct gf100_gr *); int gk20a_gr_init(struct gf100_gr *); -int gm200_gr_init(struct gf100_gr *); int gm200_gr_rops(struct gf100_gr *); int gp100_gr_init(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index 5ea74f62cee4f..d5629cdddf4a6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -335,7 +335,7 @@ gm107_gr_init(struct gf100_gr *gr) gf100_gr_mmio(gr, gr->func->mmio); - gm107_gr_init_bios(gr); + gr->func->init_bios(gr); nvkm_wr32(device, GPC_UNIT(0, 0x3018), 0x00000001); @@ -451,6 +451,7 @@ static const struct gf100_gr_func gm107_gr = { .init = gm107_gr_init, .init_gpc_mmu = gm107_gr_init_gpc_mmu, + .init_bios = gm107_gr_init_bios, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gm107_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index 6435f12575723..7a793a0bb28ed 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -61,7 +61,7 @@ gm200_gr_init_rop_active_fbps(struct gf100_gr *gr) nvkm_mask(device, 0x408958, 0x0000000f, fbp_count); /* crop */ } -int +static int gm200_gr_init(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; @@ -75,7 +75,7 @@ gm200_gr_init(struct gf100_gr *gr) gf100_gr_mmio(gr, gr->fuc_sw_nonctx); - gm107_gr_init_bios(gr); + gr->func->init_bios(gr); nvkm_wr32(device, GPC_UNIT(0, 0x3018), 0x00000001); @@ -210,6 +210,7 @@ static const struct gf100_gr_func gm200_gr = { .init = gm200_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, + .init_bios = gm107_gr_init_bios, .init_rop_active_fbps = gm200_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, From 2fe5ff6371350ce224dc2cc1da0e01888a1f9999 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 044/165] drm/nouveau/gr/gf100-: virtualise init_vsc_stream_master Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 10 +++++++++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 5 ++++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 10 +++++++++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c | 1 + 17 files changed, 39 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 6ecb4a05096d5..0c92b8c6375a3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1930,6 +1930,13 @@ gf100_gr_init_gpc_mmu(struct gf100_gr *gr) nvkm_wr32(device, 0x4188b8, nvkm_memory_addr(fb->mmu_rd) >> 8); } +void +gf100_gr_init_vsc_stream_master(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_mask(device, TPC_UNIT(0, 0, 0x05c), 0x00000001, 0x00000001); +} + int gf100_gr_init(struct gf100_gr *gr) { @@ -1956,7 +1963,7 @@ gf100_gr_init(struct gf100_gr *gr) if (gr->func->init_bios) gr->func->init_bios(gr); - nvkm_mask(device, TPC_UNIT(0, 0, 0x05c), 0x00000001, 0x00000001); + gr->func->init_vsc_stream_master(gr); memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); for (i = 0, gpc = -1; i < gr->tpc_total; i++) { @@ -2068,6 +2075,7 @@ static const struct gf100_gr_func gf100_gr = { .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, + .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, .mmio = gf100_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 1320befd4f10c..45792a33fd657 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -124,6 +124,7 @@ struct gf100_gr_func { void (*init_gpc_mmu)(struct gf100_gr *); void (*init_r405a14)(struct gf100_gr *); void (*init_bios)(struct gf100_gr *); + void (*init_vsc_stream_master)(struct gf100_gr *); void (*init_rop_active_fbps)(struct gf100_gr *); void (*init_ppc_exceptions)(struct gf100_gr *); void (*init_swdx_pes_mask)(struct gf100_gr *); @@ -143,10 +144,12 @@ struct gf100_gr_func { struct nvkm_sclass sclass[]; }; -int gf100_gr_init(struct gf100_gr *); int gf100_gr_rops(struct gf100_gr *); +int gf100_gr_init(struct gf100_gr *); +void gf100_gr_init_vsc_stream_master(struct gf100_gr *); int gk104_gr_init(struct gf100_gr *); +void gk104_gr_init_vsc_stream_master(struct gf100_gr *); void gk104_gr_init_rop_active_fbps(struct gf100_gr *); void gk104_gr_init_ppc_exceptions(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c index ec0f11983b233..61b27b179e15d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c @@ -116,6 +116,7 @@ static const struct gf100_gr_func gf104_gr = { .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, + .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, .mmio = gf104_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c index 3a59dea5ad7a2..992727f79439f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c @@ -114,6 +114,7 @@ gf108_gr = { .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_r405a14 = gf108_gr_init_r405a14, + .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, .mmio = gf108_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c index 10d2d73ca8c3a..07a57cc5074fb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c @@ -88,6 +88,7 @@ static const struct gf100_gr_func gf110_gr = { .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, + .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, .mmio = gf110_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c index ac09a07c4150b..29ab01be71ec0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c @@ -124,6 +124,7 @@ static const struct gf100_gr_func gf117_gr = { .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, + .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, .mmio = gf117_gr_pack_mmio, .fecs.ucode = &gf117_gr_fecs_ucode, .gpccs.ucode = &gf117_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c index 7f449ec6f7603..d3b06dd7702d8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c @@ -179,6 +179,7 @@ static const struct gf100_gr_func gf119_gr = { .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, + .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, .mmio = gf119_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index 1b52fcb2c49a2..835f498d6b98a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -404,6 +404,13 @@ gk104_gr_init_ppc_exceptions(struct gf100_gr *gr) } } +void +gk104_gr_init_vsc_stream_master(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_wr32(device, GPC_UNIT(0, 0x3018), 0x00000001); +} + int gk104_gr_init(struct gf100_gr *gr) { @@ -421,7 +428,7 @@ gk104_gr_init(struct gf100_gr *gr) nvkm_therm_clkgate_init(gr->base.engine.subdev.device->therm, gr->func->clkgate_pack); - nvkm_wr32(device, GPC_UNIT(0, 0x3018), 0x00000001); + gr->func->init_vsc_stream_master(gr); memset(data, 0x00, sizeof(data)); memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); @@ -536,6 +543,7 @@ static const struct gf100_gr_func gk104_gr = { .init = gk104_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, + .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk104_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index 4da916a9fc73d..eef7476e0ee89 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -338,6 +338,7 @@ static const struct gf100_gr_func gk110_gr = { .init = gk104_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, + .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk110_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index 1912c0bfd7eed..ed4361a830a5e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c @@ -104,6 +104,7 @@ static const struct gf100_gr_func gk110b_gr = { .init = gk104_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, + .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk110b_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c index 1fc258163f25a..4c8beb9c17085 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c @@ -163,6 +163,7 @@ static const struct gf100_gr_func gk208_gr = { .init = gk104_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, + .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk208_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index d5629cdddf4a6..58c03d6c1c2dc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -337,7 +337,7 @@ gm107_gr_init(struct gf100_gr *gr) gr->func->init_bios(gr); - nvkm_wr32(device, GPC_UNIT(0, 0x3018), 0x00000001); + gr->func->init_vsc_stream_master(gr); memset(data, 0x00, sizeof(data)); memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); @@ -452,6 +452,7 @@ gm107_gr = { .init = gm107_gr_init, .init_gpc_mmu = gm107_gr_init_gpc_mmu, .init_bios = gm107_gr_init_bios, + .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gm107_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index 7a793a0bb28ed..8583aad367afc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -77,7 +77,7 @@ gm200_gr_init(struct gf100_gr *gr) gr->func->init_bios(gr); - nvkm_wr32(device, GPC_UNIT(0, 0x3018), 0x00000001); + gr->func->init_vsc_stream_master(gr); memset(data, 0x00, sizeof(data)); memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); @@ -211,6 +211,7 @@ gm200_gr = { .init = gm200_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_bios = gm107_gr_init_bios, + .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_rop_active_fbps = gm200_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c index 867a5f7cc5bce..edaaebbe76131 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c @@ -63,7 +63,7 @@ gp100_gr_init(struct gf100_gr *gr) gf100_gr_mmio(gr, gr->fuc_sw_nonctx); - nvkm_wr32(device, GPC_UNIT(0, 0x3018), 0x00000001); + gr->func->init_vsc_stream_master(gr); memset(data, 0x00, sizeof(data)); memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); @@ -160,6 +160,7 @@ static const struct gf100_gr_func gp100_gr = { .init = gp100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, + .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_num_active_ltcs = gp100_gr_init_num_active_ltcs, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c index 61e3a0b085595..821a6c4589e23 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c @@ -44,6 +44,7 @@ static const struct gf100_gr_func gp102_gr = { .init = gp100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, + .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_swdx_pes_mask = gp102_gr_init_swdx_pes_mask, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c index f7272323f694a..e2e12975bb2cb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c @@ -30,6 +30,7 @@ static const struct gf100_gr_func gp107_gr = { .init = gp100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, + .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_swdx_pes_mask = gp102_gr_init_swdx_pes_mask, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c index 5f3d161a0842d..e90cc3c845ec4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c @@ -37,6 +37,7 @@ static const struct gf100_gr_func gp10b_gr = { .init = gp100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, + .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_num_active_ltcs = gp10b_gr_init_num_active_ltcs, From 02917aa39d56f504b47354135120000da1efa760 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 045/165] drm/nouveau/gr/gf100-: virtualise init_zcull Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 62 +++++++++---------- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 4 ++ .../gpu/drm/nouveau/nvkm/engine/gr/gf104.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf108.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf110.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf117.c | 29 +++++++++ .../gpu/drm/nouveau/nvkm/engine/gr/gf119.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 31 +--------- .../gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk208.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk20a.c | 33 +--------- .../gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 31 +--------- .../gpu/drm/nouveau/nvkm/engine/gr/gm200.c | 31 +--------- .../gpu/drm/nouveau/nvkm/engine/gr/gm20b.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp100.c | 31 +--------- .../gpu/drm/nouveau/nvkm/engine/gr/gp102.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp107.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp10b.c | 1 + 19 files changed, 85 insertions(+), 178 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 0c92b8c6375a3..56d9ead0b3801 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1930,6 +1930,34 @@ gf100_gr_init_gpc_mmu(struct gf100_gr *gr) nvkm_wr32(device, 0x4188b8, nvkm_memory_addr(fb->mmu_rd) >> 8); } +void +gf100_gr_init_zcull(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); + u32 data[TPC_MAX / 8] = {}; + u8 tpcnr[GPC_MAX]; + int gpc, tpc; + int i; + + memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); + for (i = 0, gpc = -1; i < gr->tpc_total; i++) { + do { + gpc = (gpc + 1) % gr->gpc_nr; + } while (!tpcnr[gpc]); + tpc = gr->tpc_nr[gpc] - tpcnr[gpc]--; + + data[i / 8] |= tpc << ((i % 8) * 4); + } + + nvkm_wr32(device, GPC_BCAST(0x0980), data[0]); + nvkm_wr32(device, GPC_BCAST(0x0984), data[1]); + nvkm_wr32(device, GPC_BCAST(0x0988), data[2]); + nvkm_wr32(device, GPC_BCAST(0x098c), data[3]); + + nvkm_wr32(device, GPC_BCAST(0x1bd4), magicgpc918); +} + void gf100_gr_init_vsc_stream_master(struct gf100_gr *gr) { @@ -1941,11 +1969,7 @@ int gf100_gr_init(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; - const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); - u32 data[TPC_MAX / 8] = {}; - u8 tpcnr[GPC_MAX]; int gpc, tpc, rop; - int i; gr->func->init_gpc_mmu(gr); @@ -1964,34 +1988,7 @@ gf100_gr_init(struct gf100_gr *gr) gr->func->init_bios(gr); gr->func->init_vsc_stream_master(gr); - - memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); - for (i = 0, gpc = -1; i < gr->tpc_total; i++) { - do { - gpc = (gpc + 1) % gr->gpc_nr; - } while (!tpcnr[gpc]); - tpc = gr->tpc_nr[gpc] - tpcnr[gpc]--; - - data[i / 8] |= tpc << ((i % 8) * 4); - } - - nvkm_wr32(device, GPC_BCAST(0x0980), data[0]); - nvkm_wr32(device, GPC_BCAST(0x0984), data[1]); - nvkm_wr32(device, GPC_BCAST(0x0988), data[2]); - nvkm_wr32(device, GPC_BCAST(0x098c), data[3]); - - for (gpc = 0; gpc < gr->gpc_nr; gpc++) { - nvkm_wr32(device, GPC_UNIT(gpc, 0x0914), - gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 | - gr->tpc_total); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918); - } - - if (device->chipset != 0xd7) - nvkm_wr32(device, GPC_BCAST(0x1bd4), magicgpc918); - else - nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918); + gr->func->init_zcull(gr); nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800)); @@ -2076,6 +2073,7 @@ gf100_gr = { .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, + .init_zcull = gf100_gr_init_zcull, .mmio = gf100_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 45792a33fd657..b322dc4247610 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -125,6 +125,7 @@ struct gf100_gr_func { void (*init_r405a14)(struct gf100_gr *); void (*init_bios)(struct gf100_gr *); void (*init_vsc_stream_master)(struct gf100_gr *); + void (*init_zcull)(struct gf100_gr *); void (*init_rop_active_fbps)(struct gf100_gr *); void (*init_ppc_exceptions)(struct gf100_gr *); void (*init_swdx_pes_mask)(struct gf100_gr *); @@ -147,6 +148,9 @@ struct gf100_gr_func { int gf100_gr_rops(struct gf100_gr *); int gf100_gr_init(struct gf100_gr *); void gf100_gr_init_vsc_stream_master(struct gf100_gr *); +void gf100_gr_init_zcull(struct gf100_gr *); + +void gf117_gr_init_zcull(struct gf100_gr *); int gk104_gr_init(struct gf100_gr *); void gk104_gr_init_vsc_stream_master(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c index 61b27b179e15d..23c2613fa6bfa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c @@ -117,6 +117,7 @@ gf104_gr = { .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, + .init_zcull = gf100_gr_init_zcull, .mmio = gf104_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c index 992727f79439f..a79a7860732a9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c @@ -115,6 +115,7 @@ gf108_gr = { .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_r405a14 = gf108_gr_init_r405a14, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, + .init_zcull = gf100_gr_init_zcull, .mmio = gf108_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c index 07a57cc5074fb..fd8e13716d94f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c @@ -89,6 +89,7 @@ gf110_gr = { .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, + .init_zcull = gf100_gr_init_zcull, .mmio = gf110_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c index 29ab01be71ec0..01e213e4d1a90 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c @@ -120,11 +120,40 @@ gf117_gr_gpccs_ucode = { .data.size = sizeof(gf117_grgpc_data), }; +void +gf117_gr_init_zcull(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); + u32 data[TPC_MAX / 8] = {}; + u8 tpcnr[GPC_MAX]; + int gpc, tpc; + int i; + + memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); + for (i = 0, gpc = -1; i < gr->tpc_total; i++) { + do { + gpc = (gpc + 1) % gr->gpc_nr; + } while (!tpcnr[gpc]); + tpc = gr->tpc_nr[gpc] - tpcnr[gpc]--; + + data[i / 8] |= tpc << ((i % 8) * 4); + } + + nvkm_wr32(device, GPC_BCAST(0x0980), data[0]); + nvkm_wr32(device, GPC_BCAST(0x0984), data[1]); + nvkm_wr32(device, GPC_BCAST(0x0988), data[2]); + nvkm_wr32(device, GPC_BCAST(0x098c), data[3]); + + nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918); +} + static const struct gf100_gr_func gf117_gr = { .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, + .init_zcull = gf117_gr_init_zcull, .mmio = gf117_gr_pack_mmio, .fecs.ucode = &gf117_gr_fecs_ucode, .gpccs.ucode = &gf117_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c index d3b06dd7702d8..269922e9fca23 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c @@ -180,6 +180,7 @@ gf119_gr = { .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, + .init_zcull = gf100_gr_init_zcull, .mmio = gf119_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index 835f498d6b98a..d1b7fb8957fb1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -415,11 +415,7 @@ int gk104_gr_init(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; - const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); - u32 data[TPC_MAX / 8] = {}; - u8 tpcnr[GPC_MAX]; int gpc, tpc, rop; - int i; gr->func->init_gpc_mmu(gr); @@ -429,32 +425,8 @@ gk104_gr_init(struct gf100_gr *gr) gr->func->clkgate_pack); gr->func->init_vsc_stream_master(gr); + gr->func->init_zcull(gr); - memset(data, 0x00, sizeof(data)); - memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); - for (i = 0, gpc = -1; i < gr->tpc_total; i++) { - do { - gpc = (gpc + 1) % gr->gpc_nr; - } while (!tpcnr[gpc]); - tpc = gr->tpc_nr[gpc] - tpcnr[gpc]--; - - data[i / 8] |= tpc << ((i % 8) * 4); - } - - nvkm_wr32(device, GPC_BCAST(0x0980), data[0]); - nvkm_wr32(device, GPC_BCAST(0x0984), data[1]); - nvkm_wr32(device, GPC_BCAST(0x0988), data[2]); - nvkm_wr32(device, GPC_BCAST(0x098c), data[3]); - - for (gpc = 0; gpc < gr->gpc_nr; gpc++) { - nvkm_wr32(device, GPC_UNIT(gpc, 0x0914), - gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 | - gr->tpc_total); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918); - } - - nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918); nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800)); gr->func->init_rop_active_fbps(gr); @@ -544,6 +516,7 @@ gk104_gr = { .init = gk104_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, + .init_zcull = gf117_gr_init_zcull, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk104_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index eef7476e0ee89..0eba041cd399c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -339,6 +339,7 @@ gk110_gr = { .init = gk104_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, + .init_zcull = gf117_gr_init_zcull, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk110_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index ed4361a830a5e..84a1664f9e467 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c @@ -105,6 +105,7 @@ gk110b_gr = { .init = gk104_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, + .init_zcull = gf117_gr_init_zcull, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk110b_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c index 4c8beb9c17085..701199abf5f9e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c @@ -164,6 +164,7 @@ gk208_gr = { .init = gk104_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, + .init_zcull = gf117_gr_init_zcull, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk208_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c index de8b806b88fd9..a806643ede7e6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c @@ -219,11 +219,7 @@ int gk20a_gr_init(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; - const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); - u32 data[TPC_MAX / 8] = {}; - u8 tpcnr[GPC_MAX]; - int gpc, tpc; - int ret, i; + int ret; /* Clear SCC RAM */ nvkm_wr32(device, 0x40802c, 0x1); @@ -246,31 +242,7 @@ gk20a_gr_init(struct gf100_gr *gr) nvkm_mask(device, 0x503018, 0x1, 0x1); /* Zcull init */ - memset(data, 0x00, sizeof(data)); - memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); - for (i = 0, gpc = -1; i < gr->tpc_total; i++) { - do { - gpc = (gpc + 1) % gr->gpc_nr; - } while (!tpcnr[gpc]); - tpc = gr->tpc_nr[gpc] - tpcnr[gpc]--; - - data[i / 8] |= tpc << ((i % 8) * 4); - } - - nvkm_wr32(device, GPC_BCAST(0x0980), data[0]); - nvkm_wr32(device, GPC_BCAST(0x0984), data[1]); - nvkm_wr32(device, GPC_BCAST(0x0988), data[2]); - nvkm_wr32(device, GPC_BCAST(0x098c), data[3]); - - for (gpc = 0; gpc < gr->gpc_nr; gpc++) { - nvkm_wr32(device, GPC_UNIT(gpc, 0x0914), - gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 | - gr->tpc_total); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918); - } - - nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918); + gr->func->init_zcull(gr); gr->func->init_rop_active_fbps(gr); @@ -311,6 +283,7 @@ gk20a_gr_init(struct gf100_gr *gr) static const struct gf100_gr_func gk20a_gr = { .init = gk20a_gr_init, + .init_zcull = gf117_gr_init_zcull, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .set_hww_esr_report_mask = gk20a_gr_set_hww_esr_report_mask, .rops = gf100_gr_rops, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index 58c03d6c1c2dc..a5f5e05c21ac5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -325,11 +325,7 @@ static int gm107_gr_init(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; - const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); - u32 data[TPC_MAX / 8] = {}; - u8 tpcnr[GPC_MAX]; int gpc, tpc, rop; - int i; gr->func->init_gpc_mmu(gr); @@ -338,32 +334,8 @@ gm107_gr_init(struct gf100_gr *gr) gr->func->init_bios(gr); gr->func->init_vsc_stream_master(gr); + gr->func->init_zcull(gr); - memset(data, 0x00, sizeof(data)); - memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); - for (i = 0, gpc = -1; i < gr->tpc_total; i++) { - do { - gpc = (gpc + 1) % gr->gpc_nr; - } while (!tpcnr[gpc]); - tpc = gr->tpc_nr[gpc] - tpcnr[gpc]--; - - data[i / 8] |= tpc << ((i % 8) * 4); - } - - nvkm_wr32(device, GPC_BCAST(0x0980), data[0]); - nvkm_wr32(device, GPC_BCAST(0x0984), data[1]); - nvkm_wr32(device, GPC_BCAST(0x0988), data[2]); - nvkm_wr32(device, GPC_BCAST(0x098c), data[3]); - - for (gpc = 0; gpc < gr->gpc_nr; gpc++) { - nvkm_wr32(device, GPC_UNIT(gpc, 0x0914), - gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 | - gr->tpc_total); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918); - } - - nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918); nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800)); gr->func->init_rop_active_fbps(gr); @@ -453,6 +425,7 @@ gm107_gr = { .init_gpc_mmu = gm107_gr_init_gpc_mmu, .init_bios = gm107_gr_init_bios, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, + .init_zcull = gf117_gr_init_zcull, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gm107_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index 8583aad367afc..2ceef1737f842 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -65,11 +65,7 @@ static int gm200_gr_init(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; - const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); - u32 data[TPC_MAX / 8] = {}; - u8 tpcnr[GPC_MAX]; int gpc, tpc, rop; - int i; gr->func->init_gpc_mmu(gr); @@ -78,32 +74,8 @@ gm200_gr_init(struct gf100_gr *gr) gr->func->init_bios(gr); gr->func->init_vsc_stream_master(gr); + gr->func->init_zcull(gr); - memset(data, 0x00, sizeof(data)); - memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); - for (i = 0, gpc = -1; i < gr->tpc_total; i++) { - do { - gpc = (gpc + 1) % gr->gpc_nr; - } while (!tpcnr[gpc]); - tpc = gr->tpc_nr[gpc] - tpcnr[gpc]--; - - data[i / 8] |= tpc << ((i % 8) * 4); - } - - nvkm_wr32(device, GPC_BCAST(0x0980), data[0]); - nvkm_wr32(device, GPC_BCAST(0x0984), data[1]); - nvkm_wr32(device, GPC_BCAST(0x0988), data[2]); - nvkm_wr32(device, GPC_BCAST(0x098c), data[3]); - - for (gpc = 0; gpc < gr->gpc_nr; gpc++) { - nvkm_wr32(device, GPC_UNIT(gpc, 0x0914), - gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 | - gr->tpc_total); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918); - } - - nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918); nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800)); nvkm_wr32(device, GPC_BCAST(0x033c), nvkm_rd32(device, 0x100804)); @@ -212,6 +184,7 @@ gm200_gr = { .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_bios = gm107_gr_init_bios, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, + .init_zcull = gf117_gr_init_zcull, .init_rop_active_fbps = gm200_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c index 69479af1d829f..fcf86d5cf26fa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c @@ -65,6 +65,7 @@ gm20b_gr_set_hww_esr_report_mask(struct gf100_gr *gr) static const struct gf100_gr_func gm20b_gr = { .init = gk20a_gr_init, + .init_zcull = gf117_gr_init_zcull, .init_gpc_mmu = gm20b_gr_init_gpc_mmu, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .set_hww_esr_report_mask = gm20b_gr_set_hww_esr_report_mask, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c index edaaebbe76131..7d3317eb3e54e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c @@ -53,43 +53,15 @@ int gp100_gr_init(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; - const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); - u32 data[TPC_MAX / 8] = {}; - u8 tpcnr[GPC_MAX]; int gpc, tpc, rop; - int i; gr->func->init_gpc_mmu(gr); gf100_gr_mmio(gr, gr->fuc_sw_nonctx); gr->func->init_vsc_stream_master(gr); + gr->func->init_zcull(gr); - memset(data, 0x00, sizeof(data)); - memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); - for (i = 0, gpc = -1; i < gr->tpc_total; i++) { - do { - gpc = (gpc + 1) % gr->gpc_nr; - } while (!tpcnr[gpc]); - tpc = gr->tpc_nr[gpc] - tpcnr[gpc]--; - - data[i / 8] |= tpc << ((i % 8) * 4); - } - - nvkm_wr32(device, GPC_BCAST(0x0980), data[0]); - nvkm_wr32(device, GPC_BCAST(0x0984), data[1]); - nvkm_wr32(device, GPC_BCAST(0x0988), data[2]); - nvkm_wr32(device, GPC_BCAST(0x098c), data[3]); - - for (gpc = 0; gpc < gr->gpc_nr; gpc++) { - nvkm_wr32(device, GPC_UNIT(gpc, 0x0914), - gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 | - gr->tpc_total); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918); - } - - nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918); gr->func->init_num_active_ltcs(gr); gr->func->init_rop_active_fbps(gr); @@ -161,6 +133,7 @@ gp100_gr = { .init = gp100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, + .init_zcull = gf117_gr_init_zcull, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_num_active_ltcs = gp100_gr_init_num_active_ltcs, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c index 821a6c4589e23..0d9bf6c27a7b6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c @@ -45,6 +45,7 @@ gp102_gr = { .init = gp100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, + .init_zcull = gf117_gr_init_zcull, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_swdx_pes_mask = gp102_gr_init_swdx_pes_mask, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c index e2e12975bb2cb..67d567e3a2ac8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c @@ -31,6 +31,7 @@ gp107_gr = { .init = gp100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, + .init_zcull = gf117_gr_init_zcull, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_swdx_pes_mask = gp102_gr_init_swdx_pes_mask, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c index e90cc3c845ec4..af06b10ba92f6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c @@ -38,6 +38,7 @@ gp10b_gr = { .init = gp100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, + .init_zcull = gf117_gr_init_zcull, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_num_active_ltcs = gp10b_gr_init_num_active_ltcs, From bfd27f39b5419724883bbd04910c4c35e57b6154 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 046/165] drm/nouveau/gr/gf100-: virtualise init_num_active_ltcs Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 11 +++++++++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 6 +++--- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c | 13 ++++++++++--- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c | 11 +---------- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c | 10 +--------- 17 files changed, 38 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 56d9ead0b3801..d33e531bb1a06 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1930,6 +1930,13 @@ gf100_gr_init_gpc_mmu(struct gf100_gr *gr) nvkm_wr32(device, 0x4188b8, nvkm_memory_addr(fb->mmu_rd) >> 8); } +void +gf100_gr_init_num_active_ltcs(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800)); +} + void gf100_gr_init_zcull(struct gf100_gr *gr) { @@ -1989,8 +1996,7 @@ gf100_gr_init(struct gf100_gr *gr) gr->func->init_vsc_stream_master(gr); gr->func->init_zcull(gr); - - nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800)); + gr->func->init_num_active_ltcs(gr); nvkm_wr32(device, 0x400500, 0x00010001); @@ -2074,6 +2080,7 @@ gf100_gr = { .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, .init_zcull = gf100_gr_init_zcull, + .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .mmio = gf100_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index b322dc4247610..7f6aed873408f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -126,10 +126,10 @@ struct gf100_gr_func { void (*init_bios)(struct gf100_gr *); void (*init_vsc_stream_master)(struct gf100_gr *); void (*init_zcull)(struct gf100_gr *); + void (*init_num_active_ltcs)(struct gf100_gr *); void (*init_rop_active_fbps)(struct gf100_gr *); void (*init_ppc_exceptions)(struct gf100_gr *); void (*init_swdx_pes_mask)(struct gf100_gr *); - void (*init_num_active_ltcs)(struct gf100_gr *); void (*set_hww_esr_report_mask)(struct gf100_gr *); const struct gf100_gr_pack *mmio; struct { @@ -149,6 +149,7 @@ int gf100_gr_rops(struct gf100_gr *); int gf100_gr_init(struct gf100_gr *); void gf100_gr_init_vsc_stream_master(struct gf100_gr *); void gf100_gr_init_zcull(struct gf100_gr *); +void gf100_gr_init_num_active_ltcs(struct gf100_gr *); void gf117_gr_init_zcull(struct gf100_gr *); @@ -160,6 +161,7 @@ void gk104_gr_init_ppc_exceptions(struct gf100_gr *); int gk20a_gr_init(struct gf100_gr *); int gm200_gr_rops(struct gf100_gr *); +void gm200_gr_init_num_active_ltcs(struct gf100_gr *); int gp100_gr_init(struct gf100_gr *); void gp100_gr_init_rop_active_fbps(struct gf100_gr *); @@ -315,7 +317,5 @@ void gm107_gr_init_bios(struct gf100_gr *); void gm200_gr_init_gpc_mmu(struct gf100_gr *); -void gp100_gr_init_num_active_ltcs(struct gf100_gr *gr); - void gp102_gr_init_swdx_pes_mask(struct gf100_gr *); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c index 23c2613fa6bfa..b6d67f5e5e712 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c @@ -118,6 +118,7 @@ gf104_gr = { .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, .init_zcull = gf100_gr_init_zcull, + .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .mmio = gf104_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c index a79a7860732a9..9b5796bd1dc03 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c @@ -116,6 +116,7 @@ gf108_gr = { .init_r405a14 = gf108_gr_init_r405a14, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, .init_zcull = gf100_gr_init_zcull, + .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .mmio = gf108_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c index fd8e13716d94f..7e346a0e95403 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c @@ -90,6 +90,7 @@ gf110_gr = { .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, .init_zcull = gf100_gr_init_zcull, + .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .mmio = gf110_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c index 01e213e4d1a90..5c68c5f904ce1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c @@ -154,6 +154,7 @@ gf117_gr = { .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, + .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .mmio = gf117_gr_pack_mmio, .fecs.ucode = &gf117_gr_fecs_ucode, .gpccs.ucode = &gf117_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c index 269922e9fca23..b642bd224ecf9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c @@ -181,6 +181,7 @@ gf119_gr = { .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, .init_zcull = gf100_gr_init_zcull, + .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .mmio = gf119_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index d1b7fb8957fb1..3f19de24ef699 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -426,8 +426,7 @@ gk104_gr_init(struct gf100_gr *gr) gr->func->init_vsc_stream_master(gr); gr->func->init_zcull(gr); - - nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800)); + gr->func->init_num_active_ltcs(gr); gr->func->init_rop_active_fbps(gr); @@ -517,6 +516,7 @@ gk104_gr = { .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, + .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk104_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index 0eba041cd399c..9a8428c5df45c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -340,6 +340,7 @@ gk110_gr = { .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, + .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk110_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index 84a1664f9e467..08f3f8c2c2bfa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c @@ -106,6 +106,7 @@ gk110b_gr = { .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, + .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk110b_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c index 701199abf5f9e..49ee5490c7c24 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c @@ -165,6 +165,7 @@ gk208_gr = { .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, + .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk208_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index a5f5e05c21ac5..bbb0a28365f54 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -335,8 +335,7 @@ gm107_gr_init(struct gf100_gr *gr) gr->func->init_vsc_stream_master(gr); gr->func->init_zcull(gr); - - nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800)); + gr->func->init_num_active_ltcs(gr); gr->func->init_rop_active_fbps(gr); @@ -426,6 +425,7 @@ gm107_gr = { .init_bios = gm107_gr_init_bios, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, + .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gm107_gr_pack_mmio, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index 2ceef1737f842..5007435e6f7d5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -38,6 +38,14 @@ gm200_gr_rops(struct gf100_gr *gr) return nvkm_rd32(gr->base.engine.subdev.device, 0x12006c); } +void +gm200_gr_init_num_active_ltcs(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800)); + nvkm_wr32(device, GPC_BCAST(0x033c), nvkm_rd32(device, 0x100804)); +} + void gm200_gr_init_gpc_mmu(struct gf100_gr *gr) { @@ -75,9 +83,7 @@ gm200_gr_init(struct gf100_gr *gr) gr->func->init_vsc_stream_master(gr); gr->func->init_zcull(gr); - - nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800)); - nvkm_wr32(device, GPC_BCAST(0x033c), nvkm_rd32(device, 0x100804)); + gr->func->init_num_active_ltcs(gr); gr->func->init_rop_active_fbps(gr); @@ -185,6 +191,7 @@ gm200_gr = { .init_bios = gm107_gr_init_bios, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, + .init_num_active_ltcs = gm200_gr_init_num_active_ltcs, .init_rop_active_fbps = gm200_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c index 7d3317eb3e54e..1e6795956abc9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c @@ -40,15 +40,6 @@ gp100_gr_init_rop_active_fbps(struct gf100_gr *gr) nvkm_mask(device, 0x408958, 0x0000000f, fbp_count); /* crop */ } -void -gp100_gr_init_num_active_ltcs(struct gf100_gr *gr) -{ - struct nvkm_device *device = gr->base.engine.subdev.device; - - nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800)); - nvkm_wr32(device, GPC_BCAST(0x033c), nvkm_rd32(device, 0x100804)); -} - int gp100_gr_init(struct gf100_gr *gr) { @@ -134,9 +125,9 @@ gp100_gr = { .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, + .init_num_active_ltcs = gm200_gr_init_num_active_ltcs, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, - .init_num_active_ltcs = gp100_gr_init_num_active_ltcs, .rops = gm200_gr_rops, .ppc_nr = 2, .grctx = &gp100_grctx, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c index 0d9bf6c27a7b6..17bd872b8dc9c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c @@ -46,10 +46,10 @@ gp102_gr = { .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, + .init_num_active_ltcs = gm200_gr_init_num_active_ltcs, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_swdx_pes_mask = gp102_gr_init_swdx_pes_mask, - .init_num_active_ltcs = gp100_gr_init_num_active_ltcs, .rops = gm200_gr_rops, .ppc_nr = 3, .grctx = &gp102_grctx, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c index 67d567e3a2ac8..3fba3af2f5a61 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c @@ -32,10 +32,10 @@ gp107_gr = { .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, + .init_num_active_ltcs = gm200_gr_init_num_active_ltcs, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_swdx_pes_mask = gp102_gr_init_swdx_pes_mask, - .init_num_active_ltcs = gp100_gr_init_num_active_ltcs, .rops = gm200_gr_rops, .ppc_nr = 1, .grctx = &gp107_grctx, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c index af06b10ba92f6..97f86677a22c3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c @@ -25,23 +25,15 @@ #include -static void -gp10b_gr_init_num_active_ltcs(struct gf100_gr *gr) -{ - struct nvkm_device *device = gr->base.engine.subdev.device; - - nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800)); -} - static const struct gf100_gr_func gp10b_gr = { .init = gp100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, + .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, - .init_num_active_ltcs = gp10b_gr_init_num_active_ltcs, .rops = gm200_gr_rops, .ppc_nr = 1, .grctx = &gp102_grctx, From 429412e231a27d48cb492dc1c647e857677240b3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 047/165] drm/nouveau/gr/gf100-: virtualise init_rop_active_fbps Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index d33e531bb1a06..6912eaa5a90ac 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1997,6 +1997,8 @@ gf100_gr_init(struct gf100_gr *gr) gr->func->init_vsc_stream_master(gr); gr->func->init_zcull(gr); gr->func->init_num_active_ltcs(gr); + if (gr->func->init_rop_active_fbps) + gr->func->init_rop_active_fbps(gr); nvkm_wr32(device, 0x400500, 0x00010001); From 0f78acc86bbfc60cdaffd4eb03e4a35b28397cbb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 048/165] drm/nouveau/gr/gf100-: implement another chunk of bios-provided init Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 2 ++ .../gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 28 +++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 6912eaa5a90ac..01b903acde4a0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1999,6 +1999,8 @@ gf100_gr_init(struct gf100_gr *gr) gr->func->init_num_active_ltcs(gr); if (gr->func->init_rop_active_fbps) gr->func->init_rop_active_fbps(gr); + if (gr->func->init_bios_2) + gr->func->init_bios_2(gr); nvkm_wr32(device, 0x400500, 0x00010001); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 7f6aed873408f..11cf2dff0f811 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -128,6 +128,7 @@ struct gf100_gr_func { void (*init_zcull)(struct gf100_gr *); void (*init_num_active_ltcs)(struct gf100_gr *); void (*init_rop_active_fbps)(struct gf100_gr *); + void (*init_bios_2)(struct gf100_gr *); void (*init_ppc_exceptions)(struct gf100_gr *); void (*init_swdx_pes_mask)(struct gf100_gr *); void (*set_hww_esr_report_mask)(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index bbb0a28365f54..c653df323f1ad 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -25,6 +25,8 @@ #include "ctxgf100.h" #include +#include +#include #include #include @@ -279,6 +281,31 @@ gm107_gr_pack_mmio[] = { * PGRAPH engine/subdev functions ******************************************************************************/ +static void +gm107_gr_init_bios_2(struct gf100_gr *gr) +{ + struct nvkm_subdev *subdev = &gr->base.engine.subdev; + struct nvkm_device *device = subdev->device; + struct nvkm_bios *bios = device->bios; + struct bit_entry bit_P; + if (!bit_entry(bios, 'P', &bit_P) && + bit_P.version == 2 && bit_P.length >= 0x2c) { + u32 data = nvbios_rd32(bios, bit_P.offset + 0x28); + if (data) { + u8 ver = nvbios_rd08(bios, data + 0x00); + u8 hdr = nvbios_rd08(bios, data + 0x01); + if (ver == 0x20 && hdr >= 8) { + data = nvbios_rd32(bios, data + 0x04); + if (data) { + u32 save = nvkm_rd32(device, 0x619444); + nvbios_init(subdev, data); + nvkm_wr32(device, 0x619444, save); + } + } + } + } +} + void gm107_gr_init_bios(struct gf100_gr *gr) { @@ -427,6 +454,7 @@ gm107_gr = { .init_zcull = gf117_gr_init_zcull, .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, + .init_bios_2 = gm107_gr_init_bios_2, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gm107_gr_pack_mmio, .fecs.ucode = &gm107_gr_fecs_ucode, From dff30dbd1d9336687ae1aa0b13e326c44f879c4e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 049/165] drm/nouveau/gr/gf100-: virtualise init_swdx_pes_mask Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 6 +++--- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 01b903acde4a0..7ad6ea0533a49 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -2001,6 +2001,8 @@ gf100_gr_init(struct gf100_gr *gr) gr->func->init_rop_active_fbps(gr); if (gr->func->init_bios_2) gr->func->init_bios_2(gr); + if (gr->func->init_swdx_pes_mask) + gr->func->init_swdx_pes_mask(gr); nvkm_wr32(device, 0x400500, 0x00010001); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 11cf2dff0f811..858024ba11865 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -129,8 +129,8 @@ struct gf100_gr_func { void (*init_num_active_ltcs)(struct gf100_gr *); void (*init_rop_active_fbps)(struct gf100_gr *); void (*init_bios_2)(struct gf100_gr *); - void (*init_ppc_exceptions)(struct gf100_gr *); void (*init_swdx_pes_mask)(struct gf100_gr *); + void (*init_ppc_exceptions)(struct gf100_gr *); void (*set_hww_esr_report_mask)(struct gf100_gr *); const struct gf100_gr_pack *mmio; struct { @@ -167,6 +167,8 @@ void gm200_gr_init_num_active_ltcs(struct gf100_gr *); int gp100_gr_init(struct gf100_gr *); void gp100_gr_init_rop_active_fbps(struct gf100_gr *); +void gp102_gr_init_swdx_pes_mask(struct gf100_gr *); + #define gf100_gr_chan(p) container_of((p), struct gf100_gr_chan, object) #include @@ -317,6 +319,4 @@ extern const struct gf100_gr_init gm107_gr_init_cbm_0[]; void gm107_gr_init_bios(struct gf100_gr *); void gm200_gr_init_gpc_mmu(struct gf100_gr *); - -void gp102_gr_init_swdx_pes_mask(struct gf100_gr *); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c index 17bd872b8dc9c..860a789769806 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c @@ -48,8 +48,8 @@ gp102_gr = { .init_zcull = gf117_gr_init_zcull, .init_num_active_ltcs = gm200_gr_init_num_active_ltcs, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, - .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_swdx_pes_mask = gp102_gr_init_swdx_pes_mask, + .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 3, .grctx = &gp102_grctx, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c index 3fba3af2f5a61..03f22646eb78d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c @@ -34,8 +34,8 @@ gp107_gr = { .init_zcull = gf117_gr_init_zcull, .init_num_active_ltcs = gm200_gr_init_num_active_ltcs, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, - .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_swdx_pes_mask = gp102_gr_init_swdx_pes_mask, + .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 1, .grctx = &gp107_grctx, From 7c76ebb65a9c8d29780e7324c8ae067c5cd980ca Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 050/165] drm/nouveau/gr/gf100: write 0x400124 during init Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 7ad6ea0533a49..0c53d456ebbcd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -2008,6 +2008,7 @@ gf100_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x400100, 0xffffffff); nvkm_wr32(device, 0x40013c, 0xffffffff); + nvkm_wr32(device, 0x400124, 0x00000002); nvkm_wr32(device, 0x409c24, 0x000f0000); nvkm_wr32(device, 0x404000, 0xc0000000); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index 3f19de24ef699..703aed48f7379 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -434,6 +434,7 @@ gk104_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x400100, 0xffffffff); nvkm_wr32(device, 0x40013c, 0xffffffff); + nvkm_wr32(device, 0x400124, 0x00000002); nvkm_wr32(device, 0x409ffc, 0x00000000); nvkm_wr32(device, 0x409c14, 0x00003e3e); From 2585a1b1312e96c6a28f3008029408b5feca3ff4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 051/165] drm/nouveau/gr/gf100-: virtualise init_fecs_exceptions + apply fixes from traces The value for GF100 has changed here, but it matches RM now. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 11 ++++++++++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 3 +++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 14 +++++++++++--- drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c | 9 ++++++++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c | 1 + 17 files changed, 47 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 0c53d456ebbcd..0493483597eda 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1914,6 +1914,13 @@ gf100_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device, return 0; } +void +gf100_gr_init_fecs_exceptions(struct gf100_gr *gr) +{ + const u32 data = gr->firmware ? 0x000e0000 : 0x000e0001; + nvkm_wr32(gr->base.engine.subdev.device, 0x409c24, data); +} + void gf100_gr_init_gpc_mmu(struct gf100_gr *gr) { @@ -2010,7 +2017,8 @@ gf100_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x40013c, 0xffffffff); nvkm_wr32(device, 0x400124, 0x00000002); - nvkm_wr32(device, 0x409c24, 0x000f0000); + gr->func->init_fecs_exceptions(gr); + nvkm_wr32(device, 0x404000, 0xc0000000); nvkm_wr32(device, 0x404600, 0xc0000000); nvkm_wr32(device, 0x408030, 0xc0000000); @@ -2088,6 +2096,7 @@ gf100_gr = { .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, .init_zcull = gf100_gr_init_zcull, .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, + .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .mmio = gf100_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 858024ba11865..387938fa352b0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -130,6 +130,7 @@ struct gf100_gr_func { void (*init_rop_active_fbps)(struct gf100_gr *); void (*init_bios_2)(struct gf100_gr *); void (*init_swdx_pes_mask)(struct gf100_gr *); + void (*init_fecs_exceptions)(struct gf100_gr *); void (*init_ppc_exceptions)(struct gf100_gr *); void (*set_hww_esr_report_mask)(struct gf100_gr *); const struct gf100_gr_pack *mmio; @@ -151,6 +152,7 @@ int gf100_gr_init(struct gf100_gr *); void gf100_gr_init_vsc_stream_master(struct gf100_gr *); void gf100_gr_init_zcull(struct gf100_gr *); void gf100_gr_init_num_active_ltcs(struct gf100_gr *); +void gf100_gr_init_fecs_exceptions(struct gf100_gr *); void gf117_gr_init_zcull(struct gf100_gr *); @@ -166,6 +168,7 @@ void gm200_gr_init_num_active_ltcs(struct gf100_gr *); int gp100_gr_init(struct gf100_gr *); void gp100_gr_init_rop_active_fbps(struct gf100_gr *); +void gp100_gr_init_fecs_exceptions(struct gf100_gr *); void gp102_gr_init_swdx_pes_mask(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c index b6d67f5e5e712..f76995b54eabb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c @@ -119,6 +119,7 @@ gf104_gr = { .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, .init_zcull = gf100_gr_init_zcull, .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, + .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .mmio = gf104_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c index 9b5796bd1dc03..ada2697a075a9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c @@ -117,6 +117,7 @@ gf108_gr = { .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, .init_zcull = gf100_gr_init_zcull, .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, + .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .mmio = gf108_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c index 7e346a0e95403..80ced8fc2e3eb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c @@ -91,6 +91,7 @@ gf110_gr = { .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, .init_zcull = gf100_gr_init_zcull, .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, + .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .mmio = gf110_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c index 5c68c5f904ce1..37ca1216372c1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c @@ -155,6 +155,7 @@ gf117_gr = { .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, + .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .mmio = gf117_gr_pack_mmio, .fecs.ucode = &gf117_gr_fecs_ucode, .gpccs.ucode = &gf117_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c index b642bd224ecf9..ddf05c5fa2fc5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c @@ -182,6 +182,7 @@ gf119_gr = { .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, .init_zcull = gf100_gr_init_zcull, .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, + .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .mmio = gf119_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index 703aed48f7379..746ad3d0d1cee 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -380,6 +380,15 @@ gk104_clkgate_pack[] = { * PGRAPH engine/subdev functions ******************************************************************************/ +static void +gk104_gr_init_fecs_exceptions(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_wr32(device, 0x409ffc, 0x00000000); + nvkm_wr32(device, 0x409c14, 0x00003e3e); + nvkm_wr32(device, 0x409c24, 0x000f0001); +} + void gk104_gr_init_rop_active_fbps(struct gf100_gr *gr) { @@ -436,9 +445,7 @@ gk104_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x40013c, 0xffffffff); nvkm_wr32(device, 0x400124, 0x00000002); - nvkm_wr32(device, 0x409ffc, 0x00000000); - nvkm_wr32(device, 0x409c14, 0x00003e3e); - nvkm_wr32(device, 0x409c24, 0x000f0001); + gr->func->init_fecs_exceptions(gr); nvkm_wr32(device, 0x404000, 0xc0000000); nvkm_wr32(device, 0x404600, 0xc0000000); nvkm_wr32(device, 0x408030, 0xc0000000); @@ -519,6 +526,7 @@ gk104_gr = { .init_zcull = gf117_gr_init_zcull, .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, + .init_fecs_exceptions = gk104_gr_init_fecs_exceptions, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk104_gr_pack_mmio, .fecs.ucode = &gk104_gr_fecs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index 9a8428c5df45c..8a6340d237662 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -342,6 +342,7 @@ gk110_gr = { .init_zcull = gf117_gr_init_zcull, .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, + .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk110_gr_pack_mmio, .fecs.ucode = &gk110_gr_fecs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index 08f3f8c2c2bfa..b50e68165df76 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c @@ -108,6 +108,7 @@ gk110b_gr = { .init_zcull = gf117_gr_init_zcull, .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, + .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk110b_gr_pack_mmio, .fecs.ucode = &gk110_gr_fecs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c index 49ee5490c7c24..7a938bb3af9fa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c @@ -167,6 +167,7 @@ gk208_gr = { .init_zcull = gf117_gr_init_zcull, .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, + .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk208_gr_pack_mmio, .fecs.ucode = &gk208_gr_fecs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index c653df323f1ad..9f2df29fd4e4b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -371,7 +371,7 @@ gm107_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x400100, 0xffffffff); nvkm_wr32(device, 0x40013c, 0xffffffff); nvkm_wr32(device, 0x400124, 0x00000002); - nvkm_wr32(device, 0x409c24, 0x000e0000); + gr->func->init_fecs_exceptions(gr); nvkm_wr32(device, 0x404000, 0xc0000000); nvkm_wr32(device, 0x404600, 0xc0000000); @@ -455,6 +455,7 @@ gm107_gr = { .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_bios_2 = gm107_gr_init_bios_2, + .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gm107_gr_pack_mmio, .fecs.ucode = &gm107_gr_fecs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index 5007435e6f7d5..a957993a0cc0e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -91,7 +91,7 @@ gm200_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x400100, 0xffffffff); nvkm_wr32(device, 0x40013c, 0xffffffff); nvkm_wr32(device, 0x400124, 0x00000002); - nvkm_wr32(device, 0x409c24, 0x000e0000); + gr->func->init_fecs_exceptions(gr); nvkm_wr32(device, 0x405848, 0xc0000000); nvkm_wr32(device, 0x40584c, 0x00000001); nvkm_wr32(device, 0x404000, 0xc0000000); @@ -193,6 +193,7 @@ gm200_gr = { .init_zcull = gf117_gr_init_zcull, .init_num_active_ltcs = gm200_gr_init_num_active_ltcs, .init_rop_active_fbps = gm200_gr_init_rop_active_fbps, + .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 2, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c index 1e6795956abc9..564b5b17b5033 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c @@ -30,6 +30,12 @@ * PGRAPH engine/subdev functions ******************************************************************************/ +void +gp100_gr_init_fecs_exceptions(struct gf100_gr *gr) +{ + nvkm_wr32(gr->base.engine.subdev.device, 0x409c24, 0x000f0002); +} + void gp100_gr_init_rop_active_fbps(struct gf100_gr *gr) { @@ -63,7 +69,7 @@ gp100_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x400100, 0xffffffff); nvkm_wr32(device, 0x40013c, 0xffffffff); nvkm_wr32(device, 0x400124, 0x00000002); - nvkm_wr32(device, 0x409c24, 0x000f0002); + gr->func->init_fecs_exceptions(gr); nvkm_wr32(device, 0x405848, 0xc0000000); nvkm_mask(device, 0x40584c, 0x00000000, 0x00000001); nvkm_wr32(device, 0x404000, 0xc0000000); @@ -127,6 +133,7 @@ gp100_gr = { .init_zcull = gf117_gr_init_zcull, .init_num_active_ltcs = gm200_gr_init_num_active_ltcs, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, + .init_fecs_exceptions = gp100_gr_init_fecs_exceptions, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 2, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c index 860a789769806..04803fa7937a3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c @@ -49,6 +49,7 @@ gp102_gr = { .init_num_active_ltcs = gm200_gr_init_num_active_ltcs, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_swdx_pes_mask = gp102_gr_init_swdx_pes_mask, + .init_fecs_exceptions = gp100_gr_init_fecs_exceptions, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 3, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c index 03f22646eb78d..c21cb8ae9a8bc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c @@ -35,6 +35,7 @@ gp107_gr = { .init_num_active_ltcs = gm200_gr_init_num_active_ltcs, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_swdx_pes_mask = gp102_gr_init_swdx_pes_mask, + .init_fecs_exceptions = gp100_gr_init_fecs_exceptions, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 1, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c index 97f86677a22c3..222b5b0c6e389 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c @@ -33,6 +33,7 @@ gp10b_gr = { .init_zcull = gf117_gr_init_zcull, .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, + .init_fecs_exceptions = gp100_gr_init_fecs_exceptions, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 1, From 3ac72e98b40ead6225eb38bcf78ec540357106c0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 052/165] drm/nouveau/gr/gf100-: virtualise init_ds_hww_esr_2 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c | 12 ++++++++++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c | 1 + 7 files changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 0493483597eda..1f764df141bd0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -2018,6 +2018,8 @@ gf100_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x400124, 0x00000002); gr->func->init_fecs_exceptions(gr); + if (gr->func->init_ds_hww_esr_2) + gr->func->init_ds_hww_esr_2(gr); nvkm_wr32(device, 0x404000, 0xc0000000); nvkm_wr32(device, 0x404600, 0xc0000000); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 387938fa352b0..ff3e265925c53 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -131,6 +131,7 @@ struct gf100_gr_func { void (*init_bios_2)(struct gf100_gr *); void (*init_swdx_pes_mask)(struct gf100_gr *); void (*init_fecs_exceptions)(struct gf100_gr *); + void (*init_ds_hww_esr_2)(struct gf100_gr *); void (*init_ppc_exceptions)(struct gf100_gr *); void (*set_hww_esr_report_mask)(struct gf100_gr *); const struct gf100_gr_pack *mmio; @@ -165,6 +166,7 @@ int gk20a_gr_init(struct gf100_gr *); int gm200_gr_rops(struct gf100_gr *); void gm200_gr_init_num_active_ltcs(struct gf100_gr *); +void gm200_gr_init_ds_hww_esr_2(struct gf100_gr *); int gp100_gr_init(struct gf100_gr *); void gp100_gr_init_rop_active_fbps(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index a957993a0cc0e..b5994dca5d03f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -38,6 +38,14 @@ gm200_gr_rops(struct gf100_gr *gr) return nvkm_rd32(gr->base.engine.subdev.device, 0x12006c); } +void +gm200_gr_init_ds_hww_esr_2(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_wr32(device, 0x405848, 0xc0000000); + nvkm_mask(device, 0x40584c, 0x00000001, 0x00000001); +} + void gm200_gr_init_num_active_ltcs(struct gf100_gr *gr) { @@ -92,8 +100,7 @@ gm200_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x40013c, 0xffffffff); nvkm_wr32(device, 0x400124, 0x00000002); gr->func->init_fecs_exceptions(gr); - nvkm_wr32(device, 0x405848, 0xc0000000); - nvkm_wr32(device, 0x40584c, 0x00000001); + gr->func->init_ds_hww_esr_2(gr); nvkm_wr32(device, 0x404000, 0xc0000000); nvkm_wr32(device, 0x404600, 0xc0000000); nvkm_wr32(device, 0x408030, 0xc0000000); @@ -194,6 +201,7 @@ gm200_gr = { .init_num_active_ltcs = gm200_gr_init_num_active_ltcs, .init_rop_active_fbps = gm200_gr_init_rop_active_fbps, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, + .init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 2, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c index 564b5b17b5033..676f58a9aceeb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c @@ -70,8 +70,7 @@ gp100_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x40013c, 0xffffffff); nvkm_wr32(device, 0x400124, 0x00000002); gr->func->init_fecs_exceptions(gr); - nvkm_wr32(device, 0x405848, 0xc0000000); - nvkm_mask(device, 0x40584c, 0x00000000, 0x00000001); + gr->func->init_ds_hww_esr_2(gr); nvkm_wr32(device, 0x404000, 0xc0000000); nvkm_wr32(device, 0x404600, 0xc0000000); nvkm_wr32(device, 0x408030, 0xc0000000); @@ -134,6 +133,7 @@ gp100_gr = { .init_num_active_ltcs = gm200_gr_init_num_active_ltcs, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_fecs_exceptions = gp100_gr_init_fecs_exceptions, + .init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 2, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c index 04803fa7937a3..3694687c85dbf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c @@ -50,6 +50,7 @@ gp102_gr = { .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_swdx_pes_mask = gp102_gr_init_swdx_pes_mask, .init_fecs_exceptions = gp100_gr_init_fecs_exceptions, + .init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 3, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c index c21cb8ae9a8bc..c83ad01bad53b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c @@ -36,6 +36,7 @@ gp107_gr = { .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_swdx_pes_mask = gp102_gr_init_swdx_pes_mask, .init_fecs_exceptions = gp100_gr_init_fecs_exceptions, + .init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 1, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c index 222b5b0c6e389..8fef3b56cf8c2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c @@ -34,6 +34,7 @@ gp10b_gr = { .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_fecs_exceptions = gp100_gr_init_fecs_exceptions, + .init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 1, From 2b297b0d6d33aee99254b43c3e41100fc75ea4ab Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 053/165] drm/nouveau/gr/gf100-: virtualise init_40601c Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 12 +++++++++++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c | 1 + 7 files changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 1f764df141bd0..1b067e600d74a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1914,6 +1914,12 @@ gf100_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device, return 0; } +void +gf100_gr_init_40601c(struct gf100_gr *gr) +{ + nvkm_wr32(gr->base.engine.subdev.device, 0x40601c, 0xc0000000); +} + void gf100_gr_init_fecs_exceptions(struct gf100_gr *gr) { @@ -2024,7 +2030,10 @@ gf100_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x404000, 0xc0000000); nvkm_wr32(device, 0x404600, 0xc0000000); nvkm_wr32(device, 0x408030, 0xc0000000); - nvkm_wr32(device, 0x40601c, 0xc0000000); + + if (gr->func->init_40601c) + gr->func->init_40601c(gr); + nvkm_wr32(device, 0x404490, 0xc0000000); nvkm_wr32(device, 0x406018, 0xc0000000); nvkm_wr32(device, 0x405840, 0xc0000000); @@ -2099,6 +2108,7 @@ gf100_gr = { .init_zcull = gf100_gr_init_zcull, .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, + .init_40601c = gf100_gr_init_40601c, .mmio = gf100_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index ff3e265925c53..8c42a7aff1839 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -132,6 +132,7 @@ struct gf100_gr_func { void (*init_swdx_pes_mask)(struct gf100_gr *); void (*init_fecs_exceptions)(struct gf100_gr *); void (*init_ds_hww_esr_2)(struct gf100_gr *); + void (*init_40601c)(struct gf100_gr *); void (*init_ppc_exceptions)(struct gf100_gr *); void (*set_hww_esr_report_mask)(struct gf100_gr *); const struct gf100_gr_pack *mmio; @@ -154,6 +155,7 @@ void gf100_gr_init_vsc_stream_master(struct gf100_gr *); void gf100_gr_init_zcull(struct gf100_gr *); void gf100_gr_init_num_active_ltcs(struct gf100_gr *); void gf100_gr_init_fecs_exceptions(struct gf100_gr *); +void gf100_gr_init_40601c(struct gf100_gr *); void gf117_gr_init_zcull(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c index f76995b54eabb..61d6eef70e689 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c @@ -120,6 +120,7 @@ gf104_gr = { .init_zcull = gf100_gr_init_zcull, .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, + .init_40601c = gf100_gr_init_40601c, .mmio = gf104_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c index ada2697a075a9..d4f712e7d6e97 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c @@ -118,6 +118,7 @@ gf108_gr = { .init_zcull = gf100_gr_init_zcull, .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, + .init_40601c = gf100_gr_init_40601c, .mmio = gf108_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c index 80ced8fc2e3eb..1b6c2f32ec921 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c @@ -92,6 +92,7 @@ gf110_gr = { .init_zcull = gf100_gr_init_zcull, .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, + .init_40601c = gf100_gr_init_40601c, .mmio = gf110_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c index 37ca1216372c1..ae76e8183d1d1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c @@ -156,6 +156,7 @@ gf117_gr = { .init_zcull = gf117_gr_init_zcull, .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, + .init_40601c = gf100_gr_init_40601c, .mmio = gf117_gr_pack_mmio, .fecs.ucode = &gf117_gr_fecs_ucode, .gpccs.ucode = &gf117_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c index ddf05c5fa2fc5..a3970c31f9517 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c @@ -183,6 +183,7 @@ gf119_gr = { .init_zcull = gf100_gr_init_zcull, .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, + .init_40601c = gf100_gr_init_40601c, .mmio = gf119_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, From 0a5b97304b9e2cd07c78a399c5395d5fb0118341 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 054/165] drm/nouveau/gr/gf100-: virtualise init_sked_hww_esr Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 4 ++++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 9 ++++++++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c | 1 + 12 files changed, 26 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 1b067e600d74a..7ccd8f21c1e0e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -2036,6 +2036,10 @@ gf100_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x404490, 0xc0000000); nvkm_wr32(device, 0x406018, 0xc0000000); + + if (gr->func->init_sked_hww_esr) + gr->func->init_sked_hww_esr(gr); + nvkm_wr32(device, 0x405840, 0xc0000000); nvkm_wr32(device, 0x405844, 0x00ffffff); nvkm_mask(device, 0x419cc0, 0x00000008, 0x00000008); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 8c42a7aff1839..c292cf3bebb1c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -133,6 +133,7 @@ struct gf100_gr_func { void (*init_fecs_exceptions)(struct gf100_gr *); void (*init_ds_hww_esr_2)(struct gf100_gr *); void (*init_40601c)(struct gf100_gr *); + void (*init_sked_hww_esr)(struct gf100_gr *); void (*init_ppc_exceptions)(struct gf100_gr *); void (*set_hww_esr_report_mask)(struct gf100_gr *); const struct gf100_gr_pack *mmio; @@ -163,6 +164,7 @@ int gk104_gr_init(struct gf100_gr *); void gk104_gr_init_vsc_stream_master(struct gf100_gr *); void gk104_gr_init_rop_active_fbps(struct gf100_gr *); void gk104_gr_init_ppc_exceptions(struct gf100_gr *); +void gk104_gr_init_sked_hww_esr(struct gf100_gr *); int gk20a_gr_init(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index 746ad3d0d1cee..6ba604edaf952 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -380,6 +380,12 @@ gk104_clkgate_pack[] = { * PGRAPH engine/subdev functions ******************************************************************************/ +void +gk104_gr_init_sked_hww_esr(struct gf100_gr *gr) +{ + nvkm_wr32(gr->base.engine.subdev.device, 0x407020, 0x40000000); +} + static void gk104_gr_init_fecs_exceptions(struct gf100_gr *gr) { @@ -451,7 +457,7 @@ gk104_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x408030, 0xc0000000); nvkm_wr32(device, 0x404490, 0xc0000000); nvkm_wr32(device, 0x406018, 0xc0000000); - nvkm_wr32(device, 0x407020, 0x40000000); + gr->func->init_sked_hww_esr(gr); nvkm_wr32(device, 0x405840, 0xc0000000); nvkm_wr32(device, 0x405844, 0x00ffffff); nvkm_mask(device, 0x419cc0, 0x00000008, 0x00000008); @@ -527,6 +533,7 @@ gk104_gr = { .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_fecs_exceptions = gk104_gr_init_fecs_exceptions, + .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk104_gr_pack_mmio, .fecs.ucode = &gk104_gr_fecs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index 8a6340d237662..7a07d24cc2279 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -343,6 +343,7 @@ gk110_gr = { .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, + .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk110_gr_pack_mmio, .fecs.ucode = &gk110_gr_fecs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index b50e68165df76..1c9f59cde3d2c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c @@ -109,6 +109,7 @@ gk110b_gr = { .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, + .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk110b_gr_pack_mmio, .fecs.ucode = &gk110_gr_fecs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c index 7a938bb3af9fa..40c87242b54df 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c @@ -168,6 +168,7 @@ gk208_gr = { .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, + .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk208_gr_pack_mmio, .fecs.ucode = &gk208_gr_fecs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index 9f2df29fd4e4b..3d180edbdcd76 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -378,7 +378,7 @@ gm107_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x408030, 0xc0000000); nvkm_wr32(device, 0x404490, 0xc0000000); nvkm_wr32(device, 0x406018, 0xc0000000); - nvkm_wr32(device, 0x407020, 0x40000000); + gr->func->init_sked_hww_esr(gr); nvkm_wr32(device, 0x405840, 0xc0000000); nvkm_wr32(device, 0x405844, 0x00ffffff); nvkm_mask(device, 0x419cc0, 0x00000008, 0x00000008); @@ -456,6 +456,7 @@ gm107_gr = { .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_bios_2 = gm107_gr_init_bios_2, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, + .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gm107_gr_pack_mmio, .fecs.ucode = &gm107_gr_fecs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index b5994dca5d03f..9436ab37aa9e5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -106,7 +106,7 @@ gm200_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x408030, 0xc0000000); nvkm_wr32(device, 0x404490, 0xc0000000); nvkm_wr32(device, 0x406018, 0xc0000000); - nvkm_wr32(device, 0x407020, 0x40000000); + gr->func->init_sked_hww_esr(gr); nvkm_wr32(device, 0x405840, 0xc0000000); nvkm_wr32(device, 0x405844, 0x00ffffff); nvkm_mask(device, 0x419cc0, 0x00000008, 0x00000008); @@ -202,6 +202,7 @@ gm200_gr = { .init_rop_active_fbps = gm200_gr_init_rop_active_fbps, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2, + .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 2, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c index 676f58a9aceeb..72ea16ee842a7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c @@ -76,7 +76,7 @@ gp100_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x408030, 0xc0000000); nvkm_wr32(device, 0x404490, 0xc0000000); nvkm_wr32(device, 0x406018, 0xc0000000); - nvkm_wr32(device, 0x407020, 0x40000000); + gr->func->init_sked_hww_esr(gr); nvkm_wr32(device, 0x405840, 0xc0000000); nvkm_wr32(device, 0x405844, 0x00ffffff); nvkm_mask(device, 0x419cc0, 0x00000008, 0x00000008); @@ -134,6 +134,7 @@ gp100_gr = { .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_fecs_exceptions = gp100_gr_init_fecs_exceptions, .init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2, + .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 2, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c index 3694687c85dbf..309815bef601b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c @@ -51,6 +51,7 @@ gp102_gr = { .init_swdx_pes_mask = gp102_gr_init_swdx_pes_mask, .init_fecs_exceptions = gp100_gr_init_fecs_exceptions, .init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2, + .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 3, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c index c83ad01bad53b..1ae9e7d991f93 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c @@ -37,6 +37,7 @@ gp107_gr = { .init_swdx_pes_mask = gp102_gr_init_swdx_pes_mask, .init_fecs_exceptions = gp100_gr_init_fecs_exceptions, .init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2, + .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 1, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c index 8fef3b56cf8c2..68e212823063b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c @@ -35,6 +35,7 @@ gp10b_gr = { .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, .init_fecs_exceptions = gp100_gr_init_fecs_exceptions, .init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2, + .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 1, From 0feab0250d34c7114b442f49b1ce18a9906b543d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 055/165] drm/nouveau/gr/gf100-: virtualise init_419cc0 + apply fixes from traces Pulled some init out of main per-GPC/TPC loops to match RM. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 21 +++++++++++++++++-- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 2 ++ .../gpu/drm/nouveau/nvkm/engine/gr/gf104.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf108.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf110.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf117.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf119.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 4 ++-- .../gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk208.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 4 ++-- .../gpu/drm/nouveau/nvkm/engine/gr/gm200.c | 4 ++-- .../gpu/drm/nouveau/nvkm/engine/gr/gp100.c | 4 ++-- .../gpu/drm/nouveau/nvkm/engine/gr/gp102.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp107.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp10b.c | 1 + 17 files changed, 40 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 7ccd8f21c1e0e..ad18ef91d34e5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1914,6 +1914,20 @@ gf100_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device, return 0; } +void +gf100_gr_init_419cc0(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + int gpc, tpc; + + nvkm_mask(device, 0x419cc0, 0x00000008, 0x00000008); + + for (gpc = 0; gpc < gr->gpc_nr; gpc++) { + for (tpc = 0; tpc < gr->tpc_nr[gpc]; tpc++) + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000); + } +} + void gf100_gr_init_40601c(struct gf100_gr *gr) { @@ -2042,7 +2056,10 @@ gf100_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x405840, 0xc0000000); nvkm_wr32(device, 0x405844, 0x00ffffff); - nvkm_mask(device, 0x419cc0, 0x00000008, 0x00000008); + + if (gr->func->init_419cc0) + gr->func->init_419cc0(gr); + nvkm_mask(device, 0x419eb4, 0x00001000, 0x00001000); for (gpc = 0; gpc < gr->gpc_nr; gpc++) { @@ -2054,7 +2071,6 @@ gf100_gr_init(struct gf100_gr *gr) nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f); @@ -2113,6 +2129,7 @@ gf100_gr = { .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_40601c = gf100_gr_init_40601c, + .init_419cc0 = gf100_gr_init_419cc0, .mmio = gf100_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index c292cf3bebb1c..cab0948f507db 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -134,6 +134,7 @@ struct gf100_gr_func { void (*init_ds_hww_esr_2)(struct gf100_gr *); void (*init_40601c)(struct gf100_gr *); void (*init_sked_hww_esr)(struct gf100_gr *); + void (*init_419cc0)(struct gf100_gr *); void (*init_ppc_exceptions)(struct gf100_gr *); void (*set_hww_esr_report_mask)(struct gf100_gr *); const struct gf100_gr_pack *mmio; @@ -157,6 +158,7 @@ void gf100_gr_init_zcull(struct gf100_gr *); void gf100_gr_init_num_active_ltcs(struct gf100_gr *); void gf100_gr_init_fecs_exceptions(struct gf100_gr *); void gf100_gr_init_40601c(struct gf100_gr *); +void gf100_gr_init_419cc0(struct gf100_gr *); void gf117_gr_init_zcull(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c index 61d6eef70e689..8598e15b40aff 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c @@ -121,6 +121,7 @@ gf104_gr = { .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_40601c = gf100_gr_init_40601c, + .init_419cc0 = gf100_gr_init_419cc0, .mmio = gf104_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c index d4f712e7d6e97..83c71ff51a2e2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c @@ -119,6 +119,7 @@ gf108_gr = { .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_40601c = gf100_gr_init_40601c, + .init_419cc0 = gf100_gr_init_419cc0, .mmio = gf108_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c index 1b6c2f32ec921..b2b44890ae955 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c @@ -93,6 +93,7 @@ gf110_gr = { .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_40601c = gf100_gr_init_40601c, + .init_419cc0 = gf100_gr_init_419cc0, .mmio = gf110_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c index ae76e8183d1d1..ec91a595affe5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c @@ -157,6 +157,7 @@ gf117_gr = { .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_40601c = gf100_gr_init_40601c, + .init_419cc0 = gf100_gr_init_419cc0, .mmio = gf117_gr_pack_mmio, .fecs.ucode = &gf117_gr_fecs_ucode, .gpccs.ucode = &gf117_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c index a3970c31f9517..570527f0370c6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c @@ -184,6 +184,7 @@ gf119_gr = { .init_num_active_ltcs = gf100_gr_init_num_active_ltcs, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_40601c = gf100_gr_init_40601c, + .init_419cc0 = gf100_gr_init_419cc0, .mmio = gf119_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index 6ba604edaf952..dcd59af254202 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -460,7 +460,7 @@ gk104_gr_init(struct gf100_gr *gr) gr->func->init_sked_hww_esr(gr); nvkm_wr32(device, 0x405840, 0xc0000000); nvkm_wr32(device, 0x405844, 0x00ffffff); - nvkm_mask(device, 0x419cc0, 0x00000008, 0x00000008); + gr->func->init_419cc0(gr); nvkm_mask(device, 0x419eb4, 0x00001000, 0x00001000); gr->func->init_ppc_exceptions(gr); @@ -474,7 +474,6 @@ gk104_gr_init(struct gf100_gr *gr) nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f); @@ -534,6 +533,7 @@ gk104_gr = { .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_fecs_exceptions = gk104_gr_init_fecs_exceptions, .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, + .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk104_gr_pack_mmio, .fecs.ucode = &gk104_gr_fecs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index 7a07d24cc2279..bea0cd324a72a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -344,6 +344,7 @@ gk110_gr = { .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, + .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk110_gr_pack_mmio, .fecs.ucode = &gk110_gr_fecs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index 1c9f59cde3d2c..e4ae88de89585 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c @@ -110,6 +110,7 @@ gk110b_gr = { .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, + .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk110b_gr_pack_mmio, .fecs.ucode = &gk110_gr_fecs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c index 40c87242b54df..1e214d94ae981 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c @@ -169,6 +169,7 @@ gk208_gr = { .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, + .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk208_gr_pack_mmio, .fecs.ucode = &gk208_gr_fecs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index 3d180edbdcd76..df668b9e00e49 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -381,7 +381,7 @@ gm107_gr_init(struct gf100_gr *gr) gr->func->init_sked_hww_esr(gr); nvkm_wr32(device, 0x405840, 0xc0000000); nvkm_wr32(device, 0x405844, 0x00ffffff); - nvkm_mask(device, 0x419cc0, 0x00000008, 0x00000008); + gr->func->init_419cc0(gr); gr->func->init_ppc_exceptions(gr); @@ -394,7 +394,6 @@ gm107_gr_init(struct gf100_gr *gr) nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x430), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x00dffffe); @@ -457,6 +456,7 @@ gm107_gr = { .init_bios_2 = gm107_gr_init_bios_2, .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, + .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gm107_gr_pack_mmio, .fecs.ucode = &gm107_gr_fecs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index 9436ab37aa9e5..9f8171aae6010 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -109,7 +109,7 @@ gm200_gr_init(struct gf100_gr *gr) gr->func->init_sked_hww_esr(gr); nvkm_wr32(device, 0x405840, 0xc0000000); nvkm_wr32(device, 0x405844, 0x00ffffff); - nvkm_mask(device, 0x419cc0, 0x00000008, 0x00000008); + gr->func->init_419cc0(gr); gr->func->init_ppc_exceptions(gr); @@ -122,7 +122,6 @@ gm200_gr_init(struct gf100_gr *gr) nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x430), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x00dffffe); @@ -203,6 +202,7 @@ gm200_gr = { .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2, .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, + .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 2, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c index 72ea16ee842a7..7518d249f648c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c @@ -79,7 +79,7 @@ gp100_gr_init(struct gf100_gr *gr) gr->func->init_sked_hww_esr(gr); nvkm_wr32(device, 0x405840, 0xc0000000); nvkm_wr32(device, 0x405844, 0x00ffffff); - nvkm_mask(device, 0x419cc0, 0x00000008, 0x00000008); + gr->func->init_419cc0(gr); nvkm_mask(device, 0x419c9c, 0x00010000, 0x00010000); nvkm_mask(device, 0x419c9c, 0x00020000, 0x00020000); @@ -95,7 +95,6 @@ gp100_gr_init(struct gf100_gr *gr) nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x430), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x00dffffe); @@ -135,6 +134,7 @@ gp100_gr = { .init_fecs_exceptions = gp100_gr_init_fecs_exceptions, .init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2, .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, + .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 2, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c index 309815bef601b..230e2eeb17012 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c @@ -52,6 +52,7 @@ gp102_gr = { .init_fecs_exceptions = gp100_gr_init_fecs_exceptions, .init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2, .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, + .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 3, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c index 1ae9e7d991f93..55b7a7e70cde0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c @@ -38,6 +38,7 @@ gp107_gr = { .init_fecs_exceptions = gp100_gr_init_fecs_exceptions, .init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2, .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, + .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 1, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c index 68e212823063b..b13a48bc7da76 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c @@ -36,6 +36,7 @@ gp10b_gr = { .init_fecs_exceptions = gp100_gr_init_fecs_exceptions, .init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2, .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, + .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 1, From 0a84a51334b5d75decd23b735aab00ff4698eeb2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 056/165] drm/nouveau/gr/gf100-: virtualise init_419eb4 + apply fixes from traces Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 12 ++++++++++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 4 ++++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 15 +++++++++++++++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | 1 + 10 files changed, 37 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index ad18ef91d34e5..947278274846e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1914,6 +1914,13 @@ gf100_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device, return 0; } +void +gf100_gr_init_419eb4(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_mask(device, 0x419eb4, 0x00001000, 0x00001000); +} + void gf100_gr_init_419cc0(struct gf100_gr *gr) { @@ -2059,8 +2066,8 @@ gf100_gr_init(struct gf100_gr *gr) if (gr->func->init_419cc0) gr->func->init_419cc0(gr); - - nvkm_mask(device, 0x419eb4, 0x00001000, 0x00001000); + if (gr->func->init_419eb4) + gr->func->init_419eb4(gr); for (gpc = 0; gpc < gr->gpc_nr; gpc++) { nvkm_wr32(device, GPC_UNIT(gpc, 0x0420), 0xc0000000); @@ -2130,6 +2137,7 @@ gf100_gr = { .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_40601c = gf100_gr_init_40601c, .init_419cc0 = gf100_gr_init_419cc0, + .init_419eb4 = gf100_gr_init_419eb4, .mmio = gf100_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index cab0948f507db..1dae373fa0d74 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -135,6 +135,7 @@ struct gf100_gr_func { void (*init_40601c)(struct gf100_gr *); void (*init_sked_hww_esr)(struct gf100_gr *); void (*init_419cc0)(struct gf100_gr *); + void (*init_419eb4)(struct gf100_gr *); void (*init_ppc_exceptions)(struct gf100_gr *); void (*set_hww_esr_report_mask)(struct gf100_gr *); const struct gf100_gr_pack *mmio; @@ -159,6 +160,7 @@ void gf100_gr_init_num_active_ltcs(struct gf100_gr *); void gf100_gr_init_fecs_exceptions(struct gf100_gr *); void gf100_gr_init_40601c(struct gf100_gr *); void gf100_gr_init_419cc0(struct gf100_gr *); +void gf100_gr_init_419eb4(struct gf100_gr *); void gf117_gr_init_zcull(struct gf100_gr *); @@ -168,6 +170,8 @@ void gk104_gr_init_rop_active_fbps(struct gf100_gr *); void gk104_gr_init_ppc_exceptions(struct gf100_gr *); void gk104_gr_init_sked_hww_esr(struct gf100_gr *); +void gk110_gr_init_419eb4(struct gf100_gr *); + int gk20a_gr_init(struct gf100_gr *); int gm200_gr_rops(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c index 8598e15b40aff..59d4dac97d8c5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c @@ -122,6 +122,7 @@ gf104_gr = { .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_40601c = gf100_gr_init_40601c, .init_419cc0 = gf100_gr_init_419cc0, + .init_419eb4 = gf100_gr_init_419eb4, .mmio = gf104_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c index 83c71ff51a2e2..73cb23a71c522 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c @@ -120,6 +120,7 @@ gf108_gr = { .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_40601c = gf100_gr_init_40601c, .init_419cc0 = gf100_gr_init_419cc0, + .init_419eb4 = gf100_gr_init_419eb4, .mmio = gf108_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c index b2b44890ae955..1d7188e844f5f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c @@ -94,6 +94,7 @@ gf110_gr = { .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_40601c = gf100_gr_init_40601c, .init_419cc0 = gf100_gr_init_419cc0, + .init_419eb4 = gf100_gr_init_419eb4, .mmio = gf110_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c index ec91a595affe5..34655676ce39c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c @@ -158,6 +158,7 @@ gf117_gr = { .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_40601c = gf100_gr_init_40601c, .init_419cc0 = gf100_gr_init_419cc0, + .init_419eb4 = gf100_gr_init_419eb4, .mmio = gf117_gr_pack_mmio, .fecs.ucode = &gf117_gr_fecs_ucode, .gpccs.ucode = &gf117_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c index 570527f0370c6..28c00cb199955 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c @@ -185,6 +185,7 @@ gf119_gr = { .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_40601c = gf100_gr_init_40601c, .init_419cc0 = gf100_gr_init_419cc0, + .init_419eb4 = gf100_gr_init_419eb4, .mmio = gf119_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index dcd59af254202..775b474284864 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -461,7 +461,7 @@ gk104_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x405840, 0xc0000000); nvkm_wr32(device, 0x405844, 0x00ffffff); gr->func->init_419cc0(gr); - nvkm_mask(device, 0x419eb4, 0x00001000, 0x00001000); + gr->func->init_419eb4(gr); gr->func->init_ppc_exceptions(gr); @@ -534,6 +534,7 @@ gk104_gr = { .init_fecs_exceptions = gk104_gr_init_fecs_exceptions, .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_419cc0 = gf100_gr_init_419cc0, + .init_419eb4 = gf100_gr_init_419eb4, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk104_gr_pack_mmio, .fecs.ucode = &gk104_gr_fecs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index bea0cd324a72a..daaa4492d764e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -334,6 +334,20 @@ gk110_gr_gpccs_ucode = { .data.size = sizeof(gk110_grgpc_data), }; +void +gk110_gr_init_419eb4(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_mask(device, 0x419eb4, 0x00001000, 0x00001000); + nvkm_mask(device, 0x419eb4, 0x00002000, 0x00002000); + nvkm_mask(device, 0x419eb4, 0x00004000, 0x00004000); + nvkm_mask(device, 0x419eb4, 0x00008000, 0x00008000); + nvkm_mask(device, 0x419eb4, 0x00001000, 0x00000000); + nvkm_mask(device, 0x419eb4, 0x00002000, 0x00000000); + nvkm_mask(device, 0x419eb4, 0x00004000, 0x00000000); + nvkm_mask(device, 0x419eb4, 0x00008000, 0x00000000); +} + static const struct gf100_gr_func gk110_gr = { .init = gk104_gr_init, @@ -345,6 +359,7 @@ gk110_gr = { .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_419cc0 = gf100_gr_init_419cc0, + .init_419eb4 = gk110_gr_init_419eb4, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk110_gr_pack_mmio, .fecs.ucode = &gk110_gr_fecs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index e4ae88de89585..ee56b00c25d04 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c @@ -111,6 +111,7 @@ gk110b_gr = { .init_fecs_exceptions = gf100_gr_init_fecs_exceptions, .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_419cc0 = gf100_gr_init_419cc0, + .init_419eb4 = gk110_gr_init_419eb4, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk110b_gr_pack_mmio, .fecs.ucode = &gk110_gr_fecs_ucode, From 778f18c607e30206c1a791a4d356f1ed32bc1947 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 057/165] drm/nouveau/gr/gf100-: virtualise init_419c9c + apply fixes from traces Deliberately removed from non-GP100, as RM doesn't touch it. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c | 14 +++++++++++--- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 947278274846e..a379794df7612 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -2068,6 +2068,8 @@ gf100_gr_init(struct gf100_gr *gr) gr->func->init_419cc0(gr); if (gr->func->init_419eb4) gr->func->init_419eb4(gr); + if (gr->func->init_419c9c) + gr->func->init_419c9c(gr); for (gpc = 0; gpc < gr->gpc_nr; gpc++) { nvkm_wr32(device, GPC_UNIT(gpc, 0x0420), 0xc0000000); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 1dae373fa0d74..e328957453fbc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -136,6 +136,7 @@ struct gf100_gr_func { void (*init_sked_hww_esr)(struct gf100_gr *); void (*init_419cc0)(struct gf100_gr *); void (*init_419eb4)(struct gf100_gr *); + void (*init_419c9c)(struct gf100_gr *); void (*init_ppc_exceptions)(struct gf100_gr *); void (*set_hww_esr_report_mask)(struct gf100_gr *); const struct gf100_gr_pack *mmio; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c index 7518d249f648c..3fcbe1fc19cf7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c @@ -30,6 +30,14 @@ * PGRAPH engine/subdev functions ******************************************************************************/ +static void +gp100_gr_init_419c9c(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_mask(device, 0x419c9c, 0x00010000, 0x00010000); + nvkm_mask(device, 0x419c9c, 0x00020000, 0x00020000); +} + void gp100_gr_init_fecs_exceptions(struct gf100_gr *gr) { @@ -80,9 +88,8 @@ gp100_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x405840, 0xc0000000); nvkm_wr32(device, 0x405844, 0x00ffffff); gr->func->init_419cc0(gr); - - nvkm_mask(device, 0x419c9c, 0x00010000, 0x00010000); - nvkm_mask(device, 0x419c9c, 0x00020000, 0x00020000); + if (gr->func->init_419c9c) + gr->func->init_419c9c(gr); gr->func->init_ppc_exceptions(gr); @@ -135,6 +142,7 @@ gp100_gr = { .init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2, .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_419cc0 = gf100_gr_init_419cc0, + .init_419c9c = gp100_gr_init_419c9c, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .rops = gm200_gr_rops, .ppc_nr = 2, From 70d2148209abd851768396cb4719710de9aeddc0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 058/165] drm/nouveau/gr/gf100-: virtualise init_ppc_exceptions Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index a379794df7612..776442582b977 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -2071,6 +2071,9 @@ gf100_gr_init(struct gf100_gr *gr) if (gr->func->init_419c9c) gr->func->init_419c9c(gr); + if (gr->func->init_ppc_exceptions) + gr->func->init_ppc_exceptions(gr); + for (gpc = 0; gpc < gr->gpc_nr; gpc++) { nvkm_wr32(device, GPC_UNIT(gpc, 0x0420), 0xc0000000); nvkm_wr32(device, GPC_UNIT(gpc, 0x0900), 0xc0000000); From f3ef80c0c491bd1a5ae4c02acbdabb8c9cedb315 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 059/165] drm/nouveau/gr/gf100-: virtualise init_tex_hww_esr Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 11 ++++++++++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c | 1 + 17 files changed, 31 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 776442582b977..25f64ece92a4e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1914,6 +1914,13 @@ gf100_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device, return 0; } +void +gf100_gr_init_tex_hww_esr(struct gf100_gr *gr, int tpc, int gpc) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000); +} + void gf100_gr_init_419eb4(struct gf100_gr *gr) { @@ -2082,7 +2089,8 @@ gf100_gr_init(struct gf100_gr *gr) for (tpc = 0; tpc < gr->tpc_nr[gpc]; tpc++) { nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000); + if (gr->func->init_tex_hww_esr) + gr->func->init_tex_hww_esr(gr, gpc, tpc); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f); @@ -2143,6 +2151,7 @@ gf100_gr = { .init_40601c = gf100_gr_init_40601c, .init_419cc0 = gf100_gr_init_419cc0, .init_419eb4 = gf100_gr_init_419eb4, + .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .mmio = gf100_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index e328957453fbc..0bbe11dd8bddc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -138,6 +138,7 @@ struct gf100_gr_func { void (*init_419eb4)(struct gf100_gr *); void (*init_419c9c)(struct gf100_gr *); void (*init_ppc_exceptions)(struct gf100_gr *); + void (*init_tex_hww_esr)(struct gf100_gr *, int gpc, int tpc); void (*set_hww_esr_report_mask)(struct gf100_gr *); const struct gf100_gr_pack *mmio; struct { @@ -162,6 +163,7 @@ void gf100_gr_init_fecs_exceptions(struct gf100_gr *); void gf100_gr_init_40601c(struct gf100_gr *); void gf100_gr_init_419cc0(struct gf100_gr *); void gf100_gr_init_419eb4(struct gf100_gr *); +void gf100_gr_init_tex_hww_esr(struct gf100_gr *, int, int); void gf117_gr_init_zcull(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c index 59d4dac97d8c5..ff03f13b087f6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c @@ -123,6 +123,7 @@ gf104_gr = { .init_40601c = gf100_gr_init_40601c, .init_419cc0 = gf100_gr_init_419cc0, .init_419eb4 = gf100_gr_init_419eb4, + .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .mmio = gf104_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c index 73cb23a71c522..ce60f5aa9901f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c @@ -121,6 +121,7 @@ gf108_gr = { .init_40601c = gf100_gr_init_40601c, .init_419cc0 = gf100_gr_init_419cc0, .init_419eb4 = gf100_gr_init_419eb4, + .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .mmio = gf108_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c index 1d7188e844f5f..4c21cbe3df971 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c @@ -95,6 +95,7 @@ gf110_gr = { .init_40601c = gf100_gr_init_40601c, .init_419cc0 = gf100_gr_init_419cc0, .init_419eb4 = gf100_gr_init_419eb4, + .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .mmio = gf110_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c index 34655676ce39c..10340e9f3e1a8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c @@ -159,6 +159,7 @@ gf117_gr = { .init_40601c = gf100_gr_init_40601c, .init_419cc0 = gf100_gr_init_419cc0, .init_419eb4 = gf100_gr_init_419eb4, + .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .mmio = gf117_gr_pack_mmio, .fecs.ucode = &gf117_gr_fecs_ucode, .gpccs.ucode = &gf117_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c index 28c00cb199955..5147c590dc20b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c @@ -186,6 +186,7 @@ gf119_gr = { .init_40601c = gf100_gr_init_40601c, .init_419cc0 = gf100_gr_init_419cc0, .init_419eb4 = gf100_gr_init_419eb4, + .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .mmio = gf119_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index 775b474284864..1805196372d51 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -473,7 +473,7 @@ gk104_gr_init(struct gf100_gr *gr) for (tpc = 0; tpc < gr->tpc_nr[gpc]; tpc++) { nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000); + gr->func->init_tex_hww_esr(gr, gpc, tpc); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f); @@ -536,6 +536,7 @@ gk104_gr = { .init_419cc0 = gf100_gr_init_419cc0, .init_419eb4 = gf100_gr_init_419eb4, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, + .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .mmio = gk104_gr_pack_mmio, .fecs.ucode = &gk104_gr_fecs_ucode, .gpccs.ucode = &gk104_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index daaa4492d764e..f4c73a929756f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -361,6 +361,7 @@ gk110_gr = { .init_419cc0 = gf100_gr_init_419cc0, .init_419eb4 = gk110_gr_init_419eb4, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, + .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .mmio = gk110_gr_pack_mmio, .fecs.ucode = &gk110_gr_fecs_ucode, .gpccs.ucode = &gk110_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index ee56b00c25d04..b585ab22ccc1d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c @@ -113,6 +113,7 @@ gk110b_gr = { .init_419cc0 = gf100_gr_init_419cc0, .init_419eb4 = gk110_gr_init_419eb4, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, + .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .mmio = gk110b_gr_pack_mmio, .fecs.ucode = &gk110_gr_fecs_ucode, .gpccs.ucode = &gk110_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c index 1e214d94ae981..7d1f585a7e545 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c @@ -171,6 +171,7 @@ gk208_gr = { .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, + .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .mmio = gk208_gr_pack_mmio, .fecs.ucode = &gk208_gr_fecs_ucode, .gpccs.ucode = &gk208_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index df668b9e00e49..8ee7723bfee4d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -393,7 +393,7 @@ gm107_gr_init(struct gf100_gr *gr) for (tpc = 0; tpc < gr->tpc_nr[gpc]; tpc++) { nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000); + gr->func->init_tex_hww_esr(gr, gpc, tpc); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x430), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x00dffffe); @@ -458,6 +458,7 @@ gm107_gr = { .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, + .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .mmio = gm107_gr_pack_mmio, .fecs.ucode = &gm107_gr_fecs_ucode, .gpccs.ucode = &gm107_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index 9f8171aae6010..0d020098f6f30 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -121,7 +121,7 @@ gm200_gr_init(struct gf100_gr *gr) for (tpc = 0; tpc < gr->tpc_nr[gpc]; tpc++) { nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000); + gr->func->init_tex_hww_esr(gr, gpc, tpc); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x430), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x00dffffe); @@ -204,6 +204,7 @@ gm200_gr = { .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, + .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .rops = gm200_gr_rops, .ppc_nr = 2, .grctx = &gm200_grctx, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c index 3fcbe1fc19cf7..c7986087a3dfa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c @@ -101,7 +101,7 @@ gp100_gr_init(struct gf100_gr *gr) for (tpc = 0; tpc < gr->tpc_nr[gpc]; tpc++) { nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000); + gr->func->init_tex_hww_esr(gr, gpc, tpc); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x430), 0xc0000000); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x00dffffe); @@ -144,6 +144,7 @@ gp100_gr = { .init_419cc0 = gf100_gr_init_419cc0, .init_419c9c = gp100_gr_init_419c9c, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, + .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .rops = gm200_gr_rops, .ppc_nr = 2, .grctx = &gp100_grctx, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c index 230e2eeb17012..a7fe2d9f48595 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c @@ -54,6 +54,7 @@ gp102_gr = { .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, + .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .rops = gm200_gr_rops, .ppc_nr = 3, .grctx = &gp102_grctx, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c index 55b7a7e70cde0..f085d01f36115 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c @@ -40,6 +40,7 @@ gp107_gr = { .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, + .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .rops = gm200_gr_rops, .ppc_nr = 1, .grctx = &gp107_grctx, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c index b13a48bc7da76..9530edc837a93 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c @@ -38,6 +38,7 @@ gp10b_gr = { .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, + .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .rops = gm200_gr_rops, .ppc_nr = 1, .grctx = &gp102_grctx, From ab4d49a349653dcd902be8974c4f7927cd49b11d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 060/165] drm/nouveau/gr/gf100-: virtualise init_504430 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 3 +++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 10 +++++++++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c | 1 + 8 files changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 25f64ece92a4e..274ff014ab9e9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -2092,6 +2092,8 @@ gf100_gr_init(struct gf100_gr *gr) if (gr->func->init_tex_hww_esr) gr->func->init_tex_hww_esr(gr, gpc, tpc); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); + if (gr->func->init_504430) + gr->func->init_504430(gr, gpc, tpc); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 0bbe11dd8bddc..81d5931eff325 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -139,6 +139,7 @@ struct gf100_gr_func { void (*init_419c9c)(struct gf100_gr *); void (*init_ppc_exceptions)(struct gf100_gr *); void (*init_tex_hww_esr)(struct gf100_gr *, int gpc, int tpc); + void (*init_504430)(struct gf100_gr *, int gpc, int tpc); void (*set_hww_esr_report_mask)(struct gf100_gr *); const struct gf100_gr_pack *mmio; struct { @@ -175,6 +176,8 @@ void gk104_gr_init_sked_hww_esr(struct gf100_gr *); void gk110_gr_init_419eb4(struct gf100_gr *); +void gm107_gr_init_504430(struct gf100_gr *, int, int); + int gk20a_gr_init(struct gf100_gr *); int gm200_gr_rops(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index 8ee7723bfee4d..4c8c2561282b2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -281,6 +281,13 @@ gm107_gr_pack_mmio[] = { * PGRAPH engine/subdev functions ******************************************************************************/ +void +gm107_gr_init_504430(struct gf100_gr *gr, int gpc, int tpc) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x430), 0xc0000000); +} + static void gm107_gr_init_bios_2(struct gf100_gr *gr) { @@ -395,7 +402,7 @@ gm107_gr_init(struct gf100_gr *gr) nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); gr->func->init_tex_hww_esr(gr, gpc, tpc); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x430), 0xc0000000); + gr->func->init_504430(gr, gpc, tpc); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x00dffffe); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x64c), 0x00000005); } @@ -459,6 +466,7 @@ gm107_gr = { .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, + .init_504430 = gm107_gr_init_504430, .mmio = gm107_gr_pack_mmio, .fecs.ucode = &gm107_gr_fecs_ucode, .gpccs.ucode = &gm107_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index 0d020098f6f30..69f191ec78ab6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -123,7 +123,7 @@ gm200_gr_init(struct gf100_gr *gr) nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); gr->func->init_tex_hww_esr(gr, gpc, tpc); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x430), 0xc0000000); + gr->func->init_504430(gr, gpc, tpc); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x00dffffe); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x64c), 0x00000005); } @@ -205,6 +205,7 @@ gm200_gr = { .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, + .init_504430 = gm107_gr_init_504430, .rops = gm200_gr_rops, .ppc_nr = 2, .grctx = &gm200_grctx, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c index c7986087a3dfa..76a9416fa4ede 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c @@ -103,7 +103,7 @@ gp100_gr_init(struct gf100_gr *gr) nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); gr->func->init_tex_hww_esr(gr, gpc, tpc); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x430), 0xc0000000); + gr->func->init_504430(gr, gpc, gpc); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x00dffffe); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x64c), 0x00000105); } @@ -145,6 +145,7 @@ gp100_gr = { .init_419c9c = gp100_gr_init_419c9c, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, + .init_504430 = gm107_gr_init_504430, .rops = gm200_gr_rops, .ppc_nr = 2, .grctx = &gp100_grctx, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c index a7fe2d9f48595..7072578be6484 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c @@ -55,6 +55,7 @@ gp102_gr = { .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, + .init_504430 = gm107_gr_init_504430, .rops = gm200_gr_rops, .ppc_nr = 3, .grctx = &gp102_grctx, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c index f085d01f36115..f23f70f027e27 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c @@ -41,6 +41,7 @@ gp107_gr = { .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, + .init_504430 = gm107_gr_init_504430, .rops = gm200_gr_rops, .ppc_nr = 1, .grctx = &gp107_grctx, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c index 9530edc837a93..0ff175960a36c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c @@ -39,6 +39,7 @@ gp10b_gr = { .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, + .init_504430 = gm107_gr_init_504430, .rops = gm200_gr_rops, .ppc_nr = 1, .grctx = &gp102_grctx, From 4615e9b4387f142e4ff495dc61525249a6926e91 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 061/165] drm/nouveau/gr/gf100-: virtualise init_shader_exceptions Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 14 +++++++++++--- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 4 ++++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 12 ++++++++++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c | 12 ++++++++++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c | 1 + 17 files changed, 50 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 274ff014ab9e9..071b3c1a93ab7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1915,7 +1915,15 @@ gf100_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device, } void -gf100_gr_init_tex_hww_esr(struct gf100_gr *gr, int tpc, int gpc) +gf100_gr_init_shader_exceptions(struct gf100_gr *gr, int gpc, int tpc) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe); + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f); +} + +void +gf100_gr_init_tex_hww_esr(struct gf100_gr *gr, int gpc, int tpc) { struct nvkm_device *device = gr->base.engine.subdev.device; nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000); @@ -2094,8 +2102,7 @@ gf100_gr_init(struct gf100_gr *gr) nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); if (gr->func->init_504430) gr->func->init_504430(gr, gpc, tpc); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f); + gr->func->init_shader_exceptions(gr, gpc, tpc); } nvkm_wr32(device, GPC_UNIT(gpc, 0x2c90), 0xffffffff); nvkm_wr32(device, GPC_UNIT(gpc, 0x2c94), 0xffffffff); @@ -2154,6 +2161,7 @@ gf100_gr = { .init_419cc0 = gf100_gr_init_419cc0, .init_419eb4 = gf100_gr_init_419eb4, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, + .init_shader_exceptions = gf100_gr_init_shader_exceptions, .mmio = gf100_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 81d5931eff325..02505c020f6aa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -140,6 +140,7 @@ struct gf100_gr_func { void (*init_ppc_exceptions)(struct gf100_gr *); void (*init_tex_hww_esr)(struct gf100_gr *, int gpc, int tpc); void (*init_504430)(struct gf100_gr *, int gpc, int tpc); + void (*init_shader_exceptions)(struct gf100_gr *, int gpc, int tpc); void (*set_hww_esr_report_mask)(struct gf100_gr *); const struct gf100_gr_pack *mmio; struct { @@ -165,6 +166,7 @@ void gf100_gr_init_40601c(struct gf100_gr *); void gf100_gr_init_419cc0(struct gf100_gr *); void gf100_gr_init_419eb4(struct gf100_gr *); void gf100_gr_init_tex_hww_esr(struct gf100_gr *, int, int); +void gf100_gr_init_shader_exceptions(struct gf100_gr *, int, int); void gf117_gr_init_zcull(struct gf100_gr *); @@ -177,6 +179,7 @@ void gk104_gr_init_sked_hww_esr(struct gf100_gr *); void gk110_gr_init_419eb4(struct gf100_gr *); void gm107_gr_init_504430(struct gf100_gr *, int, int); +void gm107_gr_init_shader_exceptions(struct gf100_gr *, int, int); int gk20a_gr_init(struct gf100_gr *); @@ -187,6 +190,7 @@ void gm200_gr_init_ds_hww_esr_2(struct gf100_gr *); int gp100_gr_init(struct gf100_gr *); void gp100_gr_init_rop_active_fbps(struct gf100_gr *); void gp100_gr_init_fecs_exceptions(struct gf100_gr *); +void gp100_gr_init_shader_exceptions(struct gf100_gr *, int, int); void gp102_gr_init_swdx_pes_mask(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c index ff03f13b087f6..c61544487ed71 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c @@ -124,6 +124,7 @@ gf104_gr = { .init_419cc0 = gf100_gr_init_419cc0, .init_419eb4 = gf100_gr_init_419eb4, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, + .init_shader_exceptions = gf100_gr_init_shader_exceptions, .mmio = gf104_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c index ce60f5aa9901f..8e8a99e54f567 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c @@ -122,6 +122,7 @@ gf108_gr = { .init_419cc0 = gf100_gr_init_419cc0, .init_419eb4 = gf100_gr_init_419eb4, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, + .init_shader_exceptions = gf100_gr_init_shader_exceptions, .mmio = gf108_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c index 4c21cbe3df971..6496411b7dfee 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c @@ -96,6 +96,7 @@ gf110_gr = { .init_419cc0 = gf100_gr_init_419cc0, .init_419eb4 = gf100_gr_init_419eb4, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, + .init_shader_exceptions = gf100_gr_init_shader_exceptions, .mmio = gf110_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c index 10340e9f3e1a8..21aa8e2270027 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c @@ -160,6 +160,7 @@ gf117_gr = { .init_419cc0 = gf100_gr_init_419cc0, .init_419eb4 = gf100_gr_init_419eb4, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, + .init_shader_exceptions = gf100_gr_init_shader_exceptions, .mmio = gf117_gr_pack_mmio, .fecs.ucode = &gf117_gr_fecs_ucode, .gpccs.ucode = &gf117_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c index 5147c590dc20b..7d73a9f8ca485 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c @@ -187,6 +187,7 @@ gf119_gr = { .init_419cc0 = gf100_gr_init_419cc0, .init_419eb4 = gf100_gr_init_419eb4, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, + .init_shader_exceptions = gf100_gr_init_shader_exceptions, .mmio = gf119_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index 1805196372d51..20735319e9205 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -475,8 +475,7 @@ gk104_gr_init(struct gf100_gr *gr) nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); gr->func->init_tex_hww_esr(gr, gpc, tpc); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f); + gr->func->init_shader_exceptions(gr, gpc, tpc); } nvkm_wr32(device, GPC_UNIT(gpc, 0x2c90), 0xffffffff); nvkm_wr32(device, GPC_UNIT(gpc, 0x2c94), 0xffffffff); @@ -537,6 +536,7 @@ gk104_gr = { .init_419eb4 = gf100_gr_init_419eb4, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, + .init_shader_exceptions = gf100_gr_init_shader_exceptions, .mmio = gk104_gr_pack_mmio, .fecs.ucode = &gk104_gr_fecs_ucode, .gpccs.ucode = &gk104_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index f4c73a929756f..e52cc24233538 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -362,6 +362,7 @@ gk110_gr = { .init_419eb4 = gk110_gr_init_419eb4, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, + .init_shader_exceptions = gf100_gr_init_shader_exceptions, .mmio = gk110_gr_pack_mmio, .fecs.ucode = &gk110_gr_fecs_ucode, .gpccs.ucode = &gk110_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index b585ab22ccc1d..35303818c4a29 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c @@ -114,6 +114,7 @@ gk110b_gr = { .init_419eb4 = gk110_gr_init_419eb4, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, + .init_shader_exceptions = gf100_gr_init_shader_exceptions, .mmio = gk110b_gr_pack_mmio, .fecs.ucode = &gk110_gr_fecs_ucode, .gpccs.ucode = &gk110_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c index 7d1f585a7e545..4e5cd540a321c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c @@ -172,6 +172,7 @@ gk208_gr = { .init_419cc0 = gf100_gr_init_419cc0, .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, + .init_shader_exceptions = gf100_gr_init_shader_exceptions, .mmio = gk208_gr_pack_mmio, .fecs.ucode = &gk208_gr_fecs_ucode, .gpccs.ucode = &gk208_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index 4c8c2561282b2..3b8ae137798f4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -281,6 +281,14 @@ gm107_gr_pack_mmio[] = { * PGRAPH engine/subdev functions ******************************************************************************/ +void +gm107_gr_init_shader_exceptions(struct gf100_gr *gr, int gpc, int tpc) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x00dffffe); + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x64c), 0x00000005); +} + void gm107_gr_init_504430(struct gf100_gr *gr, int gpc, int tpc) { @@ -403,8 +411,7 @@ gm107_gr_init(struct gf100_gr *gr) gr->func->init_tex_hww_esr(gr, gpc, tpc); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); gr->func->init_504430(gr, gpc, tpc); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x00dffffe); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x64c), 0x00000005); + gr->func->init_shader_exceptions(gr, gpc, tpc); } nvkm_wr32(device, GPC_UNIT(gpc, 0x2c90), 0xffffffff); nvkm_wr32(device, GPC_UNIT(gpc, 0x2c94), 0xffffffff); @@ -467,6 +474,7 @@ gm107_gr = { .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_504430 = gm107_gr_init_504430, + .init_shader_exceptions = gm107_gr_init_shader_exceptions, .mmio = gm107_gr_pack_mmio, .fecs.ucode = &gm107_gr_fecs_ucode, .gpccs.ucode = &gm107_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index 69f191ec78ab6..3e2a78dfb1fdf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -124,8 +124,7 @@ gm200_gr_init(struct gf100_gr *gr) gr->func->init_tex_hww_esr(gr, gpc, tpc); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); gr->func->init_504430(gr, gpc, tpc); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x00dffffe); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x64c), 0x00000005); + gr->func->init_shader_exceptions(gr, gpc, tpc); } nvkm_wr32(device, GPC_UNIT(gpc, 0x2c90), 0xffffffff); nvkm_wr32(device, GPC_UNIT(gpc, 0x2c94), 0xffffffff); @@ -206,6 +205,7 @@ gm200_gr = { .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_504430 = gm107_gr_init_504430, + .init_shader_exceptions = gm107_gr_init_shader_exceptions, .rops = gm200_gr_rops, .ppc_nr = 2, .grctx = &gm200_grctx, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c index 76a9416fa4ede..48a0e144d9838 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c @@ -30,6 +30,14 @@ * PGRAPH engine/subdev functions ******************************************************************************/ +void +gp100_gr_init_shader_exceptions(struct gf100_gr *gr, int gpc, int tpc) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x00dffffe); + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x64c), 0x00000105); +} + static void gp100_gr_init_419c9c(struct gf100_gr *gr) { @@ -104,8 +112,7 @@ gp100_gr_init(struct gf100_gr *gr) gr->func->init_tex_hww_esr(gr, gpc, tpc); nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); gr->func->init_504430(gr, gpc, gpc); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x00dffffe); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x64c), 0x00000105); + gr->func->init_shader_exceptions(gr, gpc, tpc); } nvkm_wr32(device, GPC_UNIT(gpc, 0x2c90), 0xffffffff); nvkm_wr32(device, GPC_UNIT(gpc, 0x2c94), 0xffffffff); @@ -146,6 +153,7 @@ gp100_gr = { .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_504430 = gm107_gr_init_504430, + .init_shader_exceptions = gp100_gr_init_shader_exceptions, .rops = gm200_gr_rops, .ppc_nr = 2, .grctx = &gp100_grctx, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c index 7072578be6484..7ce06520fdc99 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c @@ -56,6 +56,7 @@ gp102_gr = { .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_504430 = gm107_gr_init_504430, + .init_shader_exceptions = gp100_gr_init_shader_exceptions, .rops = gm200_gr_rops, .ppc_nr = 3, .grctx = &gp102_grctx, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c index f23f70f027e27..dbb2d4e71442d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c @@ -42,6 +42,7 @@ gp107_gr = { .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_504430 = gm107_gr_init_504430, + .init_shader_exceptions = gp100_gr_init_shader_exceptions, .rops = gm200_gr_rops, .ppc_nr = 1, .grctx = &gp107_grctx, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c index 0ff175960a36c..7f23d8bd977fe 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c @@ -40,6 +40,7 @@ gp10b_gr = { .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_504430 = gm107_gr_init_504430, + .init_shader_exceptions = gp100_gr_init_shader_exceptions, .rops = gm200_gr_rops, .ppc_nr = 1, .grctx = &gp102_grctx, From 6df6d2b95e9411f499b7d71a6cc495cff7548d6e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 062/165] drm/nouveau/gr/gf100-: apply be exception fixes from traces Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 4 ++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 071b3c1a93ab7..452b52798603e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -2109,8 +2109,8 @@ gf100_gr_init(struct gf100_gr *gr) } for (rop = 0; rop < gr->rop_nr; rop++) { - nvkm_wr32(device, ROP_UNIT(rop, 0x144), 0xc0000000); - nvkm_wr32(device, ROP_UNIT(rop, 0x070), 0xc0000000); + nvkm_wr32(device, ROP_UNIT(rop, 0x144), 0x40000000); + nvkm_wr32(device, ROP_UNIT(rop, 0x070), 0x40000000); nvkm_wr32(device, ROP_UNIT(rop, 0x204), 0xffffffff); nvkm_wr32(device, ROP_UNIT(rop, 0x208), 0xffffffff); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index 20735319e9205..1822509fca21d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -482,8 +482,8 @@ gk104_gr_init(struct gf100_gr *gr) } for (rop = 0; rop < gr->rop_nr; rop++) { - nvkm_wr32(device, ROP_UNIT(rop, 0x144), 0xc0000000); - nvkm_wr32(device, ROP_UNIT(rop, 0x070), 0xc0000000); + nvkm_wr32(device, ROP_UNIT(rop, 0x144), 0x40000000); + nvkm_wr32(device, ROP_UNIT(rop, 0x070), 0x40000000); nvkm_wr32(device, ROP_UNIT(rop, 0x204), 0xffffffff); nvkm_wr32(device, ROP_UNIT(rop, 0x208), 0xffffffff); } From 04547482aed8c77b823de9427c3f0a7b481a351a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 063/165] drm/nouveau/gr/gf100-: virtualise init_400054 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 10 +++++++++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 3 +++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 9 ++++++++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c | 3 ++- 13 files changed, 32 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 452b52798603e..ac4c0d8478fa5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1914,6 +1914,12 @@ gf100_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device, return 0; } +void +gf100_gr_init_400054(struct gf100_gr *gr) +{ + nvkm_wr32(gr->base.engine.subdev.device, 0x400054, 0x34ce3464); +} + void gf100_gr_init_shader_exceptions(struct gf100_gr *gr, int gpc, int tpc) { @@ -2122,7 +2128,8 @@ gf100_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x40011c, 0xffffffff); nvkm_wr32(device, 0x400134, 0xffffffff); - nvkm_wr32(device, 0x400054, 0x34ce3464); + if (gr->func->init_400054) + gr->func->init_400054(gr); gf100_gr_zbc_init(gr); @@ -2162,6 +2169,7 @@ gf100_gr = { .init_419eb4 = gf100_gr_init_419eb4, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, + .init_400054 = gf100_gr_init_400054, .mmio = gf100_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 02505c020f6aa..9a57f1a7fb7cc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -141,6 +141,7 @@ struct gf100_gr_func { void (*init_tex_hww_esr)(struct gf100_gr *, int gpc, int tpc); void (*init_504430)(struct gf100_gr *, int gpc, int tpc); void (*init_shader_exceptions)(struct gf100_gr *, int gpc, int tpc); + void (*init_400054)(struct gf100_gr *); void (*set_hww_esr_report_mask)(struct gf100_gr *); const struct gf100_gr_pack *mmio; struct { @@ -167,6 +168,7 @@ void gf100_gr_init_419cc0(struct gf100_gr *); void gf100_gr_init_419eb4(struct gf100_gr *); void gf100_gr_init_tex_hww_esr(struct gf100_gr *, int, int); void gf100_gr_init_shader_exceptions(struct gf100_gr *, int, int); +void gf100_gr_init_400054(struct gf100_gr *); void gf117_gr_init_zcull(struct gf100_gr *); @@ -180,6 +182,7 @@ void gk110_gr_init_419eb4(struct gf100_gr *); void gm107_gr_init_504430(struct gf100_gr *, int, int); void gm107_gr_init_shader_exceptions(struct gf100_gr *, int, int); +void gm107_gr_init_400054(struct gf100_gr *); int gk20a_gr_init(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c index c61544487ed71..d5276cab7f7b6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c @@ -125,6 +125,7 @@ gf104_gr = { .init_419eb4 = gf100_gr_init_419eb4, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, + .init_400054 = gf100_gr_init_400054, .mmio = gf104_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c index 8e8a99e54f567..8f22a311dccb7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c @@ -123,6 +123,7 @@ gf108_gr = { .init_419eb4 = gf100_gr_init_419eb4, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, + .init_400054 = gf100_gr_init_400054, .mmio = gf108_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c index 6496411b7dfee..fcbfdc7e9b266 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c @@ -97,6 +97,7 @@ gf110_gr = { .init_419eb4 = gf100_gr_init_419eb4, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, + .init_400054 = gf100_gr_init_400054, .mmio = gf110_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c index 21aa8e2270027..f526ccddaf5ed 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c @@ -161,6 +161,7 @@ gf117_gr = { .init_419eb4 = gf100_gr_init_419eb4, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, + .init_400054 = gf100_gr_init_400054, .mmio = gf117_gr_pack_mmio, .fecs.ucode = &gf117_gr_fecs_ucode, .gpccs.ucode = &gf117_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c index 7d73a9f8ca485..5d3d22fb5c86f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c @@ -188,6 +188,7 @@ gf119_gr = { .init_419eb4 = gf100_gr_init_419eb4, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, + .init_400054 = gf100_gr_init_400054, .mmio = gf119_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index 1822509fca21d..36f32e6ef9379 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -495,7 +495,7 @@ gk104_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x40011c, 0xffffffff); nvkm_wr32(device, 0x400134, 0xffffffff); - nvkm_wr32(device, 0x400054, 0x34ce3464); + gr->func->init_400054(gr); gf100_gr_zbc_init(gr); @@ -537,6 +537,7 @@ gk104_gr = { .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, + .init_400054 = gf100_gr_init_400054, .mmio = gk104_gr_pack_mmio, .fecs.ucode = &gk104_gr_fecs_ucode, .gpccs.ucode = &gk104_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index e52cc24233538..7bcea8181919b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -363,6 +363,7 @@ gk110_gr = { .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, + .init_400054 = gf100_gr_init_400054, .mmio = gk110_gr_pack_mmio, .fecs.ucode = &gk110_gr_fecs_ucode, .gpccs.ucode = &gk110_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index 35303818c4a29..5af2a54e60bc0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c @@ -115,6 +115,7 @@ gk110b_gr = { .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, + .init_400054 = gf100_gr_init_400054, .mmio = gk110b_gr_pack_mmio, .fecs.ucode = &gk110_gr_fecs_ucode, .gpccs.ucode = &gk110_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c index 4e5cd540a321c..dd08373a96b56 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c @@ -173,6 +173,7 @@ gk208_gr = { .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, + .init_400054 = gf100_gr_init_400054, .mmio = gk208_gr_pack_mmio, .fecs.ucode = &gk208_gr_fecs_ucode, .gpccs.ucode = &gk208_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index 3b8ae137798f4..4680d99b59ba1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -281,6 +281,12 @@ gm107_gr_pack_mmio[] = { * PGRAPH engine/subdev functions ******************************************************************************/ +void +gm107_gr_init_400054(struct gf100_gr *gr) +{ + nvkm_wr32(gr->base.engine.subdev.device, 0x400054, 0x2c350f63); +} + void gm107_gr_init_shader_exceptions(struct gf100_gr *gr, int gpc, int tpc) { @@ -431,7 +437,7 @@ gm107_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x40011c, 0xffffffff); nvkm_wr32(device, 0x400134, 0xffffffff); - nvkm_wr32(device, 0x400054, 0x2c350f63); + gr->func->init_400054(gr); gf100_gr_zbc_init(gr); @@ -475,6 +481,7 @@ gm107_gr = { .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_504430 = gm107_gr_init_504430, .init_shader_exceptions = gm107_gr_init_shader_exceptions, + .init_400054 = gm107_gr_init_400054, .mmio = gm107_gr_pack_mmio, .fecs.ucode = &gm107_gr_fecs_ucode, .gpccs.ucode = &gm107_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index 3e2a78dfb1fdf..bbe18873aee2f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -144,7 +144,7 @@ gm200_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x40011c, 0xffffffff); nvkm_wr32(device, 0x400134, 0xffffffff); - nvkm_wr32(device, 0x400054, 0x2c350f63); + gr->func->init_400054(gr); gf100_gr_zbc_init(gr); @@ -206,6 +206,7 @@ gm200_gr = { .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_504430 = gm107_gr_init_504430, .init_shader_exceptions = gm107_gr_init_shader_exceptions, + .init_400054 = gm107_gr_init_400054, .rops = gm200_gr_rops, .ppc_nr = 2, .grctx = &gm200_grctx, From 525230cb204db5edb0ffc42e324612809c663c75 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 064/165] drm/nouveau/gr/gf100-: delete duplicated init code Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 2 - .../gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 78 +------------------ .../gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/gk208.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 77 +----------------- .../gpu/drm/nouveau/nvkm/engine/gr/gm200.c | 76 +----------------- .../gpu/drm/nouveau/nvkm/engine/gr/gp100.c | 77 +----------------- .../gpu/drm/nouveau/nvkm/engine/gr/gp102.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/gp107.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/gp10b.c | 2 +- 11 files changed, 10 insertions(+), 312 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 9a57f1a7fb7cc..9ed51dc851dfe 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -172,7 +172,6 @@ void gf100_gr_init_400054(struct gf100_gr *); void gf117_gr_init_zcull(struct gf100_gr *); -int gk104_gr_init(struct gf100_gr *); void gk104_gr_init_vsc_stream_master(struct gf100_gr *); void gk104_gr_init_rop_active_fbps(struct gf100_gr *); void gk104_gr_init_ppc_exceptions(struct gf100_gr *); @@ -190,7 +189,6 @@ int gm200_gr_rops(struct gf100_gr *); void gm200_gr_init_num_active_ltcs(struct gf100_gr *); void gm200_gr_init_ds_hww_esr_2(struct gf100_gr *); -int gp100_gr_init(struct gf100_gr *); void gp100_gr_init_rop_active_fbps(struct gf100_gr *); void gp100_gr_init_fecs_exceptions(struct gf100_gr *); void gp100_gr_init_shader_exceptions(struct gf100_gr *, int, int); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index 36f32e6ef9379..2e5c48b61ac81 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -426,82 +426,6 @@ gk104_gr_init_vsc_stream_master(struct gf100_gr *gr) nvkm_wr32(device, GPC_UNIT(0, 0x3018), 0x00000001); } -int -gk104_gr_init(struct gf100_gr *gr) -{ - struct nvkm_device *device = gr->base.engine.subdev.device; - int gpc, tpc, rop; - - gr->func->init_gpc_mmu(gr); - - gf100_gr_mmio(gr, gr->func->mmio); - if (gr->func->clkgate_pack) - nvkm_therm_clkgate_init(gr->base.engine.subdev.device->therm, - gr->func->clkgate_pack); - - gr->func->init_vsc_stream_master(gr); - gr->func->init_zcull(gr); - gr->func->init_num_active_ltcs(gr); - - gr->func->init_rop_active_fbps(gr); - - nvkm_wr32(device, 0x400500, 0x00010001); - - nvkm_wr32(device, 0x400100, 0xffffffff); - nvkm_wr32(device, 0x40013c, 0xffffffff); - nvkm_wr32(device, 0x400124, 0x00000002); - - gr->func->init_fecs_exceptions(gr); - nvkm_wr32(device, 0x404000, 0xc0000000); - nvkm_wr32(device, 0x404600, 0xc0000000); - nvkm_wr32(device, 0x408030, 0xc0000000); - nvkm_wr32(device, 0x404490, 0xc0000000); - nvkm_wr32(device, 0x406018, 0xc0000000); - gr->func->init_sked_hww_esr(gr); - nvkm_wr32(device, 0x405840, 0xc0000000); - nvkm_wr32(device, 0x405844, 0x00ffffff); - gr->func->init_419cc0(gr); - gr->func->init_419eb4(gr); - - gr->func->init_ppc_exceptions(gr); - - for (gpc = 0; gpc < gr->gpc_nr; gpc++) { - nvkm_wr32(device, GPC_UNIT(gpc, 0x0420), 0xc0000000); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0900), 0xc0000000); - nvkm_wr32(device, GPC_UNIT(gpc, 0x1028), 0xc0000000); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0824), 0xc0000000); - for (tpc = 0; tpc < gr->tpc_nr[gpc]; tpc++) { - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); - gr->func->init_tex_hww_esr(gr, gpc, tpc); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); - gr->func->init_shader_exceptions(gr, gpc, tpc); - } - nvkm_wr32(device, GPC_UNIT(gpc, 0x2c90), 0xffffffff); - nvkm_wr32(device, GPC_UNIT(gpc, 0x2c94), 0xffffffff); - } - - for (rop = 0; rop < gr->rop_nr; rop++) { - nvkm_wr32(device, ROP_UNIT(rop, 0x144), 0x40000000); - nvkm_wr32(device, ROP_UNIT(rop, 0x070), 0x40000000); - nvkm_wr32(device, ROP_UNIT(rop, 0x204), 0xffffffff); - nvkm_wr32(device, ROP_UNIT(rop, 0x208), 0xffffffff); - } - - nvkm_wr32(device, 0x400108, 0xffffffff); - nvkm_wr32(device, 0x400138, 0xffffffff); - nvkm_wr32(device, 0x400118, 0xffffffff); - nvkm_wr32(device, 0x400130, 0xffffffff); - nvkm_wr32(device, 0x40011c, 0xffffffff); - nvkm_wr32(device, 0x400134, 0xffffffff); - - gr->func->init_400054(gr); - - gf100_gr_zbc_init(gr); - - return gf100_gr_init_ctxctl(gr); -} - #include "fuc/hubgk104.fuc3.h" static struct gf100_gr_ucode @@ -524,7 +448,7 @@ gk104_gr_gpccs_ucode = { static const struct gf100_gr_func gk104_gr = { - .init = gk104_gr_init, + .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index 7bcea8181919b..9adb55f658c64 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -350,7 +350,7 @@ gk110_gr_init_419eb4(struct gf100_gr *gr) static const struct gf100_gr_func gk110_gr = { - .init = gk104_gr_init, + .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index 5af2a54e60bc0..f848f1578cd3e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c @@ -102,7 +102,7 @@ gk110b_gr_pack_mmio[] = { static const struct gf100_gr_func gk110b_gr = { - .init = gk104_gr_init, + .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c index dd08373a96b56..9c678f17b2fe0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c @@ -161,7 +161,7 @@ gk208_gr_gpccs_ucode = { static const struct gf100_gr_func gk208_gr = { - .init = gk104_gr_init, + .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index 4680d99b59ba1..c598fa5a68e03 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -369,81 +369,6 @@ gm107_gr_init_gpc_mmu(struct gf100_gr *gr) nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(fb->mmu_rd) >> 8); } -static int -gm107_gr_init(struct gf100_gr *gr) -{ - struct nvkm_device *device = gr->base.engine.subdev.device; - int gpc, tpc, rop; - - gr->func->init_gpc_mmu(gr); - - gf100_gr_mmio(gr, gr->func->mmio); - - gr->func->init_bios(gr); - - gr->func->init_vsc_stream_master(gr); - gr->func->init_zcull(gr); - gr->func->init_num_active_ltcs(gr); - - gr->func->init_rop_active_fbps(gr); - - nvkm_wr32(device, 0x400500, 0x00010001); - - nvkm_wr32(device, 0x400100, 0xffffffff); - nvkm_wr32(device, 0x40013c, 0xffffffff); - nvkm_wr32(device, 0x400124, 0x00000002); - gr->func->init_fecs_exceptions(gr); - - nvkm_wr32(device, 0x404000, 0xc0000000); - nvkm_wr32(device, 0x404600, 0xc0000000); - nvkm_wr32(device, 0x408030, 0xc0000000); - nvkm_wr32(device, 0x404490, 0xc0000000); - nvkm_wr32(device, 0x406018, 0xc0000000); - gr->func->init_sked_hww_esr(gr); - nvkm_wr32(device, 0x405840, 0xc0000000); - nvkm_wr32(device, 0x405844, 0x00ffffff); - gr->func->init_419cc0(gr); - - gr->func->init_ppc_exceptions(gr); - - for (gpc = 0; gpc < gr->gpc_nr; gpc++) { - nvkm_wr32(device, GPC_UNIT(gpc, 0x0420), 0xc0000000); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0900), 0xc0000000); - nvkm_wr32(device, GPC_UNIT(gpc, 0x1028), 0xc0000000); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0824), 0xc0000000); - for (tpc = 0; tpc < gr->tpc_nr[gpc]; tpc++) { - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); - gr->func->init_tex_hww_esr(gr, gpc, tpc); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); - gr->func->init_504430(gr, gpc, tpc); - gr->func->init_shader_exceptions(gr, gpc, tpc); - } - nvkm_wr32(device, GPC_UNIT(gpc, 0x2c90), 0xffffffff); - nvkm_wr32(device, GPC_UNIT(gpc, 0x2c94), 0xffffffff); - } - - for (rop = 0; rop < gr->rop_nr; rop++) { - nvkm_wr32(device, ROP_UNIT(rop, 0x144), 0x40000000); - nvkm_wr32(device, ROP_UNIT(rop, 0x070), 0x40000000); - nvkm_wr32(device, ROP_UNIT(rop, 0x204), 0xffffffff); - nvkm_wr32(device, ROP_UNIT(rop, 0x208), 0xffffffff); - } - - nvkm_wr32(device, 0x400108, 0xffffffff); - nvkm_wr32(device, 0x400138, 0xffffffff); - nvkm_wr32(device, 0x400118, 0xffffffff); - nvkm_wr32(device, 0x400130, 0xffffffff); - nvkm_wr32(device, 0x40011c, 0xffffffff); - nvkm_wr32(device, 0x400134, 0xffffffff); - - gr->func->init_400054(gr); - - gf100_gr_zbc_init(gr); - - return gf100_gr_init_ctxctl(gr); -} - #include "fuc/hubgm107.fuc5.h" static struct gf100_gr_ucode @@ -466,7 +391,7 @@ gm107_gr_gpccs_ucode = { static const struct gf100_gr_func gm107_gr = { - .init = gm107_gr_init, + .init = gf100_gr_init, .init_gpc_mmu = gm107_gr_init_gpc_mmu, .init_bios = gm107_gr_init_bios, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index bbe18873aee2f..4dcb56bfbca1f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -77,80 +77,6 @@ gm200_gr_init_rop_active_fbps(struct gf100_gr *gr) nvkm_mask(device, 0x408958, 0x0000000f, fbp_count); /* crop */ } -static int -gm200_gr_init(struct gf100_gr *gr) -{ - struct nvkm_device *device = gr->base.engine.subdev.device; - int gpc, tpc, rop; - - gr->func->init_gpc_mmu(gr); - - gf100_gr_mmio(gr, gr->fuc_sw_nonctx); - - gr->func->init_bios(gr); - - gr->func->init_vsc_stream_master(gr); - gr->func->init_zcull(gr); - gr->func->init_num_active_ltcs(gr); - - gr->func->init_rop_active_fbps(gr); - - nvkm_wr32(device, 0x400500, 0x00010001); - nvkm_wr32(device, 0x400100, 0xffffffff); - nvkm_wr32(device, 0x40013c, 0xffffffff); - nvkm_wr32(device, 0x400124, 0x00000002); - gr->func->init_fecs_exceptions(gr); - gr->func->init_ds_hww_esr_2(gr); - nvkm_wr32(device, 0x404000, 0xc0000000); - nvkm_wr32(device, 0x404600, 0xc0000000); - nvkm_wr32(device, 0x408030, 0xc0000000); - nvkm_wr32(device, 0x404490, 0xc0000000); - nvkm_wr32(device, 0x406018, 0xc0000000); - gr->func->init_sked_hww_esr(gr); - nvkm_wr32(device, 0x405840, 0xc0000000); - nvkm_wr32(device, 0x405844, 0x00ffffff); - gr->func->init_419cc0(gr); - - gr->func->init_ppc_exceptions(gr); - - for (gpc = 0; gpc < gr->gpc_nr; gpc++) { - nvkm_wr32(device, GPC_UNIT(gpc, 0x0420), 0xc0000000); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0900), 0xc0000000); - nvkm_wr32(device, GPC_UNIT(gpc, 0x1028), 0xc0000000); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0824), 0xc0000000); - for (tpc = 0; tpc < gr->tpc_nr[gpc]; tpc++) { - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); - gr->func->init_tex_hww_esr(gr, gpc, tpc); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); - gr->func->init_504430(gr, gpc, tpc); - gr->func->init_shader_exceptions(gr, gpc, tpc); - } - nvkm_wr32(device, GPC_UNIT(gpc, 0x2c90), 0xffffffff); - nvkm_wr32(device, GPC_UNIT(gpc, 0x2c94), 0xffffffff); - } - - for (rop = 0; rop < gr->rop_nr; rop++) { - nvkm_wr32(device, ROP_UNIT(rop, 0x144), 0x40000000); - nvkm_wr32(device, ROP_UNIT(rop, 0x070), 0x40000000); - nvkm_wr32(device, ROP_UNIT(rop, 0x204), 0xffffffff); - nvkm_wr32(device, ROP_UNIT(rop, 0x208), 0xffffffff); - } - - nvkm_wr32(device, 0x400108, 0xffffffff); - nvkm_wr32(device, 0x400138, 0xffffffff); - nvkm_wr32(device, 0x400118, 0xffffffff); - nvkm_wr32(device, 0x400130, 0xffffffff); - nvkm_wr32(device, 0x40011c, 0xffffffff); - nvkm_wr32(device, 0x400134, 0xffffffff); - - gr->func->init_400054(gr); - - gf100_gr_zbc_init(gr); - - return gf100_gr_init_ctxctl(gr); -} - int gm200_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device, int index, struct nvkm_gr **pgr) @@ -191,7 +117,7 @@ gm200_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device, static const struct gf100_gr_func gm200_gr = { - .init = gm200_gr_init, + .init = gf100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_bios = gm107_gr_init_bios, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c index 48a0e144d9838..cc507e8305115 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c @@ -62,84 +62,9 @@ gp100_gr_init_rop_active_fbps(struct gf100_gr *gr) nvkm_mask(device, 0x408958, 0x0000000f, fbp_count); /* crop */ } -int -gp100_gr_init(struct gf100_gr *gr) -{ - struct nvkm_device *device = gr->base.engine.subdev.device; - int gpc, tpc, rop; - - gr->func->init_gpc_mmu(gr); - - gf100_gr_mmio(gr, gr->fuc_sw_nonctx); - - gr->func->init_vsc_stream_master(gr); - gr->func->init_zcull(gr); - - gr->func->init_num_active_ltcs(gr); - - gr->func->init_rop_active_fbps(gr); - if (gr->func->init_swdx_pes_mask) - gr->func->init_swdx_pes_mask(gr); - - nvkm_wr32(device, 0x400500, 0x00010001); - nvkm_wr32(device, 0x400100, 0xffffffff); - nvkm_wr32(device, 0x40013c, 0xffffffff); - nvkm_wr32(device, 0x400124, 0x00000002); - gr->func->init_fecs_exceptions(gr); - gr->func->init_ds_hww_esr_2(gr); - nvkm_wr32(device, 0x404000, 0xc0000000); - nvkm_wr32(device, 0x404600, 0xc0000000); - nvkm_wr32(device, 0x408030, 0xc0000000); - nvkm_wr32(device, 0x404490, 0xc0000000); - nvkm_wr32(device, 0x406018, 0xc0000000); - gr->func->init_sked_hww_esr(gr); - nvkm_wr32(device, 0x405840, 0xc0000000); - nvkm_wr32(device, 0x405844, 0x00ffffff); - gr->func->init_419cc0(gr); - if (gr->func->init_419c9c) - gr->func->init_419c9c(gr); - - gr->func->init_ppc_exceptions(gr); - - for (gpc = 0; gpc < gr->gpc_nr; gpc++) { - nvkm_wr32(device, GPC_UNIT(gpc, 0x0420), 0xc0000000); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0900), 0xc0000000); - nvkm_wr32(device, GPC_UNIT(gpc, 0x1028), 0xc0000000); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0824), 0xc0000000); - for (tpc = 0; tpc < gr->tpc_nr[gpc]; tpc++) { - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); - gr->func->init_tex_hww_esr(gr, gpc, tpc); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); - gr->func->init_504430(gr, gpc, gpc); - gr->func->init_shader_exceptions(gr, gpc, tpc); - } - nvkm_wr32(device, GPC_UNIT(gpc, 0x2c90), 0xffffffff); - nvkm_wr32(device, GPC_UNIT(gpc, 0x2c94), 0xffffffff); - } - - for (rop = 0; rop < gr->rop_nr; rop++) { - nvkm_wr32(device, ROP_UNIT(rop, 0x144), 0x40000000); - nvkm_wr32(device, ROP_UNIT(rop, 0x070), 0x40000000); - nvkm_wr32(device, ROP_UNIT(rop, 0x204), 0xffffffff); - nvkm_wr32(device, ROP_UNIT(rop, 0x208), 0xffffffff); - } - - nvkm_wr32(device, 0x400108, 0xffffffff); - nvkm_wr32(device, 0x400138, 0xffffffff); - nvkm_wr32(device, 0x400118, 0xffffffff); - nvkm_wr32(device, 0x400130, 0xffffffff); - nvkm_wr32(device, 0x40011c, 0xffffffff); - nvkm_wr32(device, 0x400134, 0xffffffff); - - gf100_gr_zbc_init(gr); - - return gf100_gr_init_ctxctl(gr); -} - static const struct gf100_gr_func gp100_gr = { - .init = gp100_gr_init, + .init = gf100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c index 7ce06520fdc99..86d1ff777d674 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c @@ -42,7 +42,7 @@ gp102_gr_init_swdx_pes_mask(struct gf100_gr *gr) static const struct gf100_gr_func gp102_gr = { - .init = gp100_gr_init, + .init = gf100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c index dbb2d4e71442d..14007b5d2e41d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c @@ -28,7 +28,7 @@ static const struct gf100_gr_func gp107_gr = { - .init = gp100_gr_init, + .init = gf100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c index 7f23d8bd977fe..450a96d1cd072 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c @@ -27,7 +27,7 @@ static const struct gf100_gr_func gp10b_gr = { - .init = gp100_gr_init, + .init = gf100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, .init_zcull = gf117_gr_init_zcull, From aedc49fd0ebc2aaca2176aae27f170224b139b15 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 065/165] drm/nouveau/gr/gf100-: support firmware-provided sw_ctx everywhere Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index 881015080d838..e2c8077b70df9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1239,11 +1239,15 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) nvkm_mc_unk260(device, 0); - gf100_gr_mmio(gr, grctx->hub); - gf100_gr_mmio(gr, grctx->gpc); - gf100_gr_mmio(gr, grctx->zcull); - gf100_gr_mmio(gr, grctx->tpc); - gf100_gr_mmio(gr, grctx->ppc); + if (!gr->fuc_sw_ctx) { + gf100_gr_mmio(gr, grctx->hub); + gf100_gr_mmio(gr, grctx->gpc); + gf100_gr_mmio(gr, grctx->zcull); + gf100_gr_mmio(gr, grctx->tpc); + gf100_gr_mmio(gr, grctx->ppc); + } else { + gf100_gr_mmio(gr, gr->fuc_sw_ctx); + } idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000); From ea4a2bb530464f9bbd2728a3c3c58dd758fb36c4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 066/165] drm/nouveau/gr/gf100-: virtualise patch_ltc, noting missing init Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 3 +++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c | 12 ++++++++++++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c | 1 + 6 files changed, 20 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index e2c8077b70df9..450059996b95d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1254,6 +1254,8 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->bundle(info); grctx->pagepool(info); grctx->attrib(info); + if (grctx->patch_ltc) + grctx->patch_ltc(info); grctx->unkn(gr); gf100_grctx_generate_tpcid(gr); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index 5199e5aa0cb72..94612ca370439 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -48,6 +48,8 @@ struct gf100_grctx_func { u32 attrib_nr; u32 alpha_nr_max; u32 alpha_nr; + /* other patch buffer stuff */ + void (*patch_ltc)(struct gf100_grctx *); }; extern const struct gf100_grctx_func gf100_grctx; @@ -80,6 +82,7 @@ extern const struct gf100_grctx_func gk20a_grctx; void gk104_grctx_generate_main(struct gf100_gr *, struct gf100_grctx *); void gk104_grctx_generate_bundle(struct gf100_grctx *); void gk104_grctx_generate_pagepool(struct gf100_grctx *); +void gk104_grctx_generate_patch_ltc(struct gf100_grctx *); void gk104_grctx_generate_unkn(struct gf100_gr *); void gk104_grctx_generate_r418bb8(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c index 825c8fd500bc9..da019c4904ba0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c @@ -840,6 +840,17 @@ gk104_grctx_pack_ppc[] = { * PGRAPH context implementation ******************************************************************************/ +void +gk104_grctx_generate_patch_ltc(struct gf100_grctx *info) +{ + struct nvkm_device *device = info->gr->base.engine.subdev.device; + u32 data0 = nvkm_rd32(device, 0x17e91c); + u32 data1 = nvkm_rd32(device, 0x17e920); + /*XXX: Figure out how to modify this correctly! */ + mmio_wr32(info, 0x17e91c, data0); + mmio_wr32(info, 0x17e920, data1); +} + void gk104_grctx_generate_bundle(struct gf100_grctx *info) { @@ -1005,4 +1016,5 @@ gk104_grctx = { .attrib_nr = 0x218, .alpha_nr_max = 0x7ff, .alpha_nr = 0x648, + .patch_ltc = gk104_grctx_generate_patch_ltc, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c index 7b95ec2fe4536..3ad98cd8d5314 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c @@ -830,4 +830,5 @@ gk110_grctx = { .attrib_nr = 0x218, .alpha_nr_max = 0x7ff, .alpha_nr = 0x648, + .patch_ltc = gk104_grctx_generate_patch_ltc, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c index 048b1152da443..47a4a071a7123 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c @@ -91,4 +91,5 @@ gk110b_grctx = { .attrib_nr = 0x218, .alpha_nr_max = 0x7ff, .alpha_nr = 0x648, + .patch_ltc = gk104_grctx_generate_patch_ltc, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c index 67b7a1b43617e..ba04c86b54a25 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c @@ -552,4 +552,5 @@ gk208_grctx = { .attrib_nr = 0x218, .alpha_nr_max = 0x7ff, .alpha_nr = 0x648, + .patch_ltc = gk104_grctx_generate_patch_ltc, }; From fc740f545d912b32e26f12e240270e1dc36fa26e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 067/165] drm/nouveau/gr/gf100-: virtualise sm_id/tpc_nr Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 60 ++++++++++++------- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 9 ++- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c | 2 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c | 2 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c | 2 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c | 4 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c | 2 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c | 4 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c | 2 + .../drm/nouveau/nvkm/engine/gr/ctxgk110b.c | 2 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c | 2 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c | 4 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c | 26 +++----- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c | 21 +------ .../gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c | 3 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c | 3 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 1 + 20 files changed, 85 insertions(+), 67 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index 450059996b95d..14e6bf07535ab 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1079,28 +1079,6 @@ gf100_grctx_generate_unkn(struct gf100_gr *gr) { } -void -gf100_grctx_generate_tpcid(struct gf100_gr *gr) -{ - struct nvkm_device *device = gr->base.engine.subdev.device; - int gpc, tpc, id; - - for (tpc = 0, id = 0; tpc < 4; tpc++) { - for (gpc = 0; gpc < gr->gpc_nr; gpc++) { - if (tpc < gr->tpc_nr[gpc]) { - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x698), id); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x4e8), id); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0c10 + tpc * 4), id); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x088), id); - id++; - } - - nvkm_wr32(device, GPC_UNIT(gpc, 0x0c08), gr->tpc_nr[gpc]); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0c8c), gr->tpc_nr[gpc]); - } - } -} - void gf100_grctx_generate_r406028(struct gf100_gr *gr) { @@ -1230,6 +1208,40 @@ gf100_grctx_generate_r406800(struct gf100_gr *gr) } } +void +gf100_grctx_generate_tpc_nr(struct gf100_gr *gr, int gpc) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_wr32(device, GPC_UNIT(gpc, 0x0c08), gr->tpc_nr[gpc]); + nvkm_wr32(device, GPC_UNIT(gpc, 0x0c8c), gr->tpc_nr[gpc]); +} + +void +gf100_grctx_generate_sm_id(struct gf100_gr *gr, int gpc, int tpc, int sm) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x698), sm); + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x4e8), sm); + nvkm_wr32(device, GPC_UNIT(gpc, 0x0c10 + tpc * 4), sm); + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x088), sm); +} + +void +gf100_grctx_generate_floorsweep(struct gf100_gr *gr) +{ + const struct gf100_grctx_func *func = gr->func->grctx; + int tpc, gpc, sm; + + for (tpc = 0, sm = 0; tpc < gr->tpc_max; tpc++) { + for (gpc = 0; gpc < gr->gpc_nr; gpc++) { + if (tpc < gr->tpc_nr[gpc]) + func->sm_id(gr, gpc, tpc, sm++); + if (func->tpc_nr) + func->tpc_nr(gr, gpc); + } + } +} + void gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) { @@ -1258,7 +1270,7 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->patch_ltc(info); grctx->unkn(gr); - gf100_grctx_generate_tpcid(gr); + gf100_grctx_generate_floorsweep(gr); gf100_grctx_generate_r406028(gr); gf100_grctx_generate_r4060a8(gr); gf100_grctx_generate_r418bb8(gr); @@ -1410,4 +1422,6 @@ gf100_grctx = { .attrib = gf100_grctx_generate_attrib, .attrib_nr_max = 0x324, .attrib_nr = 0x218, + .sm_id = gf100_grctx_generate_sm_id, + .tpc_nr = gf100_grctx_generate_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index 94612ca370439..6fa9b629367b9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -50,6 +50,9 @@ struct gf100_grctx_func { u32 alpha_nr; /* other patch buffer stuff */ void (*patch_ltc)(struct gf100_grctx *); + /* floorsweeping */ + void (*sm_id)(struct gf100_gr *, int gpc, int tpc, int sm); + void (*tpc_nr)(struct gf100_gr *, int gpc); }; extern const struct gf100_grctx_func gf100_grctx; @@ -59,11 +62,13 @@ void gf100_grctx_generate_bundle(struct gf100_grctx *); void gf100_grctx_generate_pagepool(struct gf100_grctx *); void gf100_grctx_generate_attrib(struct gf100_grctx *); void gf100_grctx_generate_unkn(struct gf100_gr *); -void gf100_grctx_generate_tpcid(struct gf100_gr *); +void gf100_grctx_generate_floorsweep(struct gf100_gr *); void gf100_grctx_generate_r406028(struct gf100_gr *); void gf100_grctx_generate_r4060a8(struct gf100_gr *); void gf100_grctx_generate_r418bb8(struct gf100_gr *); void gf100_grctx_generate_r406800(struct gf100_gr *); +void gf100_grctx_generate_sm_id(struct gf100_gr *, int, int, int); +void gf100_grctx_generate_tpc_nr(struct gf100_gr *, int); extern const struct gf100_grctx_func gf108_grctx; void gf108_grctx_generate_attrib(struct gf100_grctx *); @@ -89,6 +94,7 @@ void gk104_grctx_generate_r418bb8(struct gf100_gr *); void gm107_grctx_generate_bundle(struct gf100_grctx *); void gm107_grctx_generate_pagepool(struct gf100_grctx *); void gm107_grctx_generate_attrib(struct gf100_grctx *); +void gm107_grctx_generate_sm_id(struct gf100_gr *, int, int, int); extern const struct gf100_grctx_func gk110_grctx; extern const struct gf100_grctx_func gk110b_grctx; @@ -100,7 +106,6 @@ void gm107_grctx_generate_pagepool(struct gf100_grctx *); void gm107_grctx_generate_attrib(struct gf100_grctx *); extern const struct gf100_grctx_func gm200_grctx; -void gm200_grctx_generate_tpcid(struct gf100_gr *); void gm200_grctx_generate_405b60(struct gf100_gr *); extern const struct gf100_grctx_func gm20b_grctx; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c index 54fd74e9cca0b..19cc84e7d7e65 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c @@ -96,4 +96,6 @@ gf104_grctx = { .attrib = gf100_grctx_generate_attrib, .attrib_nr_max = 0x324, .attrib_nr = 0x218, + .sm_id = gf100_grctx_generate_sm_id, + .tpc_nr = gf100_grctx_generate_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c index 82f71b10c06ec..370373111a397 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c @@ -794,4 +794,6 @@ gf108_grctx = { .attrib_nr = 0x218, .alpha_nr_max = 0x324, .alpha_nr = 0x218, + .sm_id = gf100_grctx_generate_sm_id, + .tpc_nr = gf100_grctx_generate_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c index 7df398b53f8f6..6d72ae0359174 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c @@ -347,4 +347,6 @@ gf110_grctx = { .attrib = gf100_grctx_generate_attrib, .attrib_nr_max = 0x324, .attrib_nr = 0x218, + .sm_id = gf100_grctx_generate_sm_id, + .tpc_nr = gf100_grctx_generate_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c index 19301d88577dc..806102a54a0c4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c @@ -240,7 +240,7 @@ gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->attrib(info); grctx->unkn(gr); - gf100_grctx_generate_tpcid(gr); + gf100_grctx_generate_floorsweep(gr); gf100_grctx_generate_r406028(gr); gf100_grctx_generate_r4060a8(gr); gk104_grctx_generate_r418bb8(gr); @@ -275,4 +275,6 @@ gf117_grctx = { .attrib_nr = 0x218, .alpha_nr_max = 0x7ff, .alpha_nr = 0x324, + .sm_id = gf100_grctx_generate_sm_id, + .tpc_nr = gf100_grctx_generate_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c index 605185b078be9..784ab94ba2671 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c @@ -517,4 +517,6 @@ gf119_grctx = { .attrib_nr = 0x218, .alpha_nr_max = 0x324, .alpha_nr = 0x218, + .sm_id = gf100_grctx_generate_sm_id, + .tpc_nr = gf100_grctx_generate_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c index da019c4904ba0..2be72fd58b1c5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c @@ -974,7 +974,7 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->attrib(info); grctx->unkn(gr); - gf100_grctx_generate_tpcid(gr); + gf100_grctx_generate_floorsweep(gr); gf100_grctx_generate_r406028(gr); gk104_grctx_generate_r418bb8(gr); gf100_grctx_generate_r406800(gr); @@ -1017,4 +1017,6 @@ gk104_grctx = { .alpha_nr_max = 0x7ff, .alpha_nr = 0x648, .patch_ltc = gk104_grctx_generate_patch_ltc, + .sm_id = gf100_grctx_generate_sm_id, + .tpc_nr = gf100_grctx_generate_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c index 3ad98cd8d5314..5013fc5c9399f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c @@ -831,4 +831,6 @@ gk110_grctx = { .alpha_nr_max = 0x7ff, .alpha_nr = 0x648, .patch_ltc = gk104_grctx_generate_patch_ltc, + .sm_id = gf100_grctx_generate_sm_id, + .tpc_nr = gf100_grctx_generate_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c index 47a4a071a7123..1dd574232c63a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c @@ -92,4 +92,6 @@ gk110b_grctx = { .alpha_nr_max = 0x7ff, .alpha_nr = 0x648, .patch_ltc = gk104_grctx_generate_patch_ltc, + .sm_id = gf100_grctx_generate_sm_id, + .tpc_nr = gf100_grctx_generate_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c index ba04c86b54a25..214f4dad98d61 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c @@ -553,4 +553,6 @@ gk208_grctx = { .alpha_nr_max = 0x7ff, .alpha_nr = 0x648, .patch_ltc = gk104_grctx_generate_patch_ltc, + .sm_id = gf100_grctx_generate_sm_id, + .tpc_nr = gf100_grctx_generate_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c index da7c35a6a3d20..faa5f18a1da5c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c @@ -42,7 +42,7 @@ gk20a_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); - gf100_grctx_generate_tpcid(gr); + gf100_grctx_generate_floorsweep(gr); gf100_grctx_generate_r406028(gr); gk104_grctx_generate_r418bb8(gr); gf100_grctx_generate_r406800(gr); @@ -82,4 +82,6 @@ gk20a_grctx = { .attrib_nr = 0x240, .alpha_nr_max = 0x648 + (0x648 / 2), .alpha_nr = 0x648, + .sm_id = gf100_grctx_generate_sm_id, + .tpc_nr = gf100_grctx_generate_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c index 9b43d4ce3eaa3..e5c0273e03740 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c @@ -930,25 +930,13 @@ gm107_grctx_generate_attrib(struct gf100_grctx *info) } } -static void -gm107_grctx_generate_tpcid(struct gf100_gr *gr) +void +gm107_grctx_generate_sm_id(struct gf100_gr *gr, int gpc, int tpc, int sm) { struct nvkm_device *device = gr->base.engine.subdev.device; - int gpc, tpc, id; - - for (tpc = 0, id = 0; tpc < 4; tpc++) { - for (gpc = 0; gpc < gr->gpc_nr; gpc++) { - if (tpc < gr->tpc_nr[gpc]) { - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x698), id); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0c10 + tpc * 4), id); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x088), id); - id++; - } - - nvkm_wr32(device, GPC_UNIT(gpc, 0x0c08), gr->tpc_nr[gpc]); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0c8c), gr->tpc_nr[gpc]); - } - } + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x698), sm); + nvkm_wr32(device, GPC_UNIT(gpc, 0x0c10 + tpc * 4), sm); + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x088), sm); } static void @@ -972,7 +960,7 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->attrib(info); grctx->unkn(gr); - gm107_grctx_generate_tpcid(gr); + gf100_grctx_generate_floorsweep(gr); gf100_grctx_generate_r406028(gr); gk104_grctx_generate_r418bb8(gr); gf100_grctx_generate_r406800(gr); @@ -1016,4 +1004,6 @@ gm107_grctx = { .attrib_nr = 0xaa0, .alpha_nr_max = 0x1800, .alpha_nr = 0x1000, + .sm_id = gm107_grctx_generate_sm_id, + .tpc_nr = gf100_grctx_generate_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c index db209d33f4864..be5e25ab43611 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c @@ -27,24 +27,6 @@ * PGRAPH context implementation ******************************************************************************/ -void -gm200_grctx_generate_tpcid(struct gf100_gr *gr) -{ - struct nvkm_device *device = gr->base.engine.subdev.device; - int gpc, tpc, id; - - for (tpc = 0, id = 0; tpc < TPC_MAX_PER_GPC; tpc++) { - for (gpc = 0; gpc < gr->gpc_nr; gpc++) { - if (tpc < gr->tpc_nr[gpc]) { - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x698), id); - nvkm_wr32(device, GPC_UNIT(gpc, 0x0c10 + tpc * 4), id); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x088), id); - id++; - } - } - } -} - void gm200_grctx_generate_405b60(struct gf100_gr *gr) { @@ -94,7 +76,7 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->attrib(info); grctx->unkn(gr); - gm200_grctx_generate_tpcid(gr); + gf100_grctx_generate_floorsweep(gr); gf100_grctx_generate_r406028(gr); gk104_grctx_generate_r418bb8(gr); @@ -133,4 +115,5 @@ gm200_grctx = { .attrib_nr = 0x400, .alpha_nr_max = 0x1800, .alpha_nr = 0x1000, + .sm_id = gm107_grctx_generate_sm_id, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c index e5702e3e0a5aa..363d198dda60c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c @@ -53,7 +53,7 @@ gm20b_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); - gm200_grctx_generate_tpcid(gr); + gf100_grctx_generate_floorsweep(gr); gm20b_grctx_generate_r406028(gr); gk104_grctx_generate_r418bb8(gr); @@ -98,4 +98,5 @@ gm20b_grctx = { .attrib_nr = 0x400, .alpha_nr_max = 0xc00, .alpha_nr = 0x800, + .sm_id = gm107_grctx_generate_sm_id, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c index 88ea322d956c4..ac8618f849a55 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c @@ -138,7 +138,7 @@ gp100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->attrib(info); grctx->unkn(gr); - gm200_grctx_generate_tpcid(gr); + gf100_grctx_generate_floorsweep(gr); gf100_grctx_generate_r406028(gr); gk104_grctx_generate_r418bb8(gr); @@ -174,4 +174,5 @@ gp100_grctx = { .attrib_nr = 0x440, .alpha_nr_max = 0xc00, .alpha_nr = 0x800, + .sm_id = gm107_grctx_generate_sm_id, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c index 7a66b4c2eb188..a267abc2976b2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c @@ -94,4 +94,5 @@ gp102_grctx = { .attrib_nr = 0x320, .alpha_nr_max = 0xc00, .alpha_nr = 0x800, + .sm_id = gm107_grctx_generate_sm_id, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c index 8da91a0b3bd2d..77345b202fbb5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c @@ -44,4 +44,5 @@ gp107_grctx = { .attrib_nr = 0x540, .alpha_nr_max = 0xc00, .alpha_nr = 0x800, + .sm_id = gm107_grctx_generate_sm_id, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index ac4c0d8478fa5..b9519fa5bbcaf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1675,6 +1675,7 @@ gf100_gr_oneinit(struct nvkm_gr *base) gr->gpc_nr = nvkm_rd32(device, 0x409604) & 0x0000001f; for (i = 0; i < gr->gpc_nr; i++) { gr->tpc_nr[i] = nvkm_rd32(device, GPC_UNIT(i, 0x2608)); + gr->tpc_max = max(gr->tpc_max, gr->tpc_nr[i]); gr->tpc_total += gr->tpc_nr[i]; gr->ppc_nr[i] = gr->func->ppc_nr; for (j = 0; j < gr->ppc_nr[i]; j++) { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 9ed51dc851dfe..ad352ee8143c9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -99,6 +99,7 @@ struct gf100_gr { u8 rop_nr; u8 gpc_nr; u8 tpc_nr[GPC_MAX]; + u8 tpc_max; u8 tpc_total; u8 ppc_nr[GPC_MAX]; u8 ppc_mask[GPC_MAX]; From e51f75d5012e88c90b3a05b6706475d83cb7a6eb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 068/165] drm/nouveau/gr/gf100-: virtualise tpc_per_gpc GM20B now also shares the same code, as NVGPU shows it doesn't need special treatment. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 25 ++++++++----------- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 1 - .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c | 1 - .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c | 1 - .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c | 1 - .../gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c | 1 - .../gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c | 1 - .../gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c | 15 ----------- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c | 1 - 9 files changed, 10 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index 14e6bf07535ab..a4865f7b9071f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1079,19 +1079,6 @@ gf100_grctx_generate_unkn(struct gf100_gr *gr) { } -void -gf100_grctx_generate_r406028(struct gf100_gr *gr) -{ - struct nvkm_device *device = gr->base.engine.subdev.device; - u32 tmp[GPC_MAX / 8] = {}, i = 0; - for (i = 0; i < gr->gpc_nr; i++) - tmp[i / 8] |= gr->tpc_nr[i] << ((i % 8) * 4); - for (i = 0; i < 4; i++) { - nvkm_wr32(device, 0x406028 + (i * 4), tmp[i]); - nvkm_wr32(device, 0x405870 + (i * 4), tmp[i]); - } -} - void gf100_grctx_generate_r4060a8(struct gf100_gr *gr) { @@ -1229,8 +1216,10 @@ gf100_grctx_generate_sm_id(struct gf100_gr *gr, int gpc, int tpc, int sm) void gf100_grctx_generate_floorsweep(struct gf100_gr *gr) { + struct nvkm_device *device = gr->base.engine.subdev.device; const struct gf100_grctx_func *func = gr->func->grctx; - int tpc, gpc, sm; + int tpc, gpc, sm, i, j; + u32 data; for (tpc = 0, sm = 0; tpc < gr->tpc_max; tpc++) { for (gpc = 0; gpc < gr->gpc_nr; gpc++) { @@ -1240,6 +1229,13 @@ gf100_grctx_generate_floorsweep(struct gf100_gr *gr) func->tpc_nr(gr, gpc); } } + + for (gpc = 0, i = 0; i < 4; i++) { + for (data = 0, j = 0; j < 8 && gpc < gr->gpc_nr; j++, gpc++) + data |= gr->tpc_nr[gpc] << (j * 4); + nvkm_wr32(device, 0x406028 + (i * 4), data); + nvkm_wr32(device, 0x405870 + (i * 4), data); + } } void @@ -1271,7 +1267,6 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gf100_grctx_generate_r406028(gr); gf100_grctx_generate_r4060a8(gr); gf100_grctx_generate_r418bb8(gr); gf100_grctx_generate_r406800(gr); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index 6fa9b629367b9..b9e287985e67a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -63,7 +63,6 @@ void gf100_grctx_generate_pagepool(struct gf100_grctx *); void gf100_grctx_generate_attrib(struct gf100_grctx *); void gf100_grctx_generate_unkn(struct gf100_gr *); void gf100_grctx_generate_floorsweep(struct gf100_gr *); -void gf100_grctx_generate_r406028(struct gf100_gr *); void gf100_grctx_generate_r4060a8(struct gf100_gr *); void gf100_grctx_generate_r418bb8(struct gf100_gr *); void gf100_grctx_generate_r406800(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c index 806102a54a0c4..a091485426b08 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c @@ -241,7 +241,6 @@ gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gf100_grctx_generate_r406028(gr); gf100_grctx_generate_r4060a8(gr); gk104_grctx_generate_r418bb8(gr); gf100_grctx_generate_r406800(gr); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c index 2be72fd58b1c5..cb6c15686adbe 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c @@ -975,7 +975,6 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gf100_grctx_generate_r406028(gr); gk104_grctx_generate_r418bb8(gr); gf100_grctx_generate_r406800(gr); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c index faa5f18a1da5c..dda3051167723 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c @@ -43,7 +43,6 @@ gk20a_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gf100_grctx_generate_r406028(gr); gk104_grctx_generate_r418bb8(gr); gf100_grctx_generate_r406800(gr); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c index e5c0273e03740..77cce9bffd799 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c @@ -961,7 +961,6 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gf100_grctx_generate_r406028(gr); gk104_grctx_generate_r418bb8(gr); gf100_grctx_generate_r406800(gr); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c index be5e25ab43611..ac6724b61e507 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c @@ -77,7 +77,6 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gf100_grctx_generate_r406028(gr); gk104_grctx_generate_r418bb8(gr); for (i = 0; i < 8; i++) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c index 363d198dda60c..6420d13915732 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c @@ -21,20 +21,6 @@ */ #include "ctxgf100.h" -static void -gm20b_grctx_generate_r406028(struct gf100_gr *gr) -{ - struct nvkm_device *device = gr->base.engine.subdev.device; - u32 tpc_per_gpc = 0; - int i; - - for (i = 0; i < gr->gpc_nr; i++) - tpc_per_gpc |= gr->tpc_nr[i] << (4 * i); - - nvkm_wr32(device, 0x406028, tpc_per_gpc); - nvkm_wr32(device, 0x405870, tpc_per_gpc); -} - static void gm20b_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) { @@ -54,7 +40,6 @@ gm20b_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gm20b_grctx_generate_r406028(gr); gk104_grctx_generate_r418bb8(gr); for (i = 0; i < 8; i++) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c index ac8618f849a55..701341d8b39ce 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c @@ -139,7 +139,6 @@ gp100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gf100_grctx_generate_r406028(gr); gk104_grctx_generate_r418bb8(gr); for (i = 0; i < 8; i++) From 9d8a80df73b58c700e36a0051b2fb44f252693e2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 069/165] drm/nouveau/gr/gf100-: virtualise r4060a8 + apply fixes from traces Also fixes some GPUs where we write too many registers. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 11 ++++++++--- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c | 1 + 7 files changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index a4865f7b9071f..aededb2b9ad3e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1083,7 +1083,9 @@ void gf100_grctx_generate_r4060a8(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; - u8 tpcnr[GPC_MAX], data[TPC_MAX]; + const u8 gpcmax = nvkm_rd32(device, 0x022430); + const u8 tpcmax = nvkm_rd32(device, 0x022434) * gpcmax; + u8 tpcnr[GPC_MAX], data[TPC_MAX]; int gpc, tpc, i; memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); @@ -1098,7 +1100,7 @@ gf100_grctx_generate_r4060a8(struct gf100_gr *gr) data[tpc] = gpc; } - for (i = 0; i < 4; i++) + for (i = 0; i < DIV_ROUND_UP(tpcmax, 4); i++) nvkm_wr32(device, 0x4060a8 + (i * 4), ((u32 *)data)[i]); } @@ -1236,6 +1238,9 @@ gf100_grctx_generate_floorsweep(struct gf100_gr *gr) nvkm_wr32(device, 0x406028 + (i * 4), data); nvkm_wr32(device, 0x405870 + (i * 4), data); } + + if (func->r4060a8) + func->r4060a8(gr); } void @@ -1267,7 +1272,6 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gf100_grctx_generate_r4060a8(gr); gf100_grctx_generate_r418bb8(gr); gf100_grctx_generate_r406800(gr); @@ -1419,4 +1423,5 @@ gf100_grctx = { .attrib_nr = 0x218, .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, + .r4060a8 = gf100_grctx_generate_r4060a8, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index b9e287985e67a..8430d8229a2b8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -53,6 +53,7 @@ struct gf100_grctx_func { /* floorsweeping */ void (*sm_id)(struct gf100_gr *, int gpc, int tpc, int sm); void (*tpc_nr)(struct gf100_gr *, int gpc); + void (*r4060a8)(struct gf100_gr *); }; extern const struct gf100_grctx_func gf100_grctx; @@ -63,11 +64,11 @@ void gf100_grctx_generate_pagepool(struct gf100_grctx *); void gf100_grctx_generate_attrib(struct gf100_grctx *); void gf100_grctx_generate_unkn(struct gf100_gr *); void gf100_grctx_generate_floorsweep(struct gf100_gr *); -void gf100_grctx_generate_r4060a8(struct gf100_gr *); void gf100_grctx_generate_r418bb8(struct gf100_gr *); void gf100_grctx_generate_r406800(struct gf100_gr *); void gf100_grctx_generate_sm_id(struct gf100_gr *, int, int, int); void gf100_grctx_generate_tpc_nr(struct gf100_gr *, int); +void gf100_grctx_generate_r4060a8(struct gf100_gr *); extern const struct gf100_grctx_func gf108_grctx; void gf108_grctx_generate_attrib(struct gf100_grctx *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c index 19cc84e7d7e65..471fa9e833247 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c @@ -98,4 +98,5 @@ gf104_grctx = { .attrib_nr = 0x218, .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, + .r4060a8 = gf100_grctx_generate_r4060a8, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c index 370373111a397..b472a3e8a589d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c @@ -796,4 +796,5 @@ gf108_grctx = { .alpha_nr = 0x218, .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, + .r4060a8 = gf100_grctx_generate_r4060a8, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c index 6d72ae0359174..12a98f67b5c52 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c @@ -349,4 +349,5 @@ gf110_grctx = { .attrib_nr = 0x218, .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, + .r4060a8 = gf100_grctx_generate_r4060a8, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c index a091485426b08..5c4d6d92a6846 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c @@ -241,7 +241,6 @@ gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gf100_grctx_generate_r4060a8(gr); gk104_grctx_generate_r418bb8(gr); gf100_grctx_generate_r406800(gr); @@ -276,4 +275,5 @@ gf117_grctx = { .alpha_nr = 0x324, .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, + .r4060a8 = gf100_grctx_generate_r4060a8, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c index 784ab94ba2671..cbf6c6a69403c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c @@ -519,4 +519,5 @@ gf119_grctx = { .alpha_nr = 0x218, .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, + .r4060a8 = gf100_grctx_generate_r4060a8, }; From ff209c235de9c3437e131b39eb976ff4bcc4c516 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 070/165] drm/nouveau/gr/gf100-: virtualise rop_mapping Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 6 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 5 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c | 61 ++++++++++++++++++- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c | 61 +------------------ .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c | 1 + .../drm/nouveau/nvkm/engine/gr/ctxgk110b.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c | 1 + 18 files changed, 82 insertions(+), 70 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index aededb2b9ad3e..d35711b24612d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1105,7 +1105,7 @@ gf100_grctx_generate_r4060a8(struct gf100_gr *gr) } void -gf100_grctx_generate_r418bb8(struct gf100_gr *gr) +gf100_grctx_generate_rop_mapping(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; u32 data[6] = {}, data2[2] = {}; @@ -1241,6 +1241,8 @@ gf100_grctx_generate_floorsweep(struct gf100_gr *gr) if (func->r4060a8) func->r4060a8(gr); + + func->rop_mapping(gr); } void @@ -1272,7 +1274,6 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gf100_grctx_generate_r418bb8(gr); gf100_grctx_generate_r406800(gr); gf100_gr_icmd(gr, grctx->icmd); @@ -1424,4 +1425,5 @@ gf100_grctx = { .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, .r4060a8 = gf100_grctx_generate_r4060a8, + .rop_mapping = gf100_grctx_generate_rop_mapping, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index 8430d8229a2b8..0c0d2a55fd118 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -54,6 +54,7 @@ struct gf100_grctx_func { void (*sm_id)(struct gf100_gr *, int gpc, int tpc, int sm); void (*tpc_nr)(struct gf100_gr *, int gpc); void (*r4060a8)(struct gf100_gr *); + void (*rop_mapping)(struct gf100_gr *); }; extern const struct gf100_grctx_func gf100_grctx; @@ -64,11 +65,11 @@ void gf100_grctx_generate_pagepool(struct gf100_grctx *); void gf100_grctx_generate_attrib(struct gf100_grctx *); void gf100_grctx_generate_unkn(struct gf100_gr *); void gf100_grctx_generate_floorsweep(struct gf100_gr *); -void gf100_grctx_generate_r418bb8(struct gf100_gr *); void gf100_grctx_generate_r406800(struct gf100_gr *); void gf100_grctx_generate_sm_id(struct gf100_gr *, int, int, int); void gf100_grctx_generate_tpc_nr(struct gf100_gr *, int); void gf100_grctx_generate_r4060a8(struct gf100_gr *); +void gf100_grctx_generate_rop_mapping(struct gf100_gr *); extern const struct gf100_grctx_func gf108_grctx; void gf108_grctx_generate_attrib(struct gf100_grctx *); @@ -79,6 +80,7 @@ extern const struct gf100_grctx_func gf110_grctx; extern const struct gf100_grctx_func gf117_grctx; void gf117_grctx_generate_attrib(struct gf100_grctx *); +void gf117_grctx_generate_rop_mapping(struct gf100_gr *); extern const struct gf100_grctx_func gf119_grctx; @@ -89,7 +91,6 @@ void gk104_grctx_generate_bundle(struct gf100_grctx *); void gk104_grctx_generate_pagepool(struct gf100_grctx *); void gk104_grctx_generate_patch_ltc(struct gf100_grctx *); void gk104_grctx_generate_unkn(struct gf100_gr *); -void gk104_grctx_generate_r418bb8(struct gf100_gr *); void gm107_grctx_generate_bundle(struct gf100_grctx *); void gm107_grctx_generate_pagepool(struct gf100_grctx *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c index 471fa9e833247..eb0d3778d3fed 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c @@ -99,4 +99,5 @@ gf104_grctx = { .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, .r4060a8 = gf100_grctx_generate_r4060a8, + .rop_mapping = gf100_grctx_generate_rop_mapping, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c index b472a3e8a589d..f218d98a16451 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c @@ -797,4 +797,5 @@ gf108_grctx = { .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, .r4060a8 = gf100_grctx_generate_r4060a8, + .rop_mapping = gf100_grctx_generate_rop_mapping, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c index 12a98f67b5c52..35c163851477f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c @@ -350,4 +350,5 @@ gf110_grctx = { .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, .r4060a8 = gf100_grctx_generate_r4060a8, + .rop_mapping = gf100_grctx_generate_rop_mapping, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c index 5c4d6d92a6846..7aaf8a26031fb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c @@ -179,6 +179,65 @@ gf117_grctx_pack_ppc[] = { * PGRAPH context implementation ******************************************************************************/ +void +gf117_grctx_generate_rop_mapping(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + u32 data[6] = {}, data2[2] = {}; + u8 tpcnr[GPC_MAX]; + u8 shift, ntpcv; + int gpc, tpc, i; + + /* calculate first set of magics */ + memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); + + gpc = -1; + for (tpc = 0; tpc < gr->tpc_total; tpc++) { + do { + gpc = (gpc + 1) % gr->gpc_nr; + } while (!tpcnr[gpc]); + tpcnr[gpc]--; + + data[tpc / 6] |= gpc << ((tpc % 6) * 5); + } + + for (; tpc < 32; tpc++) + data[tpc / 6] |= 7 << ((tpc % 6) * 5); + + /* and the second... */ + shift = 0; + ntpcv = gr->tpc_total; + while (!(ntpcv & (1 << 4))) { + ntpcv <<= 1; + shift++; + } + + data2[0] = (ntpcv << 16); + data2[0] |= (shift << 21); + data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24); + for (i = 1; i < 7; i++) + data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5); + + /* GPC_BROADCAST */ + nvkm_wr32(device, 0x418bb8, (gr->tpc_total << 8) | + gr->screen_tile_row_offset); + for (i = 0; i < 6; i++) + nvkm_wr32(device, 0x418b08 + (i * 4), data[i]); + + /* GPC_BROADCAST.TP_BROADCAST */ + nvkm_wr32(device, 0x41bfd0, (gr->tpc_total << 8) | + gr->screen_tile_row_offset | data2[0]); + nvkm_wr32(device, 0x41bfe4, data2[1]); + for (i = 0; i < 6; i++) + nvkm_wr32(device, 0x41bf00 + (i * 4), data[i]); + + /* UNK78xx */ + nvkm_wr32(device, 0x4078bc, (gr->tpc_total << 8) | + gr->screen_tile_row_offset); + for (i = 0; i < 6; i++) + nvkm_wr32(device, 0x40780c + (i * 4), data[i]); +} + void gf117_grctx_generate_attrib(struct gf100_grctx *info) { @@ -241,7 +300,6 @@ gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gk104_grctx_generate_r418bb8(gr); gf100_grctx_generate_r406800(gr); for (i = 0; i < 8; i++) @@ -276,4 +334,5 @@ gf117_grctx = { .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, .r4060a8 = gf100_grctx_generate_r4060a8, + .rop_mapping = gf117_grctx_generate_rop_mapping, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c index cbf6c6a69403c..4cd5d8615e011 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c @@ -520,4 +520,5 @@ gf119_grctx = { .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, .r4060a8 = gf100_grctx_generate_r4060a8, + .rop_mapping = gf100_grctx_generate_rop_mapping, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c index cb6c15686adbe..25a5209db5e83 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c @@ -892,65 +892,6 @@ gk104_grctx_generate_unkn(struct gf100_gr *gr) nvkm_mask(device, 0x419c00, 0x00000008, 0x00000008); } -void -gk104_grctx_generate_r418bb8(struct gf100_gr *gr) -{ - struct nvkm_device *device = gr->base.engine.subdev.device; - u32 data[6] = {}, data2[2] = {}; - u8 tpcnr[GPC_MAX]; - u8 shift, ntpcv; - int gpc, tpc, i; - - /* calculate first set of magics */ - memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); - - gpc = -1; - for (tpc = 0; tpc < gr->tpc_total; tpc++) { - do { - gpc = (gpc + 1) % gr->gpc_nr; - } while (!tpcnr[gpc]); - tpcnr[gpc]--; - - data[tpc / 6] |= gpc << ((tpc % 6) * 5); - } - - for (; tpc < 32; tpc++) - data[tpc / 6] |= 7 << ((tpc % 6) * 5); - - /* and the second... */ - shift = 0; - ntpcv = gr->tpc_total; - while (!(ntpcv & (1 << 4))) { - ntpcv <<= 1; - shift++; - } - - data2[0] = (ntpcv << 16); - data2[0] |= (shift << 21); - data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24); - for (i = 1; i < 7; i++) - data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5); - - /* GPC_BROADCAST */ - nvkm_wr32(device, 0x418bb8, (gr->tpc_total << 8) | - gr->screen_tile_row_offset); - for (i = 0; i < 6; i++) - nvkm_wr32(device, 0x418b08 + (i * 4), data[i]); - - /* GPC_BROADCAST.TP_BROADCAST */ - nvkm_wr32(device, 0x41bfd0, (gr->tpc_total << 8) | - gr->screen_tile_row_offset | data2[0]); - nvkm_wr32(device, 0x41bfe4, data2[1]); - for (i = 0; i < 6; i++) - nvkm_wr32(device, 0x41bf00 + (i * 4), data[i]); - - /* UNK78xx */ - nvkm_wr32(device, 0x4078bc, (gr->tpc_total << 8) | - gr->screen_tile_row_offset); - for (i = 0; i < 6; i++) - nvkm_wr32(device, 0x40780c + (i * 4), data[i]); -} - void gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) { @@ -975,7 +916,6 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gk104_grctx_generate_r418bb8(gr); gf100_grctx_generate_r406800(gr); for (i = 0; i < 8; i++) @@ -1018,4 +958,5 @@ gk104_grctx = { .patch_ltc = gk104_grctx_generate_patch_ltc, .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, + .rop_mapping = gf117_grctx_generate_rop_mapping, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c index 5013fc5c9399f..038cc47602c6f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c @@ -833,4 +833,5 @@ gk110_grctx = { .patch_ltc = gk104_grctx_generate_patch_ltc, .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, + .rop_mapping = gf117_grctx_generate_rop_mapping, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c index 1dd574232c63a..8b025e2c338fa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c @@ -94,4 +94,5 @@ gk110b_grctx = { .patch_ltc = gk104_grctx_generate_patch_ltc, .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, + .rop_mapping = gf117_grctx_generate_rop_mapping, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c index 214f4dad98d61..9479b40433434 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c @@ -555,4 +555,5 @@ gk208_grctx = { .patch_ltc = gk104_grctx_generate_patch_ltc, .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, + .rop_mapping = gf117_grctx_generate_rop_mapping, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c index dda3051167723..23abbfad1bdb2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c @@ -43,7 +43,6 @@ gk20a_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gk104_grctx_generate_r418bb8(gr); gf100_grctx_generate_r406800(gr); for (i = 0; i < 8; i++) @@ -83,4 +82,5 @@ gk20a_grctx = { .alpha_nr = 0x648, .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, + .rop_mapping = gf117_grctx_generate_rop_mapping, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c index 77cce9bffd799..fef6652f471ca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c @@ -961,7 +961,6 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gk104_grctx_generate_r418bb8(gr); gf100_grctx_generate_r406800(gr); nvkm_wr32(device, 0x4064d0, 0x00000001); @@ -1005,4 +1004,5 @@ gm107_grctx = { .alpha_nr = 0x1000, .sm_id = gm107_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, + .rop_mapping = gf117_grctx_generate_rop_mapping, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c index ac6724b61e507..cfccd75dbc301 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c @@ -77,7 +77,6 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gk104_grctx_generate_r418bb8(gr); for (i = 0; i < 8; i++) nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000); @@ -115,4 +114,5 @@ gm200_grctx = { .alpha_nr_max = 0x1800, .alpha_nr = 0x1000, .sm_id = gm107_grctx_generate_sm_id, + .rop_mapping = gf117_grctx_generate_rop_mapping, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c index 6420d13915732..3dd4e18d25250 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c @@ -40,7 +40,6 @@ gm20b_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gk104_grctx_generate_r418bb8(gr); for (i = 0; i < 8; i++) nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000); @@ -84,4 +83,5 @@ gm20b_grctx = { .alpha_nr_max = 0xc00, .alpha_nr = 0x800, .sm_id = gm107_grctx_generate_sm_id, + .rop_mapping = gf117_grctx_generate_rop_mapping, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c index 701341d8b39ce..e09990785cb93 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c @@ -139,7 +139,6 @@ gp100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gk104_grctx_generate_r418bb8(gr); for (i = 0; i < 8; i++) nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000); @@ -174,4 +173,5 @@ gp100_grctx = { .alpha_nr_max = 0xc00, .alpha_nr = 0x800, .sm_id = gm107_grctx_generate_sm_id, + .rop_mapping = gf117_grctx_generate_rop_mapping, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c index a267abc2976b2..553a609c4f98b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c @@ -95,4 +95,5 @@ gp102_grctx = { .alpha_nr_max = 0xc00, .alpha_nr = 0x800, .sm_id = gm107_grctx_generate_sm_id, + .rop_mapping = gf117_grctx_generate_rop_mapping, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c index 77345b202fbb5..db3fff89bc2f1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c @@ -45,4 +45,5 @@ gp107_grctx = { .alpha_nr_max = 0xc00, .alpha_nr = 0x800, .sm_id = gm107_grctx_generate_sm_id, + .rop_mapping = gf117_grctx_generate_rop_mapping, }; From 43952c6f43106c88b4dcdc99285d92172d8c57cd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 071/165] drm/nouveau/gr/gf100-: virtualise alpha_beta_tables + improve algorithms I haven't yet been able to find a fully programatic way of calculating the same mapping as NVIDIA for GF100-GF119, so the algorithm partially depends on data tables for specific configurations. I couldn't find traces for every possibility, so the algorithm will switch to a mapping similar to what GK104-GM10x use if it encounters one. We did the wrong thing before anyway, so shouldn't matter too much. The algorithm used in the GK104 implementation was ported from NVGPU. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 158 +++++++++++++++--- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 5 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c | 49 +++++- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c | 1 + .../drm/nouveau/nvkm/engine/gr/ctxgk110b.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 10 +- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 1 + 15 files changed, 201 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index d35711b24612d..7a22614a24f74 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1163,37 +1163,140 @@ gf100_grctx_generate_rop_mapping(struct gf100_gr *gr) nvkm_wr32(device, 0x40780c + (i * 4), data[i]); } +static const u32 +gf100_grctx_alpha_beta_map[17][32] = { + [1] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + }, + [2] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + }, + //XXX: 3 + [4] = { + 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, + }, + //XXX: 5 + //XXX: 6 + [7] = { + 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, + }, + [8] = { + 1, 1, 1, + 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, + 7, 7, 7, + }, + //XXX: 9 + //XXX: 10 + [11] = { + 1, 1, + 2, 2, 2, 2, + 3, 3, 3, + 4, 4, 4, 4, + 5, 5, 5, + 6, 6, 6, + 7, 7, 7, 7, + 8, 8, 8, + 9, 9, 9, 9, + 10, 10, + }, + //XXX: 12 + //XXX: 13 + [14] = { + 1, 1, + 2, 2, + 3, 3, 3, + 4, 4, 4, + 5, 5, + 6, 6, 6, + 7, 7, + 8, 8, 8, + 9, 9, + 10, 10, 10, + 11, 11, 11, + 12, 12, + 13, 13, + }, + [15] = { + 1, 1, + 2, 2, + 3, 3, + 4, 4, 4, + 5, 5, + 6, 6, 6, + 7, 7, + 8, 8, + 9, 9, 9, + 10, 10, + 11, 11, 11, + 12, 12, + 13, 13, + 14, 14, + }, + [16] = { + 1, 1, + 2, 2, + 3, 3, + 4, 4, + 5, 5, + 6, 6, 6, + 7, 7, + 8, 8, + 9, 9, + 10, 10, 10, + 11, 11, + 12, 12, + 13, 13, + 14, 14, + 15, 15, + }, +}; + void -gf100_grctx_generate_r406800(struct gf100_gr *gr) +gf100_grctx_generate_alpha_beta_tables(struct gf100_gr *gr) { - struct nvkm_device *device = gr->base.engine.subdev.device; - u64 tpc_mask = 0, tpc_set = 0; - u8 tpcnr[GPC_MAX]; - int gpc, tpc; - int i, a, b; + struct nvkm_subdev *subdev = &gr->base.engine.subdev; + struct nvkm_device *device = subdev->device; + int i, gpc; - memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); - for (gpc = 0; gpc < gr->gpc_nr; gpc++) - tpc_mask |= ((1ULL << gr->tpc_nr[gpc]) - 1) << (gpc * 8); - - for (i = 0, gpc = -1, b = -1; i < 32; i++) { - a = (i * (gr->tpc_total - 1)) / 32; - if (a != b) { - b = a; - do { - gpc = (gpc + 1) % gr->gpc_nr; - } while (!tpcnr[gpc]); - tpc = gr->tpc_nr[gpc] - tpcnr[gpc]--; - - tpc_set |= 1ULL << ((gpc * 8) + tpc); + for (i = 0; i < 32; i++) { + u32 atarget = gf100_grctx_alpha_beta_map[gr->tpc_total][i]; + u32 abits[GPC_MAX] = {}, amask = 0, bmask = 0; + + if (!atarget) { + nvkm_warn(subdev, "missing alpha/beta mapping table\n"); + atarget = max_t(u32, gr->tpc_total * i / 32, 1); } - nvkm_wr32(device, 0x406800 + (i * 0x20), lower_32_bits(tpc_set)); - nvkm_wr32(device, 0x406c00 + (i * 0x20), lower_32_bits(tpc_set ^ tpc_mask)); - if (gr->gpc_nr > 4) { - nvkm_wr32(device, 0x406804 + (i * 0x20), upper_32_bits(tpc_set)); - nvkm_wr32(device, 0x406c04 + (i * 0x20), upper_32_bits(tpc_set ^ tpc_mask)); + while (atarget) { + for (gpc = 0; atarget && gpc < gr->gpc_nr; gpc++) { + if (abits[gpc] < gr->tpc_nr[gpc]) { + abits[gpc]++; + atarget--; + } + } } + + for (gpc = 0; gpc < gr->gpc_nr; gpc++) { + u32 bbits = gr->tpc_nr[gpc] - abits[gpc]; + amask |= ((1 << abits[gpc]) - 1) << (gpc * 8); + bmask |= ((1 << bbits) - 1) << abits[gpc] << (gpc * 8); + } + + nvkm_wr32(device, 0x406800 + (i * 0x20), amask); + nvkm_wr32(device, 0x406c00 + (i * 0x20), bmask); } } @@ -1243,6 +1346,9 @@ gf100_grctx_generate_floorsweep(struct gf100_gr *gr) func->r4060a8(gr); func->rop_mapping(gr); + + if (func->alpha_beta_tables) + func->alpha_beta_tables(gr); } void @@ -1274,7 +1380,6 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gf100_grctx_generate_r406800(gr); gf100_gr_icmd(gr, grctx->icmd); nvkm_wr32(device, 0x404154, idle_timeout); @@ -1426,4 +1531,5 @@ gf100_grctx = { .tpc_nr = gf100_grctx_generate_tpc_nr, .r4060a8 = gf100_grctx_generate_r4060a8, .rop_mapping = gf100_grctx_generate_rop_mapping, + .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index 0c0d2a55fd118..a531076aa360d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -55,6 +55,7 @@ struct gf100_grctx_func { void (*tpc_nr)(struct gf100_gr *, int gpc); void (*r4060a8)(struct gf100_gr *); void (*rop_mapping)(struct gf100_gr *); + void (*alpha_beta_tables)(struct gf100_gr *); }; extern const struct gf100_grctx_func gf100_grctx; @@ -65,11 +66,11 @@ void gf100_grctx_generate_pagepool(struct gf100_grctx *); void gf100_grctx_generate_attrib(struct gf100_grctx *); void gf100_grctx_generate_unkn(struct gf100_gr *); void gf100_grctx_generate_floorsweep(struct gf100_gr *); -void gf100_grctx_generate_r406800(struct gf100_gr *); void gf100_grctx_generate_sm_id(struct gf100_gr *, int, int, int); void gf100_grctx_generate_tpc_nr(struct gf100_gr *, int); void gf100_grctx_generate_r4060a8(struct gf100_gr *); void gf100_grctx_generate_rop_mapping(struct gf100_gr *); +void gf100_grctx_generate_alpha_beta_tables(struct gf100_gr *); extern const struct gf100_grctx_func gf108_grctx; void gf108_grctx_generate_attrib(struct gf100_grctx *); @@ -85,6 +86,8 @@ void gf117_grctx_generate_rop_mapping(struct gf100_gr *); extern const struct gf100_grctx_func gf119_grctx; extern const struct gf100_grctx_func gk104_grctx; +void gk104_grctx_generate_alpha_beta_tables(struct gf100_gr *); + extern const struct gf100_grctx_func gk20a_grctx; void gk104_grctx_generate_main(struct gf100_gr *, struct gf100_grctx *); void gk104_grctx_generate_bundle(struct gf100_grctx *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c index eb0d3778d3fed..edeb36942b80d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c @@ -100,4 +100,5 @@ gf104_grctx = { .tpc_nr = gf100_grctx_generate_tpc_nr, .r4060a8 = gf100_grctx_generate_r4060a8, .rop_mapping = gf100_grctx_generate_rop_mapping, + .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c index f218d98a16451..267cfdf9b0012 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c @@ -798,4 +798,5 @@ gf108_grctx = { .tpc_nr = gf100_grctx_generate_tpc_nr, .r4060a8 = gf100_grctx_generate_r4060a8, .rop_mapping = gf100_grctx_generate_rop_mapping, + .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c index 35c163851477f..1fb934f899f41 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c @@ -351,4 +351,5 @@ gf110_grctx = { .tpc_nr = gf100_grctx_generate_tpc_nr, .r4060a8 = gf100_grctx_generate_r4060a8, .rop_mapping = gf100_grctx_generate_rop_mapping, + .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c index 7aaf8a26031fb..f159b550807f9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c @@ -300,7 +300,6 @@ gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gf100_grctx_generate_r406800(gr); for (i = 0; i < 8; i++) nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000); @@ -335,4 +334,5 @@ gf117_grctx = { .tpc_nr = gf100_grctx_generate_tpc_nr, .r4060a8 = gf100_grctx_generate_r4060a8, .rop_mapping = gf117_grctx_generate_rop_mapping, + .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c index 4cd5d8615e011..3720afde9e9f0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c @@ -521,4 +521,5 @@ gf119_grctx = { .tpc_nr = gf100_grctx_generate_tpc_nr, .r4060a8 = gf100_grctx_generate_r4060a8, .rop_mapping = gf100_grctx_generate_rop_mapping, + .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c index 25a5209db5e83..25576c1ea9cc1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c @@ -916,7 +916,6 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gf100_grctx_generate_r406800(gr); for (i = 0; i < 8; i++) nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000); @@ -933,6 +932,53 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) nvkm_mask(device, 0x41be10, 0x00800000, 0x00800000); } +void +gk104_grctx_generate_alpha_beta_tables(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + int i, j, gpc, ppc; + + for (i = 0; i < 32; i++) { + u32 atarget = max_t(u32, gr->tpc_total * i / 32, 1); + u32 btarget = gr->tpc_total - atarget; + bool alpha = atarget < btarget; + u64 amask = 0, bmask = 0; + + for (gpc = 0; gpc < gr->gpc_nr; gpc++) { + for (ppc = 0; ppc < gr->func->ppc_nr; ppc++) { + u32 ppc_tpcs = gr->ppc_tpc_nr[gpc][ppc]; + u32 abits, bbits, pmask; + + if (alpha) { + abits = atarget ? ppc_tpcs : 0; + bbits = ppc_tpcs - abits; + } else { + bbits = btarget ? ppc_tpcs : 0; + abits = ppc_tpcs - bbits; + } + + pmask = gr->ppc_tpc_mask[gpc][ppc]; + while (ppc_tpcs-- > abits) + pmask &= pmask - 1; + amask |= (u64)pmask << (gpc * 8); + + pmask ^= gr->ppc_tpc_mask[gpc][ppc]; + bmask |= (u64)pmask << (gpc * 8); + + atarget -= min(abits, atarget); + btarget -= min(bbits, btarget); + if ((abits > 0) || (bbits > 0)) + alpha = !alpha; + } + } + + for (j = 0; j < gr->gpc_nr; j += 4, amask >>= 32, bmask >>= 32) { + nvkm_wr32(device, 0x406800 + (i * 0x20) + j, amask); + nvkm_wr32(device, 0x406c00 + (i * 0x20) + j, bmask); + } + } +} + const struct gf100_grctx_func gk104_grctx = { .main = gk104_grctx_generate_main, @@ -959,4 +1005,5 @@ gk104_grctx = { .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, .rop_mapping = gf117_grctx_generate_rop_mapping, + .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c index 038cc47602c6f..284570a0b5cc1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c @@ -834,4 +834,5 @@ gk110_grctx = { .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, .rop_mapping = gf117_grctx_generate_rop_mapping, + .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c index 8b025e2c338fa..ffd8cf989309b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c @@ -95,4 +95,5 @@ gk110b_grctx = { .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, .rop_mapping = gf117_grctx_generate_rop_mapping, + .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c index 9479b40433434..e5e4d4dce86e9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c @@ -556,4 +556,5 @@ gk208_grctx = { .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, .rop_mapping = gf117_grctx_generate_rop_mapping, + .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c index 23abbfad1bdb2..896d473dcc0f5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c @@ -43,7 +43,6 @@ gk20a_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gf100_grctx_generate_r406800(gr); for (i = 0; i < 8; i++) nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000); @@ -83,4 +82,5 @@ gk20a_grctx = { .sm_id = gf100_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, .rop_mapping = gf117_grctx_generate_rop_mapping, + .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c index fef6652f471ca..c209bf38b5d99 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c @@ -961,7 +961,6 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->unkn(gr); gf100_grctx_generate_floorsweep(gr); - gf100_grctx_generate_r406800(gr); nvkm_wr32(device, 0x4064d0, 0x00000001); for (i = 1; i < 8; i++) @@ -1005,4 +1004,5 @@ gm107_grctx = { .sm_id = gm107_grctx_generate_sm_id, .tpc_nr = gf100_grctx_generate_tpc_nr, .rop_mapping = gf117_grctx_generate_rop_mapping, + .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index b9519fa5bbcaf..fe3b44d18a671 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1679,10 +1679,12 @@ gf100_gr_oneinit(struct nvkm_gr *base) gr->tpc_total += gr->tpc_nr[i]; gr->ppc_nr[i] = gr->func->ppc_nr; for (j = 0; j < gr->ppc_nr[i]; j++) { - u8 mask = nvkm_rd32(device, GPC_UNIT(i, 0x0c30 + (j * 4))); - if (mask) - gr->ppc_mask[i] |= (1 << j); - gr->ppc_tpc_nr[i][j] = hweight8(mask); + gr->ppc_tpc_mask[i][j] = + nvkm_rd32(device, GPC_UNIT(i, 0x0c30 + (j * 4))); + if (gr->ppc_tpc_mask[i][j] == 0) + continue; + gr->ppc_mask[i] |= (1 << j); + gr->ppc_tpc_nr[i][j] = hweight8(gr->ppc_tpc_mask[i][j]); } } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index ad352ee8143c9..6f7a7864d66f2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -103,6 +103,7 @@ struct gf100_gr { u8 tpc_total; u8 ppc_nr[GPC_MAX]; u8 ppc_mask[GPC_MAX]; + u8 ppc_tpc_mask[GPC_MAX][4]; u8 ppc_tpc_nr[GPC_MAX][4]; struct gf100_gr_data mmio_data[4]; From c4a2b6385dd4a32759acf8e7884acd1115054887 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 072/165] drm/nouveau/gr/gf100-gf119: modify max_ways_evict where required I don't think this is done after Fermi, NVGPU used to do it but removed the code, and I've not seen RM traces touching it either. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 12 ++++++++++++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c | 1 + 7 files changed, 19 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index 7a22614a24f74..cdf74f31d4be9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1163,6 +1163,15 @@ gf100_grctx_generate_rop_mapping(struct gf100_gr *gr) nvkm_wr32(device, 0x40780c + (i * 4), data[i]); } +void +gf100_grctx_generate_max_ways_evict(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + u32 fbps = nvkm_rd32(device, 0x121c74); + if (fbps == 1) + nvkm_mask(device, 0x17e91c, 0x001f0000, 0x00090000); +} + static const u32 gf100_grctx_alpha_beta_map[17][32] = { [1] = { @@ -1349,6 +1358,8 @@ gf100_grctx_generate_floorsweep(struct gf100_gr *gr) if (func->alpha_beta_tables) func->alpha_beta_tables(gr); + if (func->max_ways_evict) + func->max_ways_evict(gr); } void @@ -1532,4 +1543,5 @@ gf100_grctx = { .r4060a8 = gf100_grctx_generate_r4060a8, .rop_mapping = gf100_grctx_generate_rop_mapping, .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, + .max_ways_evict = gf100_grctx_generate_max_ways_evict, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index a531076aa360d..41cb875464de9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -56,6 +56,7 @@ struct gf100_grctx_func { void (*r4060a8)(struct gf100_gr *); void (*rop_mapping)(struct gf100_gr *); void (*alpha_beta_tables)(struct gf100_gr *); + void (*max_ways_evict)(struct gf100_gr *); }; extern const struct gf100_grctx_func gf100_grctx; @@ -71,6 +72,7 @@ void gf100_grctx_generate_tpc_nr(struct gf100_gr *, int); void gf100_grctx_generate_r4060a8(struct gf100_gr *); void gf100_grctx_generate_rop_mapping(struct gf100_gr *); void gf100_grctx_generate_alpha_beta_tables(struct gf100_gr *); +void gf100_grctx_generate_max_ways_evict(struct gf100_gr *); extern const struct gf100_grctx_func gf108_grctx; void gf108_grctx_generate_attrib(struct gf100_grctx *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c index edeb36942b80d..d246bb62ab020 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c @@ -101,4 +101,5 @@ gf104_grctx = { .r4060a8 = gf100_grctx_generate_r4060a8, .rop_mapping = gf100_grctx_generate_rop_mapping, .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, + .max_ways_evict = gf100_grctx_generate_max_ways_evict, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c index 267cfdf9b0012..3b6e645b46a78 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c @@ -799,4 +799,5 @@ gf108_grctx = { .r4060a8 = gf100_grctx_generate_r4060a8, .rop_mapping = gf100_grctx_generate_rop_mapping, .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, + .max_ways_evict = gf100_grctx_generate_max_ways_evict, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c index 1fb934f899f41..b65a1f329ebd5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c @@ -352,4 +352,5 @@ gf110_grctx = { .r4060a8 = gf100_grctx_generate_r4060a8, .rop_mapping = gf100_grctx_generate_rop_mapping, .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, + .max_ways_evict = gf100_grctx_generate_max_ways_evict, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c index f159b550807f9..423b09753bb7d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c @@ -335,4 +335,5 @@ gf117_grctx = { .r4060a8 = gf100_grctx_generate_r4060a8, .rop_mapping = gf117_grctx_generate_rop_mapping, .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, + .max_ways_evict = gf100_grctx_generate_max_ways_evict, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c index 3720afde9e9f0..6b2fcfe44df20 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c @@ -522,4 +522,5 @@ gf119_grctx = { .r4060a8 = gf100_grctx_generate_r4060a8, .rop_mapping = gf100_grctx_generate_rop_mapping, .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, + .max_ways_evict = gf100_grctx_generate_max_ways_evict, }; From 60770fa28bd7d69097d3a186fe8cfa1ec21c9c1d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 073/165] drm/nouveau/gr/gf100-: virtualise dist_skip_table + improve algorithm The algorithm for GM200 and newer matches RM for all the boards I have, but I don't have enough data to try and figure something out for earlier boards, so these will still write zeroes to the table as we did before. The code in NVGPU isn't helpful here, it appears to handle specific cases. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 2 ++ .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 3 +++ .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c | 15 ++++++++--- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c | 5 +--- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c | 1 + .../drm/nouveau/nvkm/engine/gr/ctxgk110b.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c | 5 +--- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c | 25 +++++++++++++++++-- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c | 3 +-- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 3 +++ .../gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 1 + 14 files changed, 51 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index cdf74f31d4be9..176be7124f290 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1360,6 +1360,8 @@ gf100_grctx_generate_floorsweep(struct gf100_gr *gr) func->alpha_beta_tables(gr); if (func->max_ways_evict) func->max_ways_evict(gr); + if (func->dist_skip_table) + func->dist_skip_table(gr); } void diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index 41cb875464de9..dd1c73b725cde 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -57,6 +57,7 @@ struct gf100_grctx_func { void (*rop_mapping)(struct gf100_gr *); void (*alpha_beta_tables)(struct gf100_gr *); void (*max_ways_evict)(struct gf100_gr *); + void (*dist_skip_table)(struct gf100_gr *); }; extern const struct gf100_grctx_func gf100_grctx; @@ -84,6 +85,7 @@ extern const struct gf100_grctx_func gf110_grctx; extern const struct gf100_grctx_func gf117_grctx; void gf117_grctx_generate_attrib(struct gf100_grctx *); void gf117_grctx_generate_rop_mapping(struct gf100_gr *); +void gf117_grctx_generate_dist_skip_table(struct gf100_gr *); extern const struct gf100_grctx_func gf119_grctx; @@ -112,6 +114,7 @@ void gm107_grctx_generate_pagepool(struct gf100_grctx *); void gm107_grctx_generate_attrib(struct gf100_grctx *); extern const struct gf100_grctx_func gm200_grctx; +void gm200_grctx_generate_dist_skip_table(struct gf100_gr *); void gm200_grctx_generate_405b60(struct gf100_gr *); extern const struct gf100_grctx_func gm20b_grctx; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c index 423b09753bb7d..b3f4127f7520f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c @@ -179,6 +179,16 @@ gf117_grctx_pack_ppc[] = { * PGRAPH context implementation ******************************************************************************/ +void +gf117_grctx_generate_dist_skip_table(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + int i; + + for (i = 0; i < 8; i++) + nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000); +} + void gf117_grctx_generate_rop_mapping(struct gf100_gr *gr) { @@ -282,7 +292,6 @@ gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) struct nvkm_device *device = gr->base.engine.subdev.device; const struct gf100_grctx_func *grctx = gr->func->grctx; u32 idle_timeout; - int i; nvkm_mc_unk260(device, 0); @@ -301,9 +310,6 @@ gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_floorsweep(gr); - for (i = 0; i < 8; i++) - nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000); - gf100_gr_icmd(gr, grctx->icmd); nvkm_wr32(device, 0x404154, idle_timeout); gf100_gr_mthd(gr, grctx->mthd); @@ -336,4 +342,5 @@ gf117_grctx = { .rop_mapping = gf117_grctx_generate_rop_mapping, .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, .max_ways_evict = gf100_grctx_generate_max_ways_evict, + .dist_skip_table = gf117_grctx_generate_dist_skip_table, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c index 25576c1ea9cc1..12169314f3e23 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c @@ -898,7 +898,6 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) struct nvkm_device *device = gr->base.engine.subdev.device; const struct gf100_grctx_func *grctx = gr->func->grctx; u32 idle_timeout; - int i; nvkm_mc_unk260(device, 0); @@ -917,9 +916,6 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_floorsweep(gr); - for (i = 0; i < 8; i++) - nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000); - nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); nvkm_mask(device, 0x419f78, 0x00000001, 0x00000000); @@ -1006,4 +1002,5 @@ gk104_grctx = { .tpc_nr = gf100_grctx_generate_tpc_nr, .rop_mapping = gf117_grctx_generate_rop_mapping, .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, + .dist_skip_table = gf117_grctx_generate_dist_skip_table, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c index 284570a0b5cc1..e6a54dc1a01a9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c @@ -835,4 +835,5 @@ gk110_grctx = { .tpc_nr = gf100_grctx_generate_tpc_nr, .rop_mapping = gf117_grctx_generate_rop_mapping, .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, + .dist_skip_table = gf117_grctx_generate_dist_skip_table, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c index ffd8cf989309b..ef82ebee82c9f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c @@ -96,4 +96,5 @@ gk110b_grctx = { .tpc_nr = gf100_grctx_generate_tpc_nr, .rop_mapping = gf117_grctx_generate_rop_mapping, .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, + .dist_skip_table = gf117_grctx_generate_dist_skip_table, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c index e5e4d4dce86e9..226f8aa9e7f68 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c @@ -557,4 +557,5 @@ gk208_grctx = { .tpc_nr = gf100_grctx_generate_tpc_nr, .rop_mapping = gf117_grctx_generate_rop_mapping, .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, + .dist_skip_table = gf117_grctx_generate_dist_skip_table, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c index c209bf38b5d99..cdf9d60683e01 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c @@ -945,7 +945,6 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) struct nvkm_device *device = gr->base.engine.subdev.device; const struct gf100_grctx_func *grctx = gr->func->grctx; u32 idle_timeout; - int i; gf100_gr_mmio(gr, grctx->hub); gf100_gr_mmio(gr, grctx->gpc); @@ -962,9 +961,6 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_floorsweep(gr); - nvkm_wr32(device, 0x4064d0, 0x00000001); - for (i = 1; i < 8; i++) - nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000); nvkm_wr32(device, 0x406500, 0x00000001); nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); @@ -1005,4 +1001,5 @@ gm107_grctx = { .tpc_nr = gf100_grctx_generate_tpc_nr, .rop_mapping = gf117_grctx_generate_rop_mapping, .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, + .dist_skip_table = gf117_grctx_generate_dist_skip_table, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c index cfccd75dbc301..689120683fb47 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c @@ -78,8 +78,6 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_floorsweep(gr); - for (i = 0; i < 8; i++) - nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000); nvkm_wr32(device, 0x406500, 0x00000000); nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); @@ -98,6 +96,28 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) nvkm_mask(device, 0x418e4c, 0xffffffff, 0x70000000); } +void +gm200_grctx_generate_dist_skip_table(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + u32 data[8] = {}; + int gpc, ppc, i; + + for (gpc = 0; gpc < gr->gpc_nr; gpc++) { + for (ppc = 0; ppc < gr->ppc_nr[gpc]; ppc++) { + u8 ppc_tpcs = gr->ppc_tpc_nr[gpc][ppc]; + u8 ppc_tpcm = gr->ppc_tpc_mask[gpc][ppc]; + while (ppc_tpcs-- > gr->ppc_tpc_min) + ppc_tpcm &= ppc_tpcm - 1; + ppc_tpcm ^= gr->ppc_tpc_mask[gpc][ppc]; + ((u8 *)data)[gpc] |= ppc_tpcm; + } + } + + for (i = 0; i < ARRAY_SIZE(data); i++) + nvkm_wr32(device, 0x4064d0 + (i * 0x04), data[i]); +} + const struct gf100_grctx_func gm200_grctx = { .main = gm200_grctx_generate_main, @@ -115,4 +135,5 @@ gm200_grctx = { .alpha_nr = 0x1000, .sm_id = gm107_grctx_generate_sm_id, .rop_mapping = gf117_grctx_generate_rop_mapping, + .dist_skip_table = gm200_grctx_generate_dist_skip_table, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c index e09990785cb93..1a3d0c566fea4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c @@ -140,8 +140,6 @@ gp100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_floorsweep(gr); - for (i = 0; i < 8; i++) - nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000); nvkm_wr32(device, 0x406500, 0x00000000); nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); @@ -174,4 +172,5 @@ gp100_grctx = { .alpha_nr = 0x800, .sm_id = gm107_grctx_generate_sm_id, .rop_mapping = gf117_grctx_generate_rop_mapping, + .dist_skip_table = gm200_grctx_generate_dist_skip_table, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c index 553a609c4f98b..2aeabb3624470 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c @@ -96,4 +96,5 @@ gp102_grctx = { .alpha_nr = 0x800, .sm_id = gm107_grctx_generate_sm_id, .rop_mapping = gf117_grctx_generate_rop_mapping, + .dist_skip_table = gm200_grctx_generate_dist_skip_table, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c index db3fff89bc2f1..4aea2f6552cc1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c @@ -46,4 +46,5 @@ gp107_grctx = { .alpha_nr = 0x800, .sm_id = gm107_grctx_generate_sm_id, .rop_mapping = gf117_grctx_generate_rop_mapping, + .dist_skip_table = gm200_grctx_generate_dist_skip_table, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index fe3b44d18a671..dd4a4104306c1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1685,6 +1685,9 @@ gf100_gr_oneinit(struct nvkm_gr *base) continue; gr->ppc_mask[i] |= (1 << j); gr->ppc_tpc_nr[i][j] = hweight8(gr->ppc_tpc_mask[i][j]); + if (gr->ppc_tpc_min == 0 || + gr->ppc_tpc_min > gr->ppc_tpc_nr[i][j]) + gr->ppc_tpc_min = gr->ppc_tpc_nr[i][j]; } } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 6f7a7864d66f2..c2a1b2adff360 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -105,6 +105,7 @@ struct gf100_gr { u8 ppc_mask[GPC_MAX]; u8 ppc_tpc_mask[GPC_MAX][4]; u8 ppc_tpc_nr[GPC_MAX][4]; + u8 ppc_tpc_min; struct gf100_gr_data mmio_data[4]; struct gf100_gr_mmio mmio_list[4096/8]; From e7163b192226206bc350a09a52603bd103a5ff6a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 074/165] drm/nouveau/gr/gf100-: virtualise r406500 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c | 9 +++++++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c | 9 +++++++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c | 3 +-- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c | 1 + 7 files changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index 176be7124f290..7bd28c1bb289a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1362,6 +1362,8 @@ gf100_grctx_generate_floorsweep(struct gf100_gr *gr) func->max_ways_evict(gr); if (func->dist_skip_table) func->dist_skip_table(gr); + if (func->r406500) + func->r406500(gr); } void diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index dd1c73b725cde..7d949a54f9581 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -58,6 +58,7 @@ struct gf100_grctx_func { void (*alpha_beta_tables)(struct gf100_gr *); void (*max_ways_evict)(struct gf100_gr *); void (*dist_skip_table)(struct gf100_gr *); + void (*r406500)(struct gf100_gr *); }; extern const struct gf100_grctx_func gf100_grctx; @@ -115,6 +116,7 @@ void gm107_grctx_generate_attrib(struct gf100_grctx *); extern const struct gf100_grctx_func gm200_grctx; void gm200_grctx_generate_dist_skip_table(struct gf100_gr *); +void gm200_grctx_generate_r406500(struct gf100_gr *); void gm200_grctx_generate_405b60(struct gf100_gr *); extern const struct gf100_grctx_func gm20b_grctx; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c index cdf9d60683e01..aa5fff3c0d748 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c @@ -930,6 +930,12 @@ gm107_grctx_generate_attrib(struct gf100_grctx *info) } } +static void +gm107_grctx_generate_r406500(struct gf100_gr *gr) +{ + nvkm_wr32(gr->base.engine.subdev.device, 0x406500, 0x00000001); +} + void gm107_grctx_generate_sm_id(struct gf100_gr *gr, int gpc, int tpc, int sm) { @@ -961,8 +967,6 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_floorsweep(gr); - nvkm_wr32(device, 0x406500, 0x00000001); - nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); gf100_gr_icmd(gr, grctx->icmd); @@ -1002,4 +1006,5 @@ gm107_grctx = { .rop_mapping = gf117_grctx_generate_rop_mapping, .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, .dist_skip_table = gf117_grctx_generate_dist_skip_table, + .r406500 = gm107_grctx_generate_r406500, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c index 689120683fb47..9c4db049f9c96 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c @@ -59,6 +59,12 @@ gm200_grctx_generate_405b60(struct gf100_gr *gr) nvkm_wr32(device, 0x405ba0 + (i * 4), gpcs[i]); } +void +gm200_grctx_generate_r406500(struct gf100_gr *gr) +{ + nvkm_wr32(gr->base.engine.subdev.device, 0x406500, 0x00000000); +} + static void gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) { @@ -78,8 +84,6 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_floorsweep(gr); - nvkm_wr32(device, 0x406500, 0x00000000); - nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); for (tmp = 0, i = 0; i < gr->gpc_nr; i++) @@ -136,4 +140,5 @@ gm200_grctx = { .sm_id = gm107_grctx_generate_sm_id, .rop_mapping = gf117_grctx_generate_rop_mapping, .dist_skip_table = gm200_grctx_generate_dist_skip_table, + .r406500 = gm200_grctx_generate_r406500, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c index 1a3d0c566fea4..3bad1a573ee3b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c @@ -140,8 +140,6 @@ gp100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_floorsweep(gr); - nvkm_wr32(device, 0x406500, 0x00000000); - nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); for (tmp = 0, i = 0; i < gr->gpc_nr; i++) @@ -173,4 +171,5 @@ gp100_grctx = { .sm_id = gm107_grctx_generate_sm_id, .rop_mapping = gf117_grctx_generate_rop_mapping, .dist_skip_table = gm200_grctx_generate_dist_skip_table, + .r406500 = gm200_grctx_generate_r406500, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c index 2aeabb3624470..dea009702cc40 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c @@ -97,4 +97,5 @@ gp102_grctx = { .sm_id = gm107_grctx_generate_sm_id, .rop_mapping = gf117_grctx_generate_rop_mapping, .dist_skip_table = gm200_grctx_generate_dist_skip_table, + .r406500 = gm200_grctx_generate_r406500, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c index 4aea2f6552cc1..a97c4b02acb47 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c @@ -47,4 +47,5 @@ gp107_grctx = { .sm_id = gm107_grctx_generate_sm_id, .rop_mapping = gf117_grctx_generate_rop_mapping, .dist_skip_table = gm200_grctx_generate_dist_skip_table, + .r406500 = gm200_grctx_generate_r406500, }; From 60c0264a667fe80ac48d746d073e9d869a5d52f0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 075/165] drm/nouveau/gr/gf100-: virtualise gpc_tpc_nr Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c | 9 ++++++++- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c | 3 +-- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c | 3 +-- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c | 3 +-- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c | 1 + 11 files changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index 7bd28c1bb289a..c1c83e5bf0a90 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1364,6 +1364,8 @@ gf100_grctx_generate_floorsweep(struct gf100_gr *gr) func->dist_skip_table(gr); if (func->r406500) func->r406500(gr); + if (func->gpc_tpc_nr) + func->gpc_tpc_nr(gr); } void diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index 7d949a54f9581..c91904d11b244 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -59,6 +59,7 @@ struct gf100_grctx_func { void (*max_ways_evict)(struct gf100_gr *); void (*dist_skip_table)(struct gf100_gr *); void (*r406500)(struct gf100_gr *); + void (*gpc_tpc_nr)(struct gf100_gr *); }; extern const struct gf100_grctx_func gf100_grctx; @@ -92,6 +93,7 @@ extern const struct gf100_grctx_func gf119_grctx; extern const struct gf100_grctx_func gk104_grctx; void gk104_grctx_generate_alpha_beta_tables(struct gf100_gr *); +void gk104_grctx_generate_gpc_tpc_nr(struct gf100_gr *); extern const struct gf100_grctx_func gk20a_grctx; void gk104_grctx_generate_main(struct gf100_gr *, struct gf100_grctx *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c index 12169314f3e23..302b8c7b68a88 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c @@ -892,6 +892,13 @@ gk104_grctx_generate_unkn(struct gf100_gr *gr) nvkm_mask(device, 0x419c00, 0x00000008, 0x00000008); } +void +gk104_grctx_generate_gpc_tpc_nr(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); +} + void gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) { @@ -916,7 +923,6 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_floorsweep(gr); - nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); nvkm_mask(device, 0x419f78, 0x00000001, 0x00000000); gf100_gr_icmd(gr, grctx->icmd); @@ -1003,4 +1009,5 @@ gk104_grctx = { .rop_mapping = gf117_grctx_generate_rop_mapping, .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, .dist_skip_table = gf117_grctx_generate_dist_skip_table, + .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c index e6a54dc1a01a9..64e00d7dffddb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c @@ -836,4 +836,5 @@ gk110_grctx = { .rop_mapping = gf117_grctx_generate_rop_mapping, .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, .dist_skip_table = gf117_grctx_generate_dist_skip_table, + .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c index ef82ebee82c9f..f800ed5562a1d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c @@ -97,4 +97,5 @@ gk110b_grctx = { .rop_mapping = gf117_grctx_generate_rop_mapping, .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, .dist_skip_table = gf117_grctx_generate_dist_skip_table, + .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c index 226f8aa9e7f68..494d9a9a200a9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c @@ -558,4 +558,5 @@ gk208_grctx = { .rop_mapping = gf117_grctx_generate_rop_mapping, .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, .dist_skip_table = gf117_grctx_generate_dist_skip_table, + .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c index aa5fff3c0d748..6b279bb494012 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c @@ -967,8 +967,6 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_floorsweep(gr); - nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); - gf100_gr_icmd(gr, grctx->icmd); nvkm_wr32(device, 0x404154, idle_timeout); gf100_gr_mthd(gr, grctx->mthd); @@ -1007,4 +1005,5 @@ gm107_grctx = { .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, .dist_skip_table = gf117_grctx_generate_dist_skip_table, .r406500 = gm107_grctx_generate_r406500, + .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c index 9c4db049f9c96..3ba5e95d8c15e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c @@ -84,8 +84,6 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_floorsweep(gr); - nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); - for (tmp = 0, i = 0; i < gr->gpc_nr; i++) tmp |= ((1 << gr->tpc_nr[i]) - 1) << (i * 4); nvkm_wr32(device, 0x4041c4, tmp); @@ -141,4 +139,5 @@ gm200_grctx = { .rop_mapping = gf117_grctx_generate_rop_mapping, .dist_skip_table = gm200_grctx_generate_dist_skip_table, .r406500 = gm200_grctx_generate_r406500, + .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c index 3bad1a573ee3b..c48617b74d8aa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c @@ -140,8 +140,6 @@ gp100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_floorsweep(gr); - nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); - for (tmp = 0, i = 0; i < gr->gpc_nr; i++) tmp |= ((1 << gr->tpc_nr[i]) - 1) << (i * 5); nvkm_wr32(device, 0x4041c4, tmp); @@ -172,4 +170,5 @@ gp100_grctx = { .rop_mapping = gf117_grctx_generate_rop_mapping, .dist_skip_table = gm200_grctx_generate_dist_skip_table, .r406500 = gm200_grctx_generate_r406500, + .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c index dea009702cc40..ec4fbe87facfa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c @@ -98,4 +98,5 @@ gp102_grctx = { .rop_mapping = gf117_grctx_generate_rop_mapping, .dist_skip_table = gm200_grctx_generate_dist_skip_table, .r406500 = gm200_grctx_generate_r406500, + .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c index a97c4b02acb47..84c98cd5cad9c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c @@ -48,4 +48,5 @@ gp107_grctx = { .rop_mapping = gf117_grctx_generate_rop_mapping, .dist_skip_table = gm200_grctx_generate_dist_skip_table, .r406500 = gm200_grctx_generate_r406500, + .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, }; From aa5e38dc9fdf0a11724561777d712bfdf0d6ad99 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 076/165] drm/nouveau/gr/gf100-: virtualise r419f78 + apply fixes from traces Removed from GK110[B]/GK208 as RM traces show it not being touched. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c | 10 ++++++++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index c1c83e5bf0a90..3793d481e851e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1366,6 +1366,8 @@ gf100_grctx_generate_floorsweep(struct gf100_gr *gr) func->r406500(gr); if (func->gpc_tpc_nr) func->gpc_tpc_nr(gr); + if (func->r419f78) + func->r419f78(gr); } void diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index c91904d11b244..e84b46f6210dc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -60,6 +60,7 @@ struct gf100_grctx_func { void (*dist_skip_table)(struct gf100_gr *); void (*r406500)(struct gf100_gr *); void (*gpc_tpc_nr)(struct gf100_gr *); + void (*r419f78)(struct gf100_gr *); }; extern const struct gf100_grctx_func gf100_grctx; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c index 302b8c7b68a88..f527bca30a02e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c @@ -892,6 +892,13 @@ gk104_grctx_generate_unkn(struct gf100_gr *gr) nvkm_mask(device, 0x419c00, 0x00000008, 0x00000008); } +static void +gk104_grctx_generate_r419f78(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_mask(device, 0x419f78, 0x00000001, 0x00000000); +} + void gk104_grctx_generate_gpc_tpc_nr(struct gf100_gr *gr) { @@ -923,8 +930,6 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_floorsweep(gr); - nvkm_mask(device, 0x419f78, 0x00000001, 0x00000000); - gf100_gr_icmd(gr, grctx->icmd); nvkm_wr32(device, 0x404154, idle_timeout); gf100_gr_mthd(gr, grctx->mthd); @@ -1010,4 +1015,5 @@ gk104_grctx = { .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, .dist_skip_table = gf117_grctx_generate_dist_skip_table, .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, + .r419f78 = gk104_grctx_generate_r419f78, }; From fc36076441bae141893bd79899d19aa1b5fdf524 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:46 +1000 Subject: [PATCH 077/165] drm/nouveau/gr/gf100-: virtualise tpc_mask + apply fixes from traces We weren't placing higher TPC IDs in the right place on some configurations. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 4 ++++ .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 12 +++++----- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c | 22 +++++++++++-------- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c | 22 +++++++------------ .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c | 2 ++ .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c | 2 ++ .../gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 2 ++ .../gpu/drm/nouveau/nvkm/engine/gr/gm200.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp100.c | 2 ++ .../gpu/drm/nouveau/nvkm/engine/gr/gp102.c | 2 ++ .../gpu/drm/nouveau/nvkm/engine/gr/gp107.c | 2 ++ .../gpu/drm/nouveau/nvkm/engine/gr/gp10b.c | 2 ++ 13 files changed, 47 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index 3793d481e851e..a52f27f1e5a6b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1368,6 +1368,10 @@ gf100_grctx_generate_floorsweep(struct gf100_gr *gr) func->gpc_tpc_nr(gr); if (func->r419f78) func->r419f78(gr); + if (func->tpc_mask) + func->tpc_mask(gr); + if (func->smid_config) + func->smid_config(gr); } void diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index e84b46f6210dc..d319e76fbfbdf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -61,6 +61,8 @@ struct gf100_grctx_func { void (*r406500)(struct gf100_gr *); void (*gpc_tpc_nr)(struct gf100_gr *); void (*r419f78)(struct gf100_gr *); + void (*tpc_mask)(struct gf100_gr *); + void (*smid_config)(struct gf100_gr *); }; extern const struct gf100_grctx_func gf100_grctx; @@ -103,11 +105,6 @@ void gk104_grctx_generate_pagepool(struct gf100_grctx *); void gk104_grctx_generate_patch_ltc(struct gf100_grctx *); void gk104_grctx_generate_unkn(struct gf100_gr *); -void gm107_grctx_generate_bundle(struct gf100_grctx *); -void gm107_grctx_generate_pagepool(struct gf100_grctx *); -void gm107_grctx_generate_attrib(struct gf100_grctx *); -void gm107_grctx_generate_sm_id(struct gf100_gr *, int, int, int); - extern const struct gf100_grctx_func gk110_grctx; extern const struct gf100_grctx_func gk110b_grctx; extern const struct gf100_grctx_func gk208_grctx; @@ -116,17 +113,20 @@ extern const struct gf100_grctx_func gm107_grctx; void gm107_grctx_generate_bundle(struct gf100_grctx *); void gm107_grctx_generate_pagepool(struct gf100_grctx *); void gm107_grctx_generate_attrib(struct gf100_grctx *); +void gm107_grctx_generate_sm_id(struct gf100_gr *, int, int, int); extern const struct gf100_grctx_func gm200_grctx; void gm200_grctx_generate_dist_skip_table(struct gf100_gr *); void gm200_grctx_generate_r406500(struct gf100_gr *); -void gm200_grctx_generate_405b60(struct gf100_gr *); +void gm200_grctx_generate_tpc_mask(struct gf100_gr *); +void gm200_grctx_generate_smid_config(struct gf100_gr *); extern const struct gf100_grctx_func gm20b_grctx; extern const struct gf100_grctx_func gp100_grctx; void gp100_grctx_generate_main(struct gf100_gr *, struct gf100_grctx *); void gp100_grctx_generate_pagepool(struct gf100_grctx *); +void gp100_grctx_generate_smid_config(struct gf100_gr *); extern const struct gf100_grctx_func gp102_grctx; void gp102_grctx_generate_attrib(struct gf100_grctx *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c index 3ba5e95d8c15e..f1e87b97480d9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c @@ -28,7 +28,7 @@ ******************************************************************************/ void -gm200_grctx_generate_405b60(struct gf100_gr *gr) +gm200_grctx_generate_smid_config(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; const u32 dist_nr = DIV_ROUND_UP(gr->tpc_total, 4); @@ -59,6 +59,15 @@ gm200_grctx_generate_405b60(struct gf100_gr *gr) nvkm_wr32(device, 0x405ba0 + (i * 4), gpcs[i]); } +void +gm200_grctx_generate_tpc_mask(struct gf100_gr *gr) +{ + u32 tmp, i; + for (tmp = 0, i = 0; i < gr->gpc_nr; i++) + tmp |= ((1 << gr->tpc_nr[i]) - 1) << (i * gr->func->tpc_nr); + nvkm_wr32(gr->base.engine.subdev.device, 0x4041c4, tmp); +} + void gm200_grctx_generate_r406500(struct gf100_gr *gr) { @@ -70,8 +79,7 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) { struct nvkm_device *device = gr->base.engine.subdev.device; const struct gf100_grctx_func *grctx = gr->func->grctx; - u32 idle_timeout, tmp; - int i; + u32 idle_timeout; gf100_gr_mmio(gr, gr->fuc_sw_ctx); @@ -84,12 +92,6 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_floorsweep(gr); - for (tmp = 0, i = 0; i < gr->gpc_nr; i++) - tmp |= ((1 << gr->tpc_nr[i]) - 1) << (i * 4); - nvkm_wr32(device, 0x4041c4, tmp); - - gm200_grctx_generate_405b60(gr); - gf100_gr_icmd(gr, gr->fuc_bundle); nvkm_wr32(device, 0x404154, idle_timeout); gf100_gr_mthd(gr, gr->fuc_method); @@ -140,4 +142,6 @@ gm200_grctx = { .dist_skip_table = gm200_grctx_generate_dist_skip_table, .r406500 = gm200_grctx_generate_r406500, .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, + .tpc_mask = gm200_grctx_generate_tpc_mask, + .smid_config = gm200_grctx_generate_smid_config, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c index 3dd4e18d25250..a1d9e114ebeb0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c @@ -52,7 +52,7 @@ gm20b_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) tmp |= ((1 << gr->tpc_nr[i]) - 1) << (i * 4); nvkm_wr32(device, 0x4041c4, tmp); - gm200_grctx_generate_405b60(gr); + gm200_grctx_generate_smid_config(gr); gf100_gr_wait_idle(gr); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c index c48617b74d8aa..821219a041971 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c @@ -89,13 +89,12 @@ gp100_grctx_generate_attrib(struct gf100_grctx *info) mmio_wr32(info, 0x41befc, 0x00000000); } -static void -gp100_grctx_generate_405b60(struct gf100_gr *gr) +void +gp100_grctx_generate_smid_config(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; const u32 dist_nr = DIV_ROUND_UP(gr->tpc_total, 4); - u32 dist[TPC_MAX / 4] = {}; - u32 gpcs[GPC_MAX * 2] = {}; + u32 dist[TPC_MAX / 4] = {}, gpcs[16] = {}; u8 tpcnr[GPC_MAX]; int tpc, gpc, i; @@ -112,12 +111,12 @@ gp100_grctx_generate_405b60(struct gf100_gr *gr) tpc = gr->tpc_nr[gpc] - tpcnr[gpc]--; dist[i / 4] |= ((gpc << 4) | tpc) << ((i % 4) * 8); - gpcs[gpc + (gr->gpc_nr * (tpc / 4))] |= i << (tpc * 8); + gpcs[gpc + (gr->func->gpc_nr * (tpc / 4))] |= i << (tpc * 8); } for (i = 0; i < dist_nr; i++) nvkm_wr32(device, 0x405b60 + (i * 4), dist[i]); - for (i = 0; i < gr->gpc_nr * 2; i++) + for (i = 0; i < ARRAY_SIZE(gpcs); i++) nvkm_wr32(device, 0x405ba0 + (i * 4), gpcs[i]); } @@ -126,8 +125,7 @@ gp100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) { struct nvkm_device *device = gr->base.engine.subdev.device; const struct gf100_grctx_func *grctx = gr->func->grctx; - u32 idle_timeout, tmp; - int i; + u32 idle_timeout; gf100_gr_mmio(gr, gr->fuc_sw_ctx); @@ -140,12 +138,6 @@ gp100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_floorsweep(gr); - for (tmp = 0, i = 0; i < gr->gpc_nr; i++) - tmp |= ((1 << gr->tpc_nr[i]) - 1) << (i * 5); - nvkm_wr32(device, 0x4041c4, tmp); - - gp100_grctx_generate_405b60(gr); - gf100_gr_icmd(gr, gr->fuc_bundle); nvkm_wr32(device, 0x404154, idle_timeout); gf100_gr_mthd(gr, gr->fuc_method); @@ -171,4 +163,6 @@ gp100_grctx = { .dist_skip_table = gm200_grctx_generate_dist_skip_table, .r406500 = gm200_grctx_generate_r406500, .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, + .tpc_mask = gm200_grctx_generate_tpc_mask, + .smid_config = gp100_grctx_generate_smid_config, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c index ec4fbe87facfa..611819ffb1f83 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c @@ -99,4 +99,6 @@ gp102_grctx = { .dist_skip_table = gm200_grctx_generate_dist_skip_table, .r406500 = gm200_grctx_generate_r406500, .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, + .tpc_mask = gm200_grctx_generate_tpc_mask, + .smid_config = gp100_grctx_generate_smid_config, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c index 84c98cd5cad9c..d908317079e03 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c @@ -49,4 +49,6 @@ gp107_grctx = { .dist_skip_table = gm200_grctx_generate_dist_skip_table, .r406500 = gm200_grctx_generate_r406500, .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, + .tpc_mask = gm200_grctx_generate_tpc_mask, + .smid_config = gp100_grctx_generate_smid_config, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index c2a1b2adff360..31109cec5a764 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -154,6 +154,8 @@ struct gf100_gr_func { struct gf100_gr_ucode *ucode; } gpccs; int (*rops)(struct gf100_gr *); + int gpc_nr; + int tpc_nr; int ppc_nr; const struct gf100_grctx_func *grctx; const struct nvkm_therm_clkgate_pack *clkgate_pack; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index 4dcb56bfbca1f..ae0eaf8e6d713 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -134,6 +134,7 @@ gm200_gr = { .init_shader_exceptions = gm107_gr_init_shader_exceptions, .init_400054 = gm107_gr_init_400054, .rops = gm200_gr_rops, + .tpc_nr = 4, .ppc_nr = 2, .grctx = &gm200_grctx, .sclass = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c index cc507e8305115..3addbc1d62c7e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c @@ -80,6 +80,8 @@ gp100_gr = { .init_504430 = gm107_gr_init_504430, .init_shader_exceptions = gp100_gr_init_shader_exceptions, .rops = gm200_gr_rops, + .gpc_nr = 6, + .tpc_nr = 5, .ppc_nr = 2, .grctx = &gp100_grctx, .sclass = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c index 86d1ff777d674..ea99c15487efc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c @@ -58,6 +58,8 @@ gp102_gr = { .init_504430 = gm107_gr_init_504430, .init_shader_exceptions = gp100_gr_init_shader_exceptions, .rops = gm200_gr_rops, + .gpc_nr = 6, + .tpc_nr = 5, .ppc_nr = 3, .grctx = &gp102_grctx, .sclass = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c index 14007b5d2e41d..09cba537b8b9d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c @@ -44,6 +44,8 @@ gp107_gr = { .init_504430 = gm107_gr_init_504430, .init_shader_exceptions = gp100_gr_init_shader_exceptions, .rops = gm200_gr_rops, + .gpc_nr = 2, + .tpc_nr = 3, .ppc_nr = 1, .grctx = &gp107_grctx, .sclass = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c index 450a96d1cd072..4972bf8d25309 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c @@ -42,6 +42,8 @@ gp10b_gr = { .init_504430 = gm107_gr_init_504430, .init_shader_exceptions = gp100_gr_init_shader_exceptions, .rops = gm200_gr_rops, + .gpc_nr = 1, + .tpc_nr = 2, .ppc_nr = 1, .grctx = &gp102_grctx, .sclass = { From 0e5a5e86f3edb0845f6caf8f9819eebb26ec040a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 078/165] drm/nouveau/gr/gf100-: support firmware-provided bundle/method everywhere Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index a52f27f1e5a6b..5350ab0a58f26 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1404,9 +1404,17 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_floorsweep(gr); - gf100_gr_icmd(gr, grctx->icmd); + if (gr->fuc_bundle) + gf100_gr_icmd(gr, gr->fuc_bundle); + else + gf100_gr_icmd(gr, grctx->icmd); + nvkm_wr32(device, 0x404154, idle_timeout); - gf100_gr_mthd(gr, grctx->mthd); + + if (gr->fuc_method) + gf100_gr_mthd(gr, gr->fuc_method); + else + gf100_gr_mthd(gr, grctx->mthd); nvkm_mc_unk260(device, 1); } From 99a3c67e84c955736a109e645371c7132c1188f2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 079/165] drm/nouveau/gr/gf100-gf119: update 419cb8 where required Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 11 +++++++++++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 3 +++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c | 1 + 7 files changed, 19 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index 5350ab0a58f26..e29ac88841ad4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1024,6 +1024,13 @@ gf100_grctx_mmio_item(struct gf100_grctx *info, u32 addr, u32 data, nvkm_wr32(device, addr, data); } +void +gf100_grctx_generate_r419cb8(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_mask(device, 0x419cb8, 0x00007c00, 0x00000000); +} + void gf100_grctx_generate_bundle(struct gf100_grctx *info) { @@ -1416,6 +1423,9 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) else gf100_gr_mthd(gr, grctx->mthd); nvkm_mc_unk260(device, 1); + + if (grctx->r419cb8) + grctx->r419cb8(gr); } #define CB_RESERVED 0x80000 @@ -1564,4 +1574,5 @@ gf100_grctx = { .rop_mapping = gf100_grctx_generate_rop_mapping, .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, .max_ways_evict = gf100_grctx_generate_max_ways_evict, + .r419cb8 = gf100_grctx_generate_r419cb8, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index d319e76fbfbdf..67628b9a742d1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -63,6 +63,8 @@ struct gf100_grctx_func { void (*r419f78)(struct gf100_gr *); void (*tpc_mask)(struct gf100_gr *); void (*smid_config)(struct gf100_gr *); + /* misc other things */ + void (*r419cb8)(struct gf100_gr *); }; extern const struct gf100_grctx_func gf100_grctx; @@ -79,6 +81,7 @@ void gf100_grctx_generate_r4060a8(struct gf100_gr *); void gf100_grctx_generate_rop_mapping(struct gf100_gr *); void gf100_grctx_generate_alpha_beta_tables(struct gf100_gr *); void gf100_grctx_generate_max_ways_evict(struct gf100_gr *); +void gf100_grctx_generate_r419cb8(struct gf100_gr *); extern const struct gf100_grctx_func gf108_grctx; void gf108_grctx_generate_attrib(struct gf100_grctx *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c index d246bb62ab020..7f3b9289a66bf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c @@ -102,4 +102,5 @@ gf104_grctx = { .rop_mapping = gf100_grctx_generate_rop_mapping, .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, .max_ways_evict = gf100_grctx_generate_max_ways_evict, + .r419cb8 = gf100_grctx_generate_r419cb8, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c index 3b6e645b46a78..369d64f867c7a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c @@ -800,4 +800,5 @@ gf108_grctx = { .rop_mapping = gf100_grctx_generate_rop_mapping, .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, .max_ways_evict = gf100_grctx_generate_max_ways_evict, + .r419cb8 = gf100_grctx_generate_r419cb8, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c index b65a1f329ebd5..d59c2480f04d3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c @@ -353,4 +353,5 @@ gf110_grctx = { .rop_mapping = gf100_grctx_generate_rop_mapping, .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, .max_ways_evict = gf100_grctx_generate_max_ways_evict, + .r419cb8 = gf100_grctx_generate_r419cb8, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c index b3f4127f7520f..e922e3e983cfc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c @@ -343,4 +343,5 @@ gf117_grctx = { .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, .max_ways_evict = gf100_grctx_generate_max_ways_evict, .dist_skip_table = gf117_grctx_generate_dist_skip_table, + .r419cb8 = gf100_grctx_generate_r419cb8, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c index 6b2fcfe44df20..cc1a9354fecc6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c @@ -523,4 +523,5 @@ gf119_grctx = { .rop_mapping = gf100_grctx_generate_rop_mapping, .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, .max_ways_evict = gf100_grctx_generate_max_ways_evict, + .r419cb8 = gf100_grctx_generate_r419cb8, }; From 5b54b5b92543cac6b9f3728935869fafdb3bf0d9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 080/165] drm/nouveau/gr/gf100-: note missing 418800 modifications Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 2 ++ .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 2 ++ .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c | 19 +++++++++++++++++-- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c | 1 + .../drm/nouveau/nvkm/engine/gr/ctxgk110b.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c | 1 + 6 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index e29ac88841ad4..0dcb227c59f1a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1426,6 +1426,8 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) if (grctx->r419cb8) grctx->r419cb8(gr); + if (grctx->r418800) + grctx->r418800(gr); } #define CB_RESERVED 0x80000 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index 67628b9a742d1..0d05664f9ee6c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -65,6 +65,7 @@ struct gf100_grctx_func { void (*smid_config)(struct gf100_gr *); /* misc other things */ void (*r419cb8)(struct gf100_gr *); + void (*r418800)(struct gf100_gr *); }; extern const struct gf100_grctx_func gf100_grctx; @@ -107,6 +108,7 @@ void gk104_grctx_generate_bundle(struct gf100_grctx *); void gk104_grctx_generate_pagepool(struct gf100_grctx *); void gk104_grctx_generate_patch_ltc(struct gf100_grctx *); void gk104_grctx_generate_unkn(struct gf100_gr *); +void gk104_grctx_generate_r418800(struct gf100_gr *); extern const struct gf100_grctx_func gk110_grctx; extern const struct gf100_grctx_func gk110b_grctx; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c index f527bca30a02e..a4fe36c136fdc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c @@ -840,6 +840,21 @@ gk104_grctx_pack_ppc[] = { * PGRAPH context implementation ******************************************************************************/ +void +gk104_grctx_generate_r418800(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + /*XXX: Not real sure where to apply these, there doesn't seem + * to be any pattern to which chipsets it's done on. + * + * Perhaps a VBIOS tweak? + */ + if (0) { + nvkm_mask(device, 0x418800, 0x00200000, 0x00200000); + nvkm_mask(device, 0x41be10, 0x00800000, 0x00800000); + } +} + void gk104_grctx_generate_patch_ltc(struct gf100_grctx *info) { @@ -935,8 +950,7 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_gr_mthd(gr, grctx->mthd); nvkm_mc_unk260(device, 1); - nvkm_mask(device, 0x418800, 0x00200000, 0x00200000); - nvkm_mask(device, 0x41be10, 0x00800000, 0x00800000); + grctx->r418800(gr); } void @@ -1016,4 +1030,5 @@ gk104_grctx = { .dist_skip_table = gf117_grctx_generate_dist_skip_table, .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, .r419f78 = gk104_grctx_generate_r419f78, + .r418800 = gk104_grctx_generate_r418800, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c index 64e00d7dffddb..7102a24a934eb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c @@ -837,4 +837,5 @@ gk110_grctx = { .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, .dist_skip_table = gf117_grctx_generate_dist_skip_table, .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, + .r418800 = gk104_grctx_generate_r418800, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c index f800ed5562a1d..049de07d7bc56 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c @@ -98,4 +98,5 @@ gk110b_grctx = { .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, .dist_skip_table = gf117_grctx_generate_dist_skip_table, .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, + .r418800 = gk104_grctx_generate_r418800, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c index 494d9a9a200a9..c69494f7418ef 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c @@ -559,4 +559,5 @@ gk208_grctx = { .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, .dist_skip_table = gf117_grctx_generate_dist_skip_table, .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, + .r418800 = gk104_grctx_generate_r418800, }; From ad45a92b9a104285dd3c95b6a8a4d5e0b50b6929 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 081/165] drm/nouveau/gr/gf100-: update 419eb0 where required Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 3 +++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c | 8 ++++++++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c | 1 + 4 files changed, 14 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index 0dcb227c59f1a..e8be2fbb6c753 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1428,6 +1428,8 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->r419cb8(gr); if (grctx->r418800) grctx->r418800(gr); + if (grctx->r419eb0) + grctx->r419eb0(gr); } #define CB_RESERVED 0x80000 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index 0d05664f9ee6c..4a6d47010cab8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -66,6 +66,7 @@ struct gf100_grctx_func { /* misc other things */ void (*r419cb8)(struct gf100_gr *); void (*r418800)(struct gf100_gr *); + void (*r419eb0)(struct gf100_gr *); }; extern const struct gf100_grctx_func gf100_grctx; @@ -111,6 +112,8 @@ void gk104_grctx_generate_unkn(struct gf100_gr *); void gk104_grctx_generate_r418800(struct gf100_gr *); extern const struct gf100_grctx_func gk110_grctx; +void gk110_grctx_generate_r419eb0(struct gf100_gr *); + extern const struct gf100_grctx_func gk110b_grctx; extern const struct gf100_grctx_func gk208_grctx; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c index 7102a24a934eb..f00e7afef9c44 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c @@ -808,6 +808,13 @@ gk110_grctx_pack_ppc[] = { * PGRAPH context implementation ******************************************************************************/ +void +gk110_grctx_generate_r419eb0(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_mask(device, 0x419eb0, 0x00001000, 0x00001000); +} + const struct gf100_grctx_func gk110_grctx = { .main = gk104_grctx_generate_main, @@ -838,4 +845,5 @@ gk110_grctx = { .dist_skip_table = gf117_grctx_generate_dist_skip_table, .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, .r418800 = gk104_grctx_generate_r418800, + .r419eb0 = gk110_grctx_generate_r419eb0, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c index 049de07d7bc56..ed09cfdfb024b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c @@ -99,4 +99,5 @@ gk110b_grctx = { .dist_skip_table = gf117_grctx_generate_dist_skip_table, .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, .r418800 = gk104_grctx_generate_r418800, + .r419eb0 = gk110_grctx_generate_r419eb0, }; From 18d17221dd58741a8590ba0a40a9ded82aa5d619 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 082/165] drm/nouveau/gr/gf100-: virtualise r419e00 Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 2 ++ .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c | 16 ++++++++++++---- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index e8be2fbb6c753..d2b78ed6556aa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1430,6 +1430,8 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->r418800(gr); if (grctx->r419eb0) grctx->r419eb0(gr); + if (grctx->r419e00) + grctx->r419e00(gr); } #define CB_RESERVED 0x80000 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index 4a6d47010cab8..474b5ddba4ed9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -67,6 +67,7 @@ struct gf100_grctx_func { void (*r419cb8)(struct gf100_gr *); void (*r418800)(struct gf100_gr *); void (*r419eb0)(struct gf100_gr *); + void (*r419e00)(struct gf100_gr *); }; extern const struct gf100_grctx_func gf100_grctx; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c index 6b279bb494012..12a9431dc8b42 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c @@ -860,6 +860,16 @@ gm107_grctx_pack_ppc[] = { * PGRAPH context implementation ******************************************************************************/ +static void +gm107_grctx_generate_r419e00(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_mask(device, 0x419e00, 0x00808080, 0x00808080); + nvkm_mask(device, 0x419ccc, 0x80000000, 0x80000000); + nvkm_mask(device, 0x419f80, 0x80000000, 0x80000000); + nvkm_mask(device, 0x419f88, 0x80000000, 0x80000000); +} + void gm107_grctx_generate_bundle(struct gf100_grctx *info) { @@ -971,10 +981,7 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) nvkm_wr32(device, 0x404154, idle_timeout); gf100_gr_mthd(gr, grctx->mthd); - nvkm_mask(device, 0x419e00, 0x00808080, 0x00808080); - nvkm_mask(device, 0x419ccc, 0x80000000, 0x80000000); - nvkm_mask(device, 0x419f80, 0x80000000, 0x80000000); - nvkm_mask(device, 0x419f88, 0x80000000, 0x80000000); + grctx->r419e00(gr); } const struct gf100_grctx_func @@ -1006,4 +1013,5 @@ gm107_grctx = { .dist_skip_table = gf117_grctx_generate_dist_skip_table, .r406500 = gm107_grctx_generate_r406500, .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, + .r419e00 = gm107_grctx_generate_r419e00, }; From c2592adea7a81857bf27f5b820640e67a0c6b664 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 083/165] drm/nouveau/gr/gf100-: virtualise r418e94 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c | 12 ++++++++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index d2b78ed6556aa..24792be61f9b9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1432,6 +1432,8 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->r419eb0(gr); if (grctx->r419e00) grctx->r419e00(gr); + if (grctx->r418e94) + grctx->r418e94(gr); } #define CB_RESERVED 0x80000 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index 474b5ddba4ed9..ac7f4f52b707b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -68,6 +68,7 @@ struct gf100_grctx_func { void (*r418800)(struct gf100_gr *); void (*r419eb0)(struct gf100_gr *); void (*r419e00)(struct gf100_gr *); + void (*r418e94)(struct gf100_gr *); }; extern const struct gf100_grctx_func gf100_grctx; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c index f1e87b97480d9..13951aa41ba42 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c @@ -27,6 +27,14 @@ * PGRAPH context implementation ******************************************************************************/ +static void +gm200_grctx_generate_r418e94(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_mask(device, 0x418e94, 0xffffffff, 0xc4230000); + nvkm_mask(device, 0x418e4c, 0xffffffff, 0x70000000); +} + void gm200_grctx_generate_smid_config(struct gf100_gr *gr) { @@ -96,8 +104,7 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) nvkm_wr32(device, 0x404154, idle_timeout); gf100_gr_mthd(gr, gr->fuc_method); - nvkm_mask(device, 0x418e94, 0xffffffff, 0xc4230000); - nvkm_mask(device, 0x418e4c, 0xffffffff, 0x70000000); + grctx->r418e94(gr); } void @@ -144,4 +151,5 @@ gm200_grctx = { .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, .tpc_mask = gm200_grctx_generate_tpc_mask, .smid_config = gm200_grctx_generate_smid_config, + .r418e94 = gm200_grctx_generate_r418e94, }; From 8d56fc48d3563cb3767c1d3dd243974168067f99 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 084/165] drm/nouveau/gr/gf100-: update 419a3c where required Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c | 8 ++++++++ drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c | 1 + 6 files changed, 15 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index 24792be61f9b9..1d1d0ccd1ddc6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1434,6 +1434,8 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->r419e00(gr); if (grctx->r418e94) grctx->r418e94(gr); + if (grctx->r419a3c) + grctx->r419a3c(gr); } #define CB_RESERVED 0x80000 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index ac7f4f52b707b..bff24e66d39ee 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -69,6 +69,7 @@ struct gf100_grctx_func { void (*r419eb0)(struct gf100_gr *); void (*r419e00)(struct gf100_gr *); void (*r418e94)(struct gf100_gr *); + void (*r419a3c)(struct gf100_gr *); }; extern const struct gf100_grctx_func gf100_grctx; @@ -130,6 +131,7 @@ void gm200_grctx_generate_dist_skip_table(struct gf100_gr *); void gm200_grctx_generate_r406500(struct gf100_gr *); void gm200_grctx_generate_tpc_mask(struct gf100_gr *); void gm200_grctx_generate_smid_config(struct gf100_gr *); +void gm200_grctx_generate_r419a3c(struct gf100_gr *); extern const struct gf100_grctx_func gm20b_grctx; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c index 13951aa41ba42..7a9be045e684e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c @@ -27,6 +27,13 @@ * PGRAPH context implementation ******************************************************************************/ +void +gm200_grctx_generate_r419a3c(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_mask(device, 0x419a3c, 0x00000014, 0x00000000); +} + static void gm200_grctx_generate_r418e94(struct gf100_gr *gr) { @@ -152,4 +159,5 @@ gm200_grctx = { .tpc_mask = gm200_grctx_generate_tpc_mask, .smid_config = gm200_grctx_generate_smid_config, .r418e94 = gm200_grctx_generate_r418e94, + .r419a3c = gm200_grctx_generate_r419a3c, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c index 821219a041971..c60f9244fd7c0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c @@ -165,4 +165,5 @@ gp100_grctx = { .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, .tpc_mask = gm200_grctx_generate_tpc_mask, .smid_config = gp100_grctx_generate_smid_config, + .r419a3c = gm200_grctx_generate_r419a3c, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c index 611819ffb1f83..3af42c14c8f32 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c @@ -101,4 +101,5 @@ gp102_grctx = { .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, .tpc_mask = gm200_grctx_generate_tpc_mask, .smid_config = gp100_grctx_generate_smid_config, + .r419a3c = gm200_grctx_generate_r419a3c, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c index d908317079e03..1864674e5824b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c @@ -51,4 +51,5 @@ gp107_grctx = { .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, .tpc_mask = gm200_grctx_generate_tpc_mask, .smid_config = gp100_grctx_generate_smid_config, + .r419a3c = gm200_grctx_generate_r419a3c, }; From a5537f980e4aba64ce1a0b14ee8fb27d0fd10362 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 085/165] drm/nouveau/gr/gf100-: update r408840 where required Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/include/nvkm/engine/gr.h | 1 + .../gpu/drm/nouveau/nvkm/engine/device/base.c | 4 +- drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild | 2 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 2 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 3 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c | 8 +++ .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp104.c | 47 ++++++++++++++ .../gpu/drm/nouveau/nvkm/engine/gr/gp104.c | 62 +++++++++++++++++++ 8 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp104.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h index fb18f105fc433..33b2f2e543eee 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h @@ -45,6 +45,7 @@ int gm200_gr_new(struct nvkm_device *, int, struct nvkm_gr **); int gm20b_gr_new(struct nvkm_device *, int, struct nvkm_gr **); int gp100_gr_new(struct nvkm_device *, int, struct nvkm_gr **); int gp102_gr_new(struct nvkm_device *, int, struct nvkm_gr **); +int gp104_gr_new(struct nvkm_device *, int, struct nvkm_gr **); int gp107_gr_new(struct nvkm_device *, int, struct nvkm_gr **); int gp10b_gr_new(struct nvkm_device *, int, struct nvkm_gr **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 379e701962a7b..16e8090082ab3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2256,7 +2256,7 @@ nv134_chipset = { .disp = gp102_disp_new, .dma = gf119_dma_new, .fifo = gp100_fifo_new, - .gr = gp102_gr_new, + .gr = gp104_gr_new, .nvdec = gp102_nvdec_new, .sec2 = gp102_sec2_new, .sw = gf100_sw_new, @@ -2292,7 +2292,7 @@ nv136_chipset = { .disp = gp102_disp_new, .dma = gf119_dma_new, .fifo = gp100_fifo_new, - .gr = gp102_gr_new, + .gr = gp104_gr_new, .nvdec = gp102_nvdec_new, .sec2 = gp102_sec2_new, .sw = gf100_sw_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild index 8a22558b7b529..42342b4a9abe0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild @@ -33,6 +33,7 @@ nvkm-y += nvkm/engine/gr/gm200.o nvkm-y += nvkm/engine/gr/gm20b.o nvkm-y += nvkm/engine/gr/gp100.o nvkm-y += nvkm/engine/gr/gp102.o +nvkm-y += nvkm/engine/gr/gp104.o nvkm-y += nvkm/engine/gr/gp107.o nvkm-y += nvkm/engine/gr/gp10b.o @@ -54,4 +55,5 @@ nvkm-y += nvkm/engine/gr/ctxgm200.o nvkm-y += nvkm/engine/gr/ctxgm20b.o nvkm-y += nvkm/engine/gr/ctxgp100.o nvkm-y += nvkm/engine/gr/ctxgp102.o +nvkm-y += nvkm/engine/gr/ctxgp104.o nvkm-y += nvkm/engine/gr/ctxgp107.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index 1d1d0ccd1ddc6..55603766c7f13 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1436,6 +1436,8 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) grctx->r418e94(gr); if (grctx->r419a3c) grctx->r419a3c(gr); + if (grctx->r408840) + grctx->r408840(gr); } #define CB_RESERVED 0x80000 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index bff24e66d39ee..668b2c71ff429 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -70,6 +70,7 @@ struct gf100_grctx_func { void (*r419e00)(struct gf100_gr *); void (*r418e94)(struct gf100_gr *); void (*r419a3c)(struct gf100_gr *); + void (*r408840)(struct gf100_gr *); }; extern const struct gf100_grctx_func gf100_grctx; @@ -143,6 +144,8 @@ void gp100_grctx_generate_smid_config(struct gf100_gr *); extern const struct gf100_grctx_func gp102_grctx; void gp102_grctx_generate_attrib(struct gf100_grctx *); +extern const struct gf100_grctx_func gp104_grctx; + extern const struct gf100_grctx_func gp107_grctx; /* context init value lists */ diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c index 3af42c14c8f32..3c78a6d1b1ba3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c @@ -29,6 +29,13 @@ * PGRAPH context implementation ******************************************************************************/ +static void +gp102_grctx_generate_r408840(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_mask(device, 0x408840, 0x00000003, 0x00000000); +} + void gp102_grctx_generate_attrib(struct gf100_grctx *info) { @@ -102,4 +109,5 @@ gp102_grctx = { .tpc_mask = gm200_grctx_generate_tpc_mask, .smid_config = gp100_grctx_generate_smid_config, .r419a3c = gm200_grctx_generate_r419a3c, + .r408840 = gp102_grctx_generate_r408840, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp104.c new file mode 100644 index 0000000000000..020cb041c5de7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp104.c @@ -0,0 +1,47 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "ctxgf100.h" + +const struct gf100_grctx_func +gp104_grctx = { + .main = gp100_grctx_generate_main, + .unkn = gk104_grctx_generate_unkn, + .bundle = gm107_grctx_generate_bundle, + .bundle_size = 0x3000, + .bundle_min_gpm_fifo_depth = 0x180, + .bundle_token_limit = 0x900, + .pagepool = gp100_grctx_generate_pagepool, + .pagepool_size = 0x20000, + .attrib = gp102_grctx_generate_attrib, + .attrib_nr_max = 0x5d4, + .attrib_nr = 0x320, + .alpha_nr_max = 0xc00, + .alpha_nr = 0x800, + .sm_id = gm107_grctx_generate_sm_id, + .rop_mapping = gf117_grctx_generate_rop_mapping, + .dist_skip_table = gm200_grctx_generate_dist_skip_table, + .r406500 = gm200_grctx_generate_r406500, + .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, + .tpc_mask = gm200_grctx_generate_tpc_mask, + .smid_config = gp100_grctx_generate_smid_config, + .r419a3c = gm200_grctx_generate_r419a3c, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c new file mode 100644 index 0000000000000..289d8b272b42a --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c @@ -0,0 +1,62 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "gf100.h" +#include "ctxgf100.h" + +#include + +static const struct gf100_gr_func +gp104_gr = { + .init = gf100_gr_init, + .init_gpc_mmu = gm200_gr_init_gpc_mmu, + .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, + .init_zcull = gf117_gr_init_zcull, + .init_num_active_ltcs = gm200_gr_init_num_active_ltcs, + .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, + .init_swdx_pes_mask = gp102_gr_init_swdx_pes_mask, + .init_fecs_exceptions = gp100_gr_init_fecs_exceptions, + .init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2, + .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, + .init_419cc0 = gf100_gr_init_419cc0, + .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, + .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, + .init_504430 = gm107_gr_init_504430, + .init_shader_exceptions = gp100_gr_init_shader_exceptions, + .rops = gm200_gr_rops, + .gpc_nr = 6, + .tpc_nr = 5, + .ppc_nr = 3, + .grctx = &gp104_grctx, + .sclass = { + { -1, -1, FERMI_TWOD_A }, + { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, + { -1, -1, PASCAL_B, &gf100_fermi }, + { -1, -1, PASCAL_COMPUTE_B }, + {} + } +}; + +int +gp104_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr) +{ + return gm200_gr_new_(&gp104_gr, device, index, pgr); +} From 201ed6f651e72d886d9066237a830aa49d2ffcd1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 086/165] drm/nouveau/gr/gf100-: delete duplicated grctx init code Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 2 -- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c | 32 +---------------- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c | 34 +------------------ .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c | 2 +- .../drm/nouveau/nvkm/engine/gr/ctxgk110b.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c | 31 +---------------- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c | 27 +-------------- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c | 25 +------------- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp104.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c | 2 +- 12 files changed, 11 insertions(+), 152 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index 668b2c71ff429..be57ff0860229 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -108,7 +108,6 @@ void gk104_grctx_generate_alpha_beta_tables(struct gf100_gr *); void gk104_grctx_generate_gpc_tpc_nr(struct gf100_gr *); extern const struct gf100_grctx_func gk20a_grctx; -void gk104_grctx_generate_main(struct gf100_gr *, struct gf100_grctx *); void gk104_grctx_generate_bundle(struct gf100_grctx *); void gk104_grctx_generate_pagepool(struct gf100_grctx *); void gk104_grctx_generate_patch_ltc(struct gf100_grctx *); @@ -137,7 +136,6 @@ void gm200_grctx_generate_r419a3c(struct gf100_gr *); extern const struct gf100_grctx_func gm20b_grctx; extern const struct gf100_grctx_func gp100_grctx; -void gp100_grctx_generate_main(struct gf100_gr *, struct gf100_grctx *); void gp100_grctx_generate_pagepool(struct gf100_grctx *); void gp100_grctx_generate_smid_config(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c index e922e3e983cfc..4b7b4f8f75fd6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c @@ -286,39 +286,9 @@ gf117_grctx_generate_attrib(struct gf100_grctx *info) } } -static void -gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) -{ - struct nvkm_device *device = gr->base.engine.subdev.device; - const struct gf100_grctx_func *grctx = gr->func->grctx; - u32 idle_timeout; - - nvkm_mc_unk260(device, 0); - - gf100_gr_mmio(gr, grctx->hub); - gf100_gr_mmio(gr, grctx->gpc); - gf100_gr_mmio(gr, grctx->zcull); - gf100_gr_mmio(gr, grctx->tpc); - gf100_gr_mmio(gr, grctx->ppc); - - idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000); - - grctx->bundle(info); - grctx->pagepool(info); - grctx->attrib(info); - grctx->unkn(gr); - - gf100_grctx_generate_floorsweep(gr); - - gf100_gr_icmd(gr, grctx->icmd); - nvkm_wr32(device, 0x404154, idle_timeout); - gf100_gr_mthd(gr, grctx->mthd); - nvkm_mc_unk260(device, 1); -} - const struct gf100_grctx_func gf117_grctx = { - .main = gf117_grctx_generate_main, + .main = gf100_grctx_generate_main, .unkn = gk104_grctx_generate_unkn, .hub = gf117_grctx_pack_hub, .gpc = gf117_grctx_pack_gpc, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c index a4fe36c136fdc..bdf2a1e6d3b6a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c @@ -921,38 +921,6 @@ gk104_grctx_generate_gpc_tpc_nr(struct gf100_gr *gr) nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); } -void -gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) -{ - struct nvkm_device *device = gr->base.engine.subdev.device; - const struct gf100_grctx_func *grctx = gr->func->grctx; - u32 idle_timeout; - - nvkm_mc_unk260(device, 0); - - gf100_gr_mmio(gr, grctx->hub); - gf100_gr_mmio(gr, grctx->gpc); - gf100_gr_mmio(gr, grctx->zcull); - gf100_gr_mmio(gr, grctx->tpc); - gf100_gr_mmio(gr, grctx->ppc); - - idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000); - - grctx->bundle(info); - grctx->pagepool(info); - grctx->attrib(info); - grctx->unkn(gr); - - gf100_grctx_generate_floorsweep(gr); - - gf100_gr_icmd(gr, grctx->icmd); - nvkm_wr32(device, 0x404154, idle_timeout); - gf100_gr_mthd(gr, grctx->mthd); - nvkm_mc_unk260(device, 1); - - grctx->r418800(gr); -} - void gk104_grctx_generate_alpha_beta_tables(struct gf100_gr *gr) { @@ -1002,7 +970,7 @@ gk104_grctx_generate_alpha_beta_tables(struct gf100_gr *gr) const struct gf100_grctx_func gk104_grctx = { - .main = gk104_grctx_generate_main, + .main = gf100_grctx_generate_main, .unkn = gk104_grctx_generate_unkn, .hub = gk104_grctx_pack_hub, .gpc = gk104_grctx_pack_gpc, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c index f00e7afef9c44..2ba35d727dc1d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c @@ -817,7 +817,7 @@ gk110_grctx_generate_r419eb0(struct gf100_gr *gr) const struct gf100_grctx_func gk110_grctx = { - .main = gk104_grctx_generate_main, + .main = gf100_grctx_generate_main, .unkn = gk104_grctx_generate_unkn, .hub = gk110_grctx_pack_hub, .gpc = gk110_grctx_pack_gpc, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c index ed09cfdfb024b..1112f8dc70e2c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c @@ -71,7 +71,7 @@ gk110b_grctx_pack_tpc[] = { const struct gf100_grctx_func gk110b_grctx = { - .main = gk104_grctx_generate_main, + .main = gf100_grctx_generate_main, .unkn = gk104_grctx_generate_unkn, .hub = gk110_grctx_pack_hub, .gpc = gk110_grctx_pack_gpc, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c index c69494f7418ef..613c5cf8b3bf7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c @@ -532,7 +532,7 @@ gk208_grctx_pack_ppc[] = { const struct gf100_grctx_func gk208_grctx = { - .main = gk104_grctx_generate_main, + .main = gf100_grctx_generate_main, .unkn = gk104_grctx_generate_unkn, .hub = gk208_grctx_pack_hub, .gpc = gk208_grctx_pack_gpc, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c index 12a9431dc8b42..7816dcb7c9743 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c @@ -955,38 +955,9 @@ gm107_grctx_generate_sm_id(struct gf100_gr *gr, int gpc, int tpc, int sm) nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x088), sm); } -static void -gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) -{ - struct nvkm_device *device = gr->base.engine.subdev.device; - const struct gf100_grctx_func *grctx = gr->func->grctx; - u32 idle_timeout; - - gf100_gr_mmio(gr, grctx->hub); - gf100_gr_mmio(gr, grctx->gpc); - gf100_gr_mmio(gr, grctx->zcull); - gf100_gr_mmio(gr, grctx->tpc); - gf100_gr_mmio(gr, grctx->ppc); - - idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000); - - grctx->bundle(info); - grctx->pagepool(info); - grctx->attrib(info); - grctx->unkn(gr); - - gf100_grctx_generate_floorsweep(gr); - - gf100_gr_icmd(gr, grctx->icmd); - nvkm_wr32(device, 0x404154, idle_timeout); - gf100_gr_mthd(gr, grctx->mthd); - - grctx->r419e00(gr); -} - const struct gf100_grctx_func gm107_grctx = { - .main = gm107_grctx_generate_main, + .main = gf100_grctx_generate_main, .unkn = gk104_grctx_generate_unkn, .hub = gm107_grctx_pack_hub, .gpc = gm107_grctx_pack_gpc, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c index 7a9be045e684e..7107ec4297783 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c @@ -89,31 +89,6 @@ gm200_grctx_generate_r406500(struct gf100_gr *gr) nvkm_wr32(gr->base.engine.subdev.device, 0x406500, 0x00000000); } -static void -gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) -{ - struct nvkm_device *device = gr->base.engine.subdev.device; - const struct gf100_grctx_func *grctx = gr->func->grctx; - u32 idle_timeout; - - gf100_gr_mmio(gr, gr->fuc_sw_ctx); - - idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000); - - grctx->bundle(info); - grctx->pagepool(info); - grctx->attrib(info); - grctx->unkn(gr); - - gf100_grctx_generate_floorsweep(gr); - - gf100_gr_icmd(gr, gr->fuc_bundle); - nvkm_wr32(device, 0x404154, idle_timeout); - gf100_gr_mthd(gr, gr->fuc_method); - - grctx->r418e94(gr); -} - void gm200_grctx_generate_dist_skip_table(struct gf100_gr *gr) { @@ -138,7 +113,7 @@ gm200_grctx_generate_dist_skip_table(struct gf100_gr *gr) const struct gf100_grctx_func gm200_grctx = { - .main = gm200_grctx_generate_main, + .main = gf100_grctx_generate_main, .unkn = gk104_grctx_generate_unkn, .bundle = gm107_grctx_generate_bundle, .bundle_size = 0x3000, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c index c60f9244fd7c0..af6330c738723 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c @@ -120,32 +120,9 @@ gp100_grctx_generate_smid_config(struct gf100_gr *gr) nvkm_wr32(device, 0x405ba0 + (i * 4), gpcs[i]); } -void -gp100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) -{ - struct nvkm_device *device = gr->base.engine.subdev.device; - const struct gf100_grctx_func *grctx = gr->func->grctx; - u32 idle_timeout; - - gf100_gr_mmio(gr, gr->fuc_sw_ctx); - - idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000); - - grctx->pagepool(info); - grctx->bundle(info); - grctx->attrib(info); - grctx->unkn(gr); - - gf100_grctx_generate_floorsweep(gr); - - gf100_gr_icmd(gr, gr->fuc_bundle); - nvkm_wr32(device, 0x404154, idle_timeout); - gf100_gr_mthd(gr, gr->fuc_method); -} - const struct gf100_grctx_func gp100_grctx = { - .main = gp100_grctx_generate_main, + .main = gf100_grctx_generate_main, .unkn = gk104_grctx_generate_unkn, .bundle = gm107_grctx_generate_bundle, .bundle_size = 0x3000, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c index 3c78a6d1b1ba3..8a438c2efc3e6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c @@ -88,7 +88,7 @@ gp102_grctx_generate_attrib(struct gf100_grctx *info) const struct gf100_grctx_func gp102_grctx = { - .main = gp100_grctx_generate_main, + .main = gf100_grctx_generate_main, .unkn = gk104_grctx_generate_unkn, .bundle = gm107_grctx_generate_bundle, .bundle_size = 0x3000, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp104.c index 020cb041c5de7..5f799c7369bbc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp104.c @@ -23,7 +23,7 @@ const struct gf100_grctx_func gp104_grctx = { - .main = gp100_grctx_generate_main, + .main = gf100_grctx_generate_main, .unkn = gk104_grctx_generate_unkn, .bundle = gm107_grctx_generate_bundle, .bundle_size = 0x3000, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c index 1864674e5824b..a69e824676c9d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c @@ -31,7 +31,7 @@ const struct gf100_grctx_func gp107_grctx = { - .main = gp100_grctx_generate_main, + .main = gf100_grctx_generate_main, .unkn = gk104_grctx_generate_unkn, .bundle = gm107_grctx_generate_bundle, .bundle_size = 0x3000, From 74b6068bd660a806e801ae039dbab58dc284301e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 087/165] drm/nouveau/gr/gf100-: add missing reset sequence before golden context init RM and NVGPU both have a variant of this, we probably should too. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index 55603766c7f13..4c25389fe80ae 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1456,6 +1456,26 @@ gf100_grctx_generate(struct gf100_gr *gr) int ret, i; u64 addr; + /* NV_PGRAPH_FE_PWR_MODE_FORCE_ON. */ + nvkm_wr32(device, 0x404170, 0x00000012); + nvkm_msec(device, 2000, + if (!(nvkm_rd32(device, 0x404170) & 0x00000010)) + break; + ); + + /* Reset FECS. */ + nvkm_wr32(device, 0x409614, 0x00000070); + nvkm_usec(device, 10, NVKM_DELAY); + nvkm_mask(device, 0x409614, 0x00000700, 0x00000700); + nvkm_usec(device, 10, NVKM_DELAY); + nvkm_rd32(device, 0x409614); + + /* NV_PGRAPH_FE_PWR_MODE_AUTO. */ + nvkm_wr32(device, 0x404170, 0x00000010); + + /* Init SCC RAM. */ + nvkm_wr32(device, 0x40802c, 0x00000001); + /* Allocate memory to for a "channel", which we'll use to generate * the default context values. */ From 5c05a589856ad5f79c22b0500340291c591c3050 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 088/165] drm/nouveau/gr/gf100-: virtualise trap_mp Required to support Volta. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 5 +++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c | 1 + 20 files changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index dd4a4104306c1..f05d9d4c6e5cc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1010,7 +1010,7 @@ static const struct nvkm_bitfield gf100_mp_global_error[] = { {} }; -static void +void gf100_gr_trap_mp(struct gf100_gr *gr, int gpc, int tpc) { struct nvkm_subdev *subdev = &gr->base.engine.subdev; @@ -1046,7 +1046,7 @@ gf100_gr_trap_tpc(struct gf100_gr *gr, int gpc, int tpc) } if (stat & 0x00000002) { - gf100_gr_trap_mp(gr, gpc, tpc); + gr->func->trap_mp(gr, gpc, tpc); stat &= ~0x00000002; } @@ -2176,6 +2176,7 @@ gf100_gr = { .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, .init_400054 = gf100_gr_init_400054, + .trap_mp = gf100_gr_trap_mp, .mmio = gf100_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 31109cec5a764..c25b93a0cb03d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -145,6 +145,7 @@ struct gf100_gr_func { void (*init_504430)(struct gf100_gr *, int gpc, int tpc); void (*init_shader_exceptions)(struct gf100_gr *, int gpc, int tpc); void (*init_400054)(struct gf100_gr *); + void (*trap_mp)(struct gf100_gr *, int gpc, int tpc); void (*set_hww_esr_report_mask)(struct gf100_gr *); const struct gf100_gr_pack *mmio; struct { @@ -301,6 +302,7 @@ extern const struct gf100_gr_init gf100_gr_init_be_0[]; extern const struct gf100_gr_init gf100_gr_init_fe_1[]; extern const struct gf100_gr_init gf100_gr_init_pe_1[]; void gf100_gr_init_gpc_mmu(struct gf100_gr *); +void gf100_gr_trap_mp(struct gf100_gr *, int, int); extern const struct gf100_gr_init gf104_gr_init_ds_0[]; extern const struct gf100_gr_init gf104_gr_init_tex_0[]; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c index d5276cab7f7b6..df9cbed7ce509 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c @@ -126,6 +126,7 @@ gf104_gr = { .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, .init_400054 = gf100_gr_init_400054, + .trap_mp = gf100_gr_trap_mp, .mmio = gf104_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c index 8f22a311dccb7..8ffa0fd1134f4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c @@ -124,6 +124,7 @@ gf108_gr = { .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, .init_400054 = gf100_gr_init_400054, + .trap_mp = gf100_gr_trap_mp, .mmio = gf108_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c index fcbfdc7e9b266..0d4293e3e4eae 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c @@ -98,6 +98,7 @@ gf110_gr = { .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, .init_400054 = gf100_gr_init_400054, + .trap_mp = gf100_gr_trap_mp, .mmio = gf110_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c index f526ccddaf5ed..e3c1dbbfbf34d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c @@ -162,6 +162,7 @@ gf117_gr = { .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, .init_400054 = gf100_gr_init_400054, + .trap_mp = gf100_gr_trap_mp, .mmio = gf117_gr_pack_mmio, .fecs.ucode = &gf117_gr_fecs_ucode, .gpccs.ucode = &gf117_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c index 5d3d22fb5c86f..1ed70b93a10aa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c @@ -189,6 +189,7 @@ gf119_gr = { .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, .init_400054 = gf100_gr_init_400054, + .trap_mp = gf100_gr_trap_mp, .mmio = gf119_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index 2e5c48b61ac81..86819ab7f9a4d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -462,6 +462,7 @@ gk104_gr = { .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, .init_400054 = gf100_gr_init_400054, + .trap_mp = gf100_gr_trap_mp, .mmio = gk104_gr_pack_mmio, .fecs.ucode = &gk104_gr_fecs_ucode, .gpccs.ucode = &gk104_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index 9adb55f658c64..e30d94ff23d73 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -364,6 +364,7 @@ gk110_gr = { .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, .init_400054 = gf100_gr_init_400054, + .trap_mp = gf100_gr_trap_mp, .mmio = gk110_gr_pack_mmio, .fecs.ucode = &gk110_gr_fecs_ucode, .gpccs.ucode = &gk110_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index f848f1578cd3e..253b98181ac43 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c @@ -116,6 +116,7 @@ gk110b_gr = { .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, .init_400054 = gf100_gr_init_400054, + .trap_mp = gf100_gr_trap_mp, .mmio = gk110b_gr_pack_mmio, .fecs.ucode = &gk110_gr_fecs_ucode, .gpccs.ucode = &gk110_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c index 9c678f17b2fe0..702e9094c1c82 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c @@ -174,6 +174,7 @@ gk208_gr = { .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_shader_exceptions = gf100_gr_init_shader_exceptions, .init_400054 = gf100_gr_init_400054, + .trap_mp = gf100_gr_trap_mp, .mmio = gk208_gr_pack_mmio, .fecs.ucode = &gk208_gr_fecs_ucode, .gpccs.ucode = &gk208_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c index a806643ede7e6..95f7d859e6340 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c @@ -285,6 +285,7 @@ gk20a_gr = { .init = gk20a_gr_init, .init_zcull = gf117_gr_init_zcull, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, + .trap_mp = gf100_gr_trap_mp, .set_hww_esr_report_mask = gk20a_gr_set_hww_esr_report_mask, .rops = gf100_gr_rops, .ppc_nr = 1, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index c598fa5a68e03..d67bf9465baa5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -407,6 +407,7 @@ gm107_gr = { .init_504430 = gm107_gr_init_504430, .init_shader_exceptions = gm107_gr_init_shader_exceptions, .init_400054 = gm107_gr_init_400054, + .trap_mp = gf100_gr_trap_mp, .mmio = gm107_gr_pack_mmio, .fecs.ucode = &gm107_gr_fecs_ucode, .gpccs.ucode = &gm107_gr_gpccs_ucode, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index ae0eaf8e6d713..03b255e9b8120 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -133,6 +133,7 @@ gm200_gr = { .init_504430 = gm107_gr_init_504430, .init_shader_exceptions = gm107_gr_init_shader_exceptions, .init_400054 = gm107_gr_init_400054, + .trap_mp = gf100_gr_trap_mp, .rops = gm200_gr_rops, .tpc_nr = 4, .ppc_nr = 2, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c index fcf86d5cf26fa..d2f9c7bf9f037 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c @@ -68,6 +68,7 @@ gm20b_gr = { .init_zcull = gf117_gr_init_zcull, .init_gpc_mmu = gm20b_gr_init_gpc_mmu, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, + .trap_mp = gf100_gr_trap_mp, .set_hww_esr_report_mask = gm20b_gr_set_hww_esr_report_mask, .rops = gm200_gr_rops, .ppc_nr = 1, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c index 3addbc1d62c7e..e5f941f81e074 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c @@ -79,6 +79,7 @@ gp100_gr = { .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_504430 = gm107_gr_init_504430, .init_shader_exceptions = gp100_gr_init_shader_exceptions, + .trap_mp = gf100_gr_trap_mp, .rops = gm200_gr_rops, .gpc_nr = 6, .tpc_nr = 5, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c index ea99c15487efc..09e2665e49885 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c @@ -57,6 +57,7 @@ gp102_gr = { .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_504430 = gm107_gr_init_504430, .init_shader_exceptions = gp100_gr_init_shader_exceptions, + .trap_mp = gf100_gr_trap_mp, .rops = gm200_gr_rops, .gpc_nr = 6, .tpc_nr = 5, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c index 289d8b272b42a..844fc9d63e5c5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c @@ -41,6 +41,7 @@ gp104_gr = { .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_504430 = gm107_gr_init_504430, .init_shader_exceptions = gp100_gr_init_shader_exceptions, + .trap_mp = gf100_gr_trap_mp, .rops = gm200_gr_rops, .gpc_nr = 6, .tpc_nr = 5, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c index 09cba537b8b9d..674385da3d43f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c @@ -43,6 +43,7 @@ gp107_gr = { .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_504430 = gm107_gr_init_504430, .init_shader_exceptions = gp100_gr_init_shader_exceptions, + .trap_mp = gf100_gr_trap_mp, .rops = gm200_gr_rops, .gpc_nr = 2, .tpc_nr = 3, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c index 4972bf8d25309..6103186a3724c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c @@ -41,6 +41,7 @@ gp10b_gr = { .init_tex_hww_esr = gf100_gr_init_tex_hww_esr, .init_504430 = gm107_gr_init_504430, .init_shader_exceptions = gp100_gr_init_shader_exceptions, + .trap_mp = gf100_gr_trap_mp, .rops = gm200_gr_rops, .gpc_nr = 1, .tpc_nr = 2, From 5f6474a4e6ce3291abb1843b279a23a0bb050d37 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 089/165] drm/nouveau/gr/gf100-: port tile mapping calculations from NVGPU There's also a couple of hardcoded tables for a couple of very specific configurations that NVGPU's algorithm didn't work for. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 23 +--- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c | 23 +--- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 118 ++++++++++++------ .../gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 8 +- .../gpu/drm/nouveau/nvkm/engine/gr/gf104.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf108.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf110.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf117.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf119.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk208.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk20a.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gm200.c | 41 ++++++ .../gpu/drm/nouveau/nvkm/engine/gr/gm20b.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp100.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp102.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp104.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp107.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp10b.c | 1 + 22 files changed, 153 insertions(+), 77 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index 4c25389fe80ae..949e1216b8ba3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1116,27 +1116,14 @@ gf100_grctx_generate_rop_mapping(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; u32 data[6] = {}, data2[2] = {}; - u8 tpcnr[GPC_MAX]; u8 shift, ntpcv; - int gpc, tpc, i; - - /* calculate first set of magics */ - memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); - - gpc = -1; - for (tpc = 0; tpc < gr->tpc_total; tpc++) { - do { - gpc = (gpc + 1) % gr->gpc_nr; - } while (!tpcnr[gpc]); - tpcnr[gpc]--; - - data[tpc / 6] |= gpc << ((tpc % 6) * 5); - } + int i; - for (; tpc < 32; tpc++) - data[tpc / 6] |= 7 << ((tpc % 6) * 5); + /* Pack tile map into register format. */ + for (i = 0; i < 32; i++) + data[i / 6] |= (gr->tile[i] & 0x07) << ((i % 6) * 5); - /* and the second... */ + /* Magic. */ shift = 0; ntpcv = gr->tpc_total; while (!(ntpcv & (1 << 4))) { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c index 4b7b4f8f75fd6..bc4e86bbb9d47 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c @@ -194,27 +194,14 @@ gf117_grctx_generate_rop_mapping(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; u32 data[6] = {}, data2[2] = {}; - u8 tpcnr[GPC_MAX]; u8 shift, ntpcv; - int gpc, tpc, i; - - /* calculate first set of magics */ - memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); - - gpc = -1; - for (tpc = 0; tpc < gr->tpc_total; tpc++) { - do { - gpc = (gpc + 1) % gr->gpc_nr; - } while (!tpcnr[gpc]); - tpcnr[gpc]--; - - data[tpc / 6] |= gpc << ((tpc % 6) * 5); - } + int i; - for (; tpc < 32; tpc++) - data[tpc / 6] |= 7 << ((tpc % 6) * 5); + /* Pack tile map into register format. */ + for (i = 0; i < 32; i++) + data[i / 6] |= (gr->tile[i] & 0x07) << ((i % 6) * 5); - /* and the second... */ + /* Magic. */ shift = 0; ntpcv = gr->tpc_total; while (!(ntpcv & (1 << 4))) { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index f05d9d4c6e5cc..519b109f40d2e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1652,6 +1652,82 @@ gf100_gr_init_ctxctl(struct gf100_gr *gr) return ret; } +void +gf100_gr_oneinit_tiles(struct gf100_gr *gr) +{ + static const u8 primes[] = { + 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61 + }; + int init_frac[GPC_MAX], init_err[GPC_MAX], run_err[GPC_MAX], i, j; + u32 mul_factor, comm_denom; + u8 gpc_map[GPC_MAX]; + bool sorted; + + switch (gr->tpc_total) { + case 15: gr->screen_tile_row_offset = 0x06; break; + case 14: gr->screen_tile_row_offset = 0x05; break; + case 13: gr->screen_tile_row_offset = 0x02; break; + case 11: gr->screen_tile_row_offset = 0x07; break; + case 10: gr->screen_tile_row_offset = 0x06; break; + case 7: + case 5: gr->screen_tile_row_offset = 0x01; break; + case 3: gr->screen_tile_row_offset = 0x02; break; + case 2: + case 1: gr->screen_tile_row_offset = 0x01; break; + default: gr->screen_tile_row_offset = 0x03; + for (i = 0; i < ARRAY_SIZE(primes); i++) { + if (gr->tpc_total % primes[i]) { + gr->screen_tile_row_offset = primes[i]; + break; + } + } + break; + } + + /* Sort GPCs by TPC count, highest-to-lowest. */ + for (i = 0; i < gr->gpc_nr; i++) + gpc_map[i] = i; + sorted = false; + + while (!sorted) { + for (sorted = true, i = 0; i < gr->gpc_nr - 1; i++) { + if (gr->tpc_nr[gpc_map[i + 1]] > + gr->tpc_nr[gpc_map[i + 0]]) { + u8 swap = gpc_map[i]; + gpc_map[i + 0] = gpc_map[i + 1]; + gpc_map[i + 1] = swap; + sorted = false; + } + } + } + + /* Determine tile->GPC mapping */ + mul_factor = gr->gpc_nr * gr->tpc_max; + if (mul_factor & 1) + mul_factor = 2; + else + mul_factor = 1; + + comm_denom = gr->gpc_nr * gr->tpc_max * mul_factor; + + for (i = 0; i < gr->gpc_nr; i++) { + init_frac[i] = gr->tpc_nr[gpc_map[i]] * gr->gpc_nr * mul_factor; + init_err[i] = i * gr->tpc_max * mul_factor - comm_denom/2; + run_err[i] = init_frac[i] + init_err[i]; + } + + for (i = 0; i < gr->tpc_total;) { + for (j = 0; j < gr->gpc_nr; j++) { + if ((run_err[j] * 2) >= comm_denom) { + gr->tile[i++] = gpc_map[j]; + run_err[j] += init_frac[j] - comm_denom; + } else { + run_err[j] += init_frac[j]; + } + } + } +} + static int gf100_gr_oneinit(struct nvkm_gr *base) { @@ -1691,45 +1767,8 @@ gf100_gr_oneinit(struct nvkm_gr *base) } } - /*XXX: these need figuring out... though it might not even matter */ - switch (device->chipset) { - case 0xc0: - if (gr->tpc_total == 11) { /* 465, 3/4/4/0, 4 */ - gr->screen_tile_row_offset = 0x07; - } else - if (gr->tpc_total == 14) { /* 470, 3/3/4/4, 5 */ - gr->screen_tile_row_offset = 0x05; - } else - if (gr->tpc_total == 15) { /* 480, 3/4/4/4, 6 */ - gr->screen_tile_row_offset = 0x06; - } - break; - case 0xc3: /* 450, 4/0/0/0, 2 */ - gr->screen_tile_row_offset = 0x03; - break; - case 0xc4: /* 460, 3/4/0/0, 4 */ - gr->screen_tile_row_offset = 0x01; - break; - case 0xc1: /* 2/0/0/0, 1 */ - gr->screen_tile_row_offset = 0x01; - break; - case 0xc8: /* 4/4/3/4, 5 */ - gr->screen_tile_row_offset = 0x06; - break; - case 0xce: /* 4/4/0/0, 4 */ - gr->screen_tile_row_offset = 0x03; - break; - case 0xcf: /* 4/0/0/0, 3 */ - gr->screen_tile_row_offset = 0x03; - break; - case 0xd7: - case 0xd9: /* 1/0/0/0, 1 */ - case 0xea: /* gk20a */ - case 0x12b: /* gm20b */ - gr->screen_tile_row_offset = 0x01; - break; - } - + memset(gr->tile, 0xff, sizeof(gr->tile)); + gr->func->oneinit_tiles(gr); return 0; } @@ -2164,6 +2203,7 @@ gf100_gr_gpccs_ucode = { static const struct gf100_gr_func gf100_gr = { + .oneinit_tiles = gf100_gr_oneinit_tiles, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index c25b93a0cb03d..53a173e023b4c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -107,12 +107,13 @@ struct gf100_gr { u8 ppc_tpc_nr[GPC_MAX][4]; u8 ppc_tpc_min; + u8 screen_tile_row_offset; + u8 tile[TPC_MAX]; + struct gf100_gr_data mmio_data[4]; struct gf100_gr_mmio mmio_list[4096/8]; u32 size; u32 *data; - - u8 screen_tile_row_offset; }; int gf100_gr_ctor(const struct gf100_gr_func *, struct nvkm_device *, @@ -123,6 +124,7 @@ void *gf100_gr_dtor(struct nvkm_gr *); struct gf100_gr_func { void (*dtor)(struct gf100_gr *); + void (*oneinit_tiles)(struct gf100_gr *); int (*init)(struct gf100_gr *); void (*init_gpc_mmu)(struct gf100_gr *); void (*init_r405a14)(struct gf100_gr *); @@ -164,6 +166,7 @@ struct gf100_gr_func { }; int gf100_gr_rops(struct gf100_gr *); +void gf100_gr_oneinit_tiles(struct gf100_gr *); int gf100_gr_init(struct gf100_gr *); void gf100_gr_init_vsc_stream_master(struct gf100_gr *); void gf100_gr_init_zcull(struct gf100_gr *); @@ -191,6 +194,7 @@ void gm107_gr_init_400054(struct gf100_gr *); int gk20a_gr_init(struct gf100_gr *); +void gm200_gr_oneinit_tiles(struct gf100_gr *); int gm200_gr_rops(struct gf100_gr *); void gm200_gr_init_num_active_ltcs(struct gf100_gr *); void gm200_gr_init_ds_hww_esr_2(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c index df9cbed7ce509..8b49b8fe6d2cf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c @@ -114,6 +114,7 @@ gf104_gr_pack_mmio[] = { static const struct gf100_gr_func gf104_gr = { + .oneinit_tiles = gf100_gr_oneinit_tiles, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c index 8ffa0fd1134f4..6432aeba0a148 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c @@ -111,6 +111,7 @@ gf108_gr_init_r405a14(struct gf100_gr *gr) static const struct gf100_gr_func gf108_gr = { + .oneinit_tiles = gf100_gr_oneinit_tiles, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_r405a14 = gf108_gr_init_r405a14, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c index 0d4293e3e4eae..4e007c945233c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c @@ -86,6 +86,7 @@ gf110_gr_pack_mmio[] = { static const struct gf100_gr_func gf110_gr = { + .oneinit_tiles = gf100_gr_oneinit_tiles, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c index e3c1dbbfbf34d..2ddb728fb7ca3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c @@ -150,6 +150,7 @@ gf117_gr_init_zcull(struct gf100_gr *gr) static const struct gf100_gr_func gf117_gr = { + .oneinit_tiles = gf100_gr_oneinit_tiles, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c index 1ed70b93a10aa..f0f10a4d8a26b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c @@ -177,6 +177,7 @@ gf119_gr_pack_mmio[] = { static const struct gf100_gr_func gf119_gr = { + .oneinit_tiles = gf100_gr_oneinit_tiles, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index 86819ab7f9a4d..d57fb5ff1fe94 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -448,6 +448,7 @@ gk104_gr_gpccs_ucode = { static const struct gf100_gr_func gk104_gr = { + .oneinit_tiles = gf100_gr_oneinit_tiles, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index e30d94ff23d73..41997ebda7193 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -350,6 +350,7 @@ gk110_gr_init_419eb4(struct gf100_gr *gr) static const struct gf100_gr_func gk110_gr = { + .oneinit_tiles = gf100_gr_oneinit_tiles, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index 253b98181ac43..b7a6479c6ec22 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c @@ -102,6 +102,7 @@ gk110b_gr_pack_mmio[] = { static const struct gf100_gr_func gk110b_gr = { + .oneinit_tiles = gf100_gr_oneinit_tiles, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c index 702e9094c1c82..5f1e71abe5042 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c @@ -161,6 +161,7 @@ gk208_gr_gpccs_ucode = { static const struct gf100_gr_func gk208_gr = { + .oneinit_tiles = gf100_gr_oneinit_tiles, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c index 95f7d859e6340..ab4e5380eba2d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c @@ -282,6 +282,7 @@ gk20a_gr_init(struct gf100_gr *gr) static const struct gf100_gr_func gk20a_gr = { + .oneinit_tiles = gf100_gr_oneinit_tiles, .init = gk20a_gr_init, .init_zcull = gf117_gr_init_zcull, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index d67bf9465baa5..98f74fe7007d0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -391,6 +391,7 @@ gm107_gr_gpccs_ucode = { static const struct gf100_gr_func gm107_gr = { + .oneinit_tiles = gf100_gr_oneinit_tiles, .init = gf100_gr_init, .init_gpc_mmu = gm107_gr_init_gpc_mmu, .init_bios = gm107_gr_init_bios, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index 03b255e9b8120..3e017fdd23ed9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -77,6 +77,46 @@ gm200_gr_init_rop_active_fbps(struct gf100_gr *gr) nvkm_mask(device, 0x408958, 0x0000000f, fbp_count); /* crop */ } +static u8 +gm200_gr_tile_map_6_24[] = { + 0, 1, 2, 3, 4, 5, 3, 4, 5, 0, 1, 2, 0, 1, 2, 3, 4, 5, 3, 4, 5, 0, 1, 2, +}; + +static u8 +gm200_gr_tile_map_4_16[] = { + 0, 1, 2, 3, 2, 3, 0, 1, 3, 0, 1, 2, 1, 2, 3, 0, +}; + +static u8 +gm200_gr_tile_map_2_8[] = { + 0, 1, 1, 0, 0, 1, 1, 0, +}; + +void +gm200_gr_oneinit_tiles(struct gf100_gr *gr) +{ + /*XXX: Not sure what this is about. The algorithm from NVGPU + * seems to work for all boards I tried from earlier (and + * later) GPUs except in these specific configurations. + * + * Let's just hardcode them for now. + */ + if (gr->gpc_nr == 2 && gr->tpc_total == 8) { + memcpy(gr->tile, gm200_gr_tile_map_2_8, gr->tpc_total); + gr->screen_tile_row_offset = 1; + } else + if (gr->gpc_nr == 4 && gr->tpc_total == 16) { + memcpy(gr->tile, gm200_gr_tile_map_4_16, gr->tpc_total); + gr->screen_tile_row_offset = 4; + } else + if (gr->gpc_nr == 6 && gr->tpc_total == 24) { + memcpy(gr->tile, gm200_gr_tile_map_6_24, gr->tpc_total); + gr->screen_tile_row_offset = 5; + } else { + gf100_gr_oneinit_tiles(gr); + } +} + int gm200_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device, int index, struct nvkm_gr **pgr) @@ -117,6 +157,7 @@ gm200_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device, static const struct gf100_gr_func gm200_gr = { + .oneinit_tiles = gm200_gr_oneinit_tiles, .init = gf100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_bios = gm107_gr_init_bios, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c index d2f9c7bf9f037..29d3b9445cf63 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c @@ -64,6 +64,7 @@ gm20b_gr_set_hww_esr_report_mask(struct gf100_gr *gr) static const struct gf100_gr_func gm20b_gr = { + .oneinit_tiles = gm200_gr_oneinit_tiles, .init = gk20a_gr_init, .init_zcull = gf117_gr_init_zcull, .init_gpc_mmu = gm20b_gr_init_gpc_mmu, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c index e5f941f81e074..70d0aa2c1076b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c @@ -64,6 +64,7 @@ gp100_gr_init_rop_active_fbps(struct gf100_gr *gr) static const struct gf100_gr_func gp100_gr = { + .oneinit_tiles = gm200_gr_oneinit_tiles, .init = gf100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c index 09e2665e49885..71bfe2d8c3f61 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c @@ -42,6 +42,7 @@ gp102_gr_init_swdx_pes_mask(struct gf100_gr *gr) static const struct gf100_gr_func gp102_gr = { + .oneinit_tiles = gm200_gr_oneinit_tiles, .init = gf100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c index 844fc9d63e5c5..234c970bb0dc9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c @@ -26,6 +26,7 @@ static const struct gf100_gr_func gp104_gr = { + .oneinit_tiles = gm200_gr_oneinit_tiles, .init = gf100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c index 674385da3d43f..6c5724017c719 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c @@ -28,6 +28,7 @@ static const struct gf100_gr_func gp107_gr = { + .oneinit_tiles = gm200_gr_oneinit_tiles, .init = gf100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c index 6103186a3724c..aaaa2844ec201 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c @@ -27,6 +27,7 @@ static const struct gf100_gr_func gp10b_gr = { + .oneinit_tiles = gm200_gr_oneinit_tiles, .init = gf100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, From d00ffc0c403784c9f88d8da357f9f33f855289a4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 090/165] drm/nouveau/gr/gf100-: port zcull tile mapping calculations from NVGPU Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 34 +++++++++---------- .../gpu/drm/nouveau/nvkm/engine/gr/gf117.c | 34 +++++++++---------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 519b109f40d2e..f6d884156b754 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -2042,25 +2042,25 @@ gf100_gr_init_zcull(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); - u32 data[TPC_MAX / 8] = {}; - u8 tpcnr[GPC_MAX]; - int gpc, tpc; - int i; - - memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); - for (i = 0, gpc = -1; i < gr->tpc_total; i++) { - do { - gpc = (gpc + 1) % gr->gpc_nr; - } while (!tpcnr[gpc]); - tpc = gr->tpc_nr[gpc] - tpcnr[gpc]--; - - data[i / 8] |= tpc << ((i % 8) * 4); + const u8 tile_nr = ALIGN(gr->tpc_total, 32); + u8 bank[GPC_MAX] = {}, gpc, i, j; + u32 data; + + for (i = 0; i < tile_nr; i += 8) { + for (data = 0, j = 0; j < 8 && i + j < gr->tpc_total; j++) { + data |= bank[gr->tile[i + j]] << (j * 4); + bank[gr->tile[i + j]]++; + } + nvkm_wr32(device, GPC_BCAST(0x0980 + ((i / 8) * 4)), data); } - nvkm_wr32(device, GPC_BCAST(0x0980), data[0]); - nvkm_wr32(device, GPC_BCAST(0x0984), data[1]); - nvkm_wr32(device, GPC_BCAST(0x0988), data[2]); - nvkm_wr32(device, GPC_BCAST(0x098c), data[3]); + for (gpc = 0; gpc < gr->gpc_nr; gpc++) { + nvkm_wr32(device, GPC_UNIT(gpc, 0x0914), + gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]); + nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 | + gr->tpc_total); + nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918); + } nvkm_wr32(device, GPC_BCAST(0x1bd4), magicgpc918); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c index 2ddb728fb7ca3..d6831b41df39f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c @@ -125,25 +125,25 @@ gf117_gr_init_zcull(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); - u32 data[TPC_MAX / 8] = {}; - u8 tpcnr[GPC_MAX]; - int gpc, tpc; - int i; - - memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); - for (i = 0, gpc = -1; i < gr->tpc_total; i++) { - do { - gpc = (gpc + 1) % gr->gpc_nr; - } while (!tpcnr[gpc]); - tpc = gr->tpc_nr[gpc] - tpcnr[gpc]--; - - data[i / 8] |= tpc << ((i % 8) * 4); + const u8 tile_nr = ALIGN(gr->tpc_total, 32); + u8 bank[GPC_MAX] = {}, gpc, i, j; + u32 data; + + for (i = 0; i < tile_nr; i += 8) { + for (data = 0, j = 0; j < 8 && i + j < gr->tpc_total; j++) { + data |= bank[gr->tile[i + j]] << (j * 4); + bank[gr->tile[i + j]]++; + } + nvkm_wr32(device, GPC_BCAST(0x0980 + ((i / 8) * 4)), data); } - nvkm_wr32(device, GPC_BCAST(0x0980), data[0]); - nvkm_wr32(device, GPC_BCAST(0x0984), data[1]); - nvkm_wr32(device, GPC_BCAST(0x0988), data[2]); - nvkm_wr32(device, GPC_BCAST(0x098c), data[3]); + for (gpc = 0; gpc < gr->gpc_nr; gpc++) { + nvkm_wr32(device, GPC_UNIT(gpc, 0x0914), + gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]); + nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 | + gr->tpc_total); + nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918); + } nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918); } From 068cae743c2ad08a082d6fef007e6b38f5fb3b16 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 091/165] drm/nouveau/gr/gf100-: calculate and use sm mapping table There's a number of places that require this data, so let's separate out the calculations to ensure they remain consistent. This is incorrect for GM200 and newer, but will produce the same results as we did before. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 40 ++++++++----------- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c | 22 +++------- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c | 22 +++------- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 17 ++++++++ .../gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 9 +++++ .../gpu/drm/nouveau/nvkm/engine/gr/gf104.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf108.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf110.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf117.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf119.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk208.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk20a.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gm200.c | 8 ++++ .../gpu/drm/nouveau/nvkm/engine/gr/gm20b.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp100.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp102.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp104.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp107.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp10b.c | 1 + 23 files changed, 79 insertions(+), 56 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index 949e1216b8ba3..c2dcc01379c9e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1092,23 +1092,18 @@ gf100_grctx_generate_r4060a8(struct gf100_gr *gr) struct nvkm_device *device = gr->base.engine.subdev.device; const u8 gpcmax = nvkm_rd32(device, 0x022430); const u8 tpcmax = nvkm_rd32(device, 0x022434) * gpcmax; - u8 tpcnr[GPC_MAX], data[TPC_MAX]; - int gpc, tpc, i; - - memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); - memset(data, 0x1f, sizeof(data)); - - gpc = -1; - for (tpc = 0; tpc < gr->tpc_total; tpc++) { - do { - gpc = (gpc + 1) % gr->gpc_nr; - } while (!tpcnr[gpc]); - tpcnr[gpc]--; - data[tpc] = gpc; - } + int i, j, sm = 0; + u32 data; - for (i = 0; i < DIV_ROUND_UP(tpcmax, 4); i++) - nvkm_wr32(device, 0x4060a8 + (i * 4), ((u32 *)data)[i]); + for (i = 0; i < DIV_ROUND_UP(tpcmax, 4); i++) { + for (data = 0, j = 0; j < 4; j++) { + if (sm < gr->sm_nr) + data |= gr->sm[sm++].gpc << (j * 8); + else + data |= 0x1f << (j * 8); + } + nvkm_wr32(device, 0x4060a8 + (i * 4), data); + } } void @@ -1326,16 +1321,13 @@ gf100_grctx_generate_floorsweep(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; const struct gf100_grctx_func *func = gr->func->grctx; - int tpc, gpc, sm, i, j; + int gpc, sm, i, j; u32 data; - for (tpc = 0, sm = 0; tpc < gr->tpc_max; tpc++) { - for (gpc = 0; gpc < gr->gpc_nr; gpc++) { - if (tpc < gr->tpc_nr[gpc]) - func->sm_id(gr, gpc, tpc, sm++); - if (func->tpc_nr) - func->tpc_nr(gr, gpc); - } + for (sm = 0; sm < gr->sm_nr; sm++) { + func->sm_id(gr, gr->sm[sm].gpc, gr->sm[sm].tpc, sm); + if (func->tpc_nr) + func->tpc_nr(gr, gr->sm[sm].gpc); } for (gpc = 0, i = 0; i < 4; i++) { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c index 7107ec4297783..013d05a0f0f64 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c @@ -49,23 +49,13 @@ gm200_grctx_generate_smid_config(struct gf100_gr *gr) const u32 dist_nr = DIV_ROUND_UP(gr->tpc_total, 4); u32 dist[TPC_MAX / 4] = {}; u32 gpcs[GPC_MAX] = {}; - u8 tpcnr[GPC_MAX]; - int tpc, gpc, i; + u8 sm, i; - memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); - - /* won't result in the same distribution as the binary driver where - * some of the gpcs have more tpcs than others, but this shall do - * for the moment. the code for earlier gpus has this issue too. - */ - for (gpc = -1, i = 0; i < gr->tpc_total; i++) { - do { - gpc = (gpc + 1) % gr->gpc_nr; - } while(!tpcnr[gpc]); - tpc = gr->tpc_nr[gpc] - tpcnr[gpc]--; - - dist[i / 4] |= ((gpc << 4) | tpc) << ((i % 4) * 8); - gpcs[gpc] |= i << (tpc * 8); + for (sm = 0; sm < gr->sm_nr; sm++) { + const u8 gpc = gr->sm[sm].gpc; + const u8 tpc = gr->sm[sm].tpc; + dist[sm / 4] |= ((gpc << 4) | tpc) << ((sm % 4) * 8); + gpcs[gpc] |= sm << (tpc * 8); } for (i = 0; i < dist_nr; i++) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c index af6330c738723..2344fd8086f72 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c @@ -95,23 +95,13 @@ gp100_grctx_generate_smid_config(struct gf100_gr *gr) struct nvkm_device *device = gr->base.engine.subdev.device; const u32 dist_nr = DIV_ROUND_UP(gr->tpc_total, 4); u32 dist[TPC_MAX / 4] = {}, gpcs[16] = {}; - u8 tpcnr[GPC_MAX]; - int tpc, gpc, i; + u8 sm, i; - memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); - - /* won't result in the same distribution as the binary driver where - * some of the gpcs have more tpcs than others, but this shall do - * for the moment. the code for earlier gpus has this issue too. - */ - for (gpc = -1, i = 0; i < gr->tpc_total; i++) { - do { - gpc = (gpc + 1) % gr->gpc_nr; - } while(!tpcnr[gpc]); - tpc = gr->tpc_nr[gpc] - tpcnr[gpc]--; - - dist[i / 4] |= ((gpc << 4) | tpc) << ((i % 4) * 8); - gpcs[gpc + (gr->func->gpc_nr * (tpc / 4))] |= i << (tpc * 8); + for (sm = 0; sm < gr->sm_nr; sm++) { + const u8 gpc = gr->sm[sm].gpc; + const u8 tpc = gr->sm[sm].tpc; + dist[sm / 4] |= ((gpc << 4) | tpc) << ((sm % 4) * 8); + gpcs[gpc + (gr->func->gpc_nr * (tpc / 4))] |= sm << ((tpc % 4) * 8); } for (i = 0; i < dist_nr; i++) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index f6d884156b754..b2070c87c91ce 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1652,6 +1652,21 @@ gf100_gr_init_ctxctl(struct gf100_gr *gr) return ret; } +void +gf100_gr_oneinit_sm_id(struct gf100_gr *gr) +{ + int tpc, gpc; + for (tpc = 0; tpc < gr->tpc_max; tpc++) { + for (gpc = 0; gpc < gr->gpc_nr; gpc++) { + if (tpc < gr->tpc_nr[gpc]) { + gr->sm[gr->sm_nr].gpc = gpc; + gr->sm[gr->sm_nr].tpc = tpc; + gr->sm_nr++; + } + } + } +} + void gf100_gr_oneinit_tiles(struct gf100_gr *gr) { @@ -1769,6 +1784,7 @@ gf100_gr_oneinit(struct nvkm_gr *base) memset(gr->tile, 0xff, sizeof(gr->tile)); gr->func->oneinit_tiles(gr); + gr->func->oneinit_sm_id(gr); return 0; } @@ -2204,6 +2220,7 @@ gf100_gr_gpccs_ucode = { static const struct gf100_gr_func gf100_gr = { .oneinit_tiles = gf100_gr_oneinit_tiles, + .oneinit_sm_id = gf100_gr_oneinit_sm_id, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 53a173e023b4c..55dedd87fc380 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -110,6 +110,12 @@ struct gf100_gr { u8 screen_tile_row_offset; u8 tile[TPC_MAX]; + struct { + u8 gpc; + u8 tpc; + } sm[TPC_MAX]; + u8 sm_nr; + struct gf100_gr_data mmio_data[4]; struct gf100_gr_mmio mmio_list[4096/8]; u32 size; @@ -125,6 +131,7 @@ void *gf100_gr_dtor(struct nvkm_gr *); struct gf100_gr_func { void (*dtor)(struct gf100_gr *); void (*oneinit_tiles)(struct gf100_gr *); + void (*oneinit_sm_id)(struct gf100_gr *); int (*init)(struct gf100_gr *); void (*init_gpc_mmu)(struct gf100_gr *); void (*init_r405a14)(struct gf100_gr *); @@ -167,6 +174,7 @@ struct gf100_gr_func { int gf100_gr_rops(struct gf100_gr *); void gf100_gr_oneinit_tiles(struct gf100_gr *); +void gf100_gr_oneinit_sm_id(struct gf100_gr *); int gf100_gr_init(struct gf100_gr *); void gf100_gr_init_vsc_stream_master(struct gf100_gr *); void gf100_gr_init_zcull(struct gf100_gr *); @@ -195,6 +203,7 @@ void gm107_gr_init_400054(struct gf100_gr *); int gk20a_gr_init(struct gf100_gr *); void gm200_gr_oneinit_tiles(struct gf100_gr *); +void gm200_gr_oneinit_sm_id(struct gf100_gr *); int gm200_gr_rops(struct gf100_gr *); void gm200_gr_init_num_active_ltcs(struct gf100_gr *); void gm200_gr_init_ds_hww_esr_2(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c index 8b49b8fe6d2cf..1d8e16a571360 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c @@ -115,6 +115,7 @@ gf104_gr_pack_mmio[] = { static const struct gf100_gr_func gf104_gr = { .oneinit_tiles = gf100_gr_oneinit_tiles, + .oneinit_sm_id = gf100_gr_oneinit_sm_id, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c index 6432aeba0a148..a5a74df4edffd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c @@ -112,6 +112,7 @@ gf108_gr_init_r405a14(struct gf100_gr *gr) static const struct gf100_gr_func gf108_gr = { .oneinit_tiles = gf100_gr_oneinit_tiles, + .oneinit_sm_id = gf100_gr_oneinit_sm_id, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_r405a14 = gf108_gr_init_r405a14, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c index 4e007c945233c..45fada0990098 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c @@ -87,6 +87,7 @@ gf110_gr_pack_mmio[] = { static const struct gf100_gr_func gf110_gr = { .oneinit_tiles = gf100_gr_oneinit_tiles, + .oneinit_sm_id = gf100_gr_oneinit_sm_id, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c index d6831b41df39f..5ee167d0f5aa9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c @@ -151,6 +151,7 @@ gf117_gr_init_zcull(struct gf100_gr *gr) static const struct gf100_gr_func gf117_gr = { .oneinit_tiles = gf100_gr_oneinit_tiles, + .oneinit_sm_id = gf100_gr_oneinit_sm_id, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c index f0f10a4d8a26b..2096552fc537c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c @@ -178,6 +178,7 @@ gf119_gr_pack_mmio[] = { static const struct gf100_gr_func gf119_gr = { .oneinit_tiles = gf100_gr_oneinit_tiles, + .oneinit_sm_id = gf100_gr_oneinit_sm_id, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index d57fb5ff1fe94..cce250a85ba60 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -449,6 +449,7 @@ gk104_gr_gpccs_ucode = { static const struct gf100_gr_func gk104_gr = { .oneinit_tiles = gf100_gr_oneinit_tiles, + .oneinit_sm_id = gf100_gr_oneinit_sm_id, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index 41997ebda7193..558b497692abe 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -351,6 +351,7 @@ gk110_gr_init_419eb4(struct gf100_gr *gr) static const struct gf100_gr_func gk110_gr = { .oneinit_tiles = gf100_gr_oneinit_tiles, + .oneinit_sm_id = gf100_gr_oneinit_sm_id, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index b7a6479c6ec22..c8c48a26f4355 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c @@ -103,6 +103,7 @@ gk110b_gr_pack_mmio[] = { static const struct gf100_gr_func gk110b_gr = { .oneinit_tiles = gf100_gr_oneinit_tiles, + .oneinit_sm_id = gf100_gr_oneinit_sm_id, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c index 5f1e71abe5042..477a7dea79f5f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c @@ -162,6 +162,7 @@ gk208_gr_gpccs_ucode = { static const struct gf100_gr_func gk208_gr = { .oneinit_tiles = gf100_gr_oneinit_tiles, + .oneinit_sm_id = gf100_gr_oneinit_sm_id, .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c index ab4e5380eba2d..11a32fa01586c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c @@ -283,6 +283,7 @@ gk20a_gr_init(struct gf100_gr *gr) static const struct gf100_gr_func gk20a_gr = { .oneinit_tiles = gf100_gr_oneinit_tiles, + .oneinit_sm_id = gf100_gr_oneinit_sm_id, .init = gk20a_gr_init, .init_zcull = gf117_gr_init_zcull, .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index 98f74fe7007d0..a6937f8c3cfdf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -392,6 +392,7 @@ gm107_gr_gpccs_ucode = { static const struct gf100_gr_func gm107_gr = { .oneinit_tiles = gf100_gr_oneinit_tiles, + .oneinit_sm_id = gf100_gr_oneinit_sm_id, .init = gf100_gr_init, .init_gpc_mmu = gm107_gr_init_gpc_mmu, .init_bios = gm107_gr_init_bios, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index 3e017fdd23ed9..8966d2a7235ca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -92,6 +92,13 @@ gm200_gr_tile_map_2_8[] = { 0, 1, 1, 0, 0, 1, 1, 0, }; +void +gm200_gr_oneinit_sm_id(struct gf100_gr *gr) +{ + /*XXX: There's a different algorithm here I've not yet figured out. */ + gf100_gr_oneinit_sm_id(gr); +} + void gm200_gr_oneinit_tiles(struct gf100_gr *gr) { @@ -158,6 +165,7 @@ gm200_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device, static const struct gf100_gr_func gm200_gr = { .oneinit_tiles = gm200_gr_oneinit_tiles, + .oneinit_sm_id = gm200_gr_oneinit_sm_id, .init = gf100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_bios = gm107_gr_init_bios, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c index 29d3b9445cf63..afa1c6e322307 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c @@ -65,6 +65,7 @@ gm20b_gr_set_hww_esr_report_mask(struct gf100_gr *gr) static const struct gf100_gr_func gm20b_gr = { .oneinit_tiles = gm200_gr_oneinit_tiles, + .oneinit_sm_id = gm200_gr_oneinit_sm_id, .init = gk20a_gr_init, .init_zcull = gf117_gr_init_zcull, .init_gpc_mmu = gm20b_gr_init_gpc_mmu, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c index 70d0aa2c1076b..1d9d8760e13e0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c @@ -65,6 +65,7 @@ gp100_gr_init_rop_active_fbps(struct gf100_gr *gr) static const struct gf100_gr_func gp100_gr = { .oneinit_tiles = gm200_gr_oneinit_tiles, + .oneinit_sm_id = gm200_gr_oneinit_sm_id, .init = gf100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c index 71bfe2d8c3f61..2d9a2c3ec2613 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c @@ -43,6 +43,7 @@ gp102_gr_init_swdx_pes_mask(struct gf100_gr *gr) static const struct gf100_gr_func gp102_gr = { .oneinit_tiles = gm200_gr_oneinit_tiles, + .oneinit_sm_id = gm200_gr_oneinit_sm_id, .init = gf100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c index 234c970bb0dc9..e466ae460d3ce 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c @@ -27,6 +27,7 @@ static const struct gf100_gr_func gp104_gr = { .oneinit_tiles = gm200_gr_oneinit_tiles, + .oneinit_sm_id = gm200_gr_oneinit_sm_id, .init = gf100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c index 6c5724017c719..2fa046a1da608 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c @@ -29,6 +29,7 @@ static const struct gf100_gr_func gp107_gr = { .oneinit_tiles = gm200_gr_oneinit_tiles, + .oneinit_sm_id = gm200_gr_oneinit_sm_id, .init = gf100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c index aaaa2844ec201..0a01a306da2a6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c @@ -28,6 +28,7 @@ static const struct gf100_gr_func gp10b_gr = { .oneinit_tiles = gm200_gr_oneinit_tiles, + .oneinit_sm_id = gm200_gr_oneinit_sm_id, .init = gf100_gr_init, .init_gpc_mmu = gm200_gr_init_gpc_mmu, .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, From 6f0233329bacd8de54959e0c0b9b6c46bf5118b8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 092/165] drm/nouveau/gr/gf100-: swap bundle and pagepool Makes it easier to diff against RM traces. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index c2dcc01379c9e..4096e2d235272 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1381,8 +1381,8 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000); - grctx->bundle(info); grctx->pagepool(info); + grctx->bundle(info); grctx->attrib(info); if (grctx->patch_ltc) grctx->patch_ltc(info); From 191e323278dd7025ecd5fef02fbb984cfc91eebb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 093/165] drm/nouveau/gr/gf100-gm10x: update register lists There are differences on GM200 and newer too, but we can't fix them there as they come from firmware packages. A request has been made to NVIDIA to release updated firmware. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 13 ++++++++++--- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 12 ++++++++---- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c | 10 ++++++++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c | 8 +++----- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c | 10 ++++++++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c | 8 +++----- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c | 12 +++++++++--- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c | 10 ++++++++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c | 10 ++++++++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c | 10 ++++++++-- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 3 ++- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 7 +++++++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 9 ++++++--- 19 files changed, 96 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index 4096e2d235272..1ed63ed1a2835 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -850,12 +850,17 @@ gf100_grctx_init_gcc_0[] = { }; const struct gf100_gr_pack -gf100_grctx_pack_gpc[] = { +gf100_grctx_pack_gpc_0[] = { { gf100_grctx_init_gpc_unk_0 }, { gf100_grctx_init_prop_0 }, { gf100_grctx_init_gpc_unk_1 }, { gf100_grctx_init_setup_0 }, { gf100_grctx_init_zcull_0 }, + {} +}; + +const struct gf100_gr_pack +gf100_grctx_pack_gpc_1[] = { { gf100_grctx_init_crstr_0 }, { gf100_grctx_init_gpm_0 }, { gf100_grctx_init_gcc_0 }, @@ -1371,8 +1376,9 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) if (!gr->fuc_sw_ctx) { gf100_gr_mmio(gr, grctx->hub); - gf100_gr_mmio(gr, grctx->gpc); + gf100_gr_mmio(gr, grctx->gpc_0); gf100_gr_mmio(gr, grctx->zcull); + gf100_gr_mmio(gr, grctx->gpc_1); gf100_gr_mmio(gr, grctx->tpc); gf100_gr_mmio(gr, grctx->ppc); } else { @@ -1567,7 +1573,8 @@ gf100_grctx = { .main = gf100_grctx_generate_main, .unkn = gf100_grctx_generate_unkn, .hub = gf100_grctx_pack_hub, - .gpc = gf100_grctx_pack_gpc, + .gpc_0 = gf100_grctx_pack_gpc_0, + .gpc_1 = gf100_grctx_pack_gpc_1, .zcull = gf100_grctx_pack_zcull, .tpc = gf100_grctx_pack_tpc, .icmd = gf100_grctx_pack_icmd, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index be57ff0860229..1c06c675f09e9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -27,7 +27,8 @@ struct gf100_grctx_func { void (*unkn)(struct gf100_gr *); /* mmio context data */ const struct gf100_gr_pack *hub; - const struct gf100_gr_pack *gpc; + const struct gf100_gr_pack *gpc_0; + const struct gf100_gr_pack *gpc_1; const struct gf100_gr_pack *zcull; const struct gf100_gr_pack *tpc; const struct gf100_gr_pack *ppc; @@ -163,7 +164,8 @@ extern const struct gf100_gr_init gf100_grctx_init_memfmt_0[]; extern const struct gf100_gr_init gf100_grctx_init_rstr2d_0[]; extern const struct gf100_gr_init gf100_grctx_init_scc_0[]; -extern const struct gf100_gr_pack gf100_grctx_pack_gpc[]; +extern const struct gf100_gr_pack gf100_grctx_pack_gpc_0[]; +extern const struct gf100_gr_pack gf100_grctx_pack_gpc_1[]; extern const struct gf100_gr_init gf100_grctx_init_gpc_unk_0[]; extern const struct gf100_gr_init gf100_grctx_init_prop_0[]; extern const struct gf100_gr_init gf100_grctx_init_gpc_unk_1[]; @@ -212,6 +214,8 @@ extern const struct gf100_gr_init gf117_grctx_init_pe_0[]; extern const struct gf100_gr_init gf117_grctx_init_wwdx_0[]; +extern const struct gf100_gr_pack gf117_grctx_pack_gpc_1[]; + extern const struct gf100_gr_init gk104_grctx_init_memfmt_0[]; extern const struct gf100_gr_init gk104_grctx_init_ds_0[]; extern const struct gf100_gr_init gk104_grctx_init_scc_0[]; @@ -221,7 +225,6 @@ extern const struct gf100_gr_init gk104_grctx_init_gpm_0[]; extern const struct gf100_gr_init gk104_grctx_init_pes_0[]; extern const struct gf100_gr_pack gk104_grctx_pack_hub[]; -extern const struct gf100_gr_pack gk104_grctx_pack_gpc[]; extern const struct gf100_gr_pack gk104_grctx_pack_tpc[]; extern const struct gf100_gr_pack gk104_grctx_pack_ppc[]; extern const struct gf100_gr_pack gk104_grctx_pack_icmd[]; @@ -235,7 +238,8 @@ extern const struct gf100_gr_pack gk110_grctx_pack_hub[]; extern const struct gf100_gr_init gk110_grctx_init_pri_0[]; extern const struct gf100_gr_init gk110_grctx_init_cwd_0[]; -extern const struct gf100_gr_pack gk110_grctx_pack_gpc[]; +extern const struct gf100_gr_pack gk110_grctx_pack_gpc_0[]; +extern const struct gf100_gr_pack gk110_grctx_pack_gpc_1[]; extern const struct gf100_gr_init gk110_grctx_init_gpc_unk_2[]; extern const struct gf100_gr_init gk110_grctx_init_tex_0[]; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c index 7f3b9289a66bf..7a0564b6e3c71 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c @@ -84,7 +84,8 @@ gf104_grctx = { .main = gf100_grctx_generate_main, .unkn = gf100_grctx_generate_unkn, .hub = gf100_grctx_pack_hub, - .gpc = gf100_grctx_pack_gpc, + .gpc_0 = gf100_grctx_pack_gpc_0, + .gpc_1 = gf100_grctx_pack_gpc_1, .zcull = gf100_grctx_pack_zcull, .tpc = gf104_grctx_pack_tpc, .icmd = gf100_grctx_pack_icmd, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c index 369d64f867c7a..dda2c32e62324 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c @@ -667,12 +667,17 @@ gf108_grctx_init_gpm_0[] = { }; static const struct gf100_gr_pack -gf108_grctx_pack_gpc[] = { +gf108_grctx_pack_gpc_0[] = { { gf100_grctx_init_gpc_unk_0 }, { gf100_grctx_init_prop_0 }, { gf100_grctx_init_gpc_unk_1 }, { gf108_grctx_init_setup_0 }, { gf100_grctx_init_zcull_0 }, + {} +}; + +static const struct gf100_gr_pack +gf108_grctx_pack_gpc_1[] = { { gf100_grctx_init_crstr_0 }, { gf108_grctx_init_gpm_0 }, { gf100_grctx_init_gcc_0 }, @@ -780,7 +785,8 @@ gf108_grctx = { .main = gf100_grctx_generate_main, .unkn = gf108_grctx_generate_unkn, .hub = gf108_grctx_pack_hub, - .gpc = gf108_grctx_pack_gpc, + .gpc_0 = gf108_grctx_pack_gpc_0, + .gpc_1 = gf108_grctx_pack_gpc_1, .zcull = gf100_grctx_pack_zcull, .tpc = gf108_grctx_pack_tpc, .icmd = gf108_grctx_pack_icmd, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c index d59c2480f04d3..f5cca5e6a4f24 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c @@ -314,15 +314,12 @@ gf110_grctx_init_setup_0[] = { }; static const struct gf100_gr_pack -gf110_grctx_pack_gpc[] = { +gf110_grctx_pack_gpc_0[] = { { gf100_grctx_init_gpc_unk_0 }, { gf100_grctx_init_prop_0 }, { gf100_grctx_init_gpc_unk_1 }, { gf110_grctx_init_setup_0 }, { gf100_grctx_init_zcull_0 }, - { gf100_grctx_init_crstr_0 }, - { gf100_grctx_init_gpm_0 }, - { gf100_grctx_init_gcc_0 }, {} }; @@ -335,7 +332,8 @@ gf110_grctx = { .main = gf100_grctx_generate_main, .unkn = gf100_grctx_generate_unkn, .hub = gf100_grctx_pack_hub, - .gpc = gf110_grctx_pack_gpc, + .gpc_0 = gf110_grctx_pack_gpc_0, + .gpc_1 = gf100_grctx_pack_gpc_1, .zcull = gf100_grctx_pack_zcull, .tpc = gf100_grctx_pack_tpc, .icmd = gf110_grctx_pack_icmd, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c index bc4e86bbb9d47..276c282d19aa6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c @@ -84,12 +84,17 @@ gf117_grctx_init_setup_0[] = { }; static const struct gf100_gr_pack -gf117_grctx_pack_gpc[] = { +gf117_grctx_pack_gpc_0[] = { { gf100_grctx_init_gpc_unk_0 }, { gf119_grctx_init_prop_0 }, { gf119_grctx_init_gpc_unk_1 }, { gf117_grctx_init_setup_0 }, { gf100_grctx_init_zcull_0 }, + {} +}; + +const struct gf100_gr_pack +gf117_grctx_pack_gpc_1[] = { { gf119_grctx_init_crstr_0 }, { gf108_grctx_init_gpm_0 }, { gf100_grctx_init_gcc_0 }, @@ -278,7 +283,8 @@ gf117_grctx = { .main = gf100_grctx_generate_main, .unkn = gk104_grctx_generate_unkn, .hub = gf117_grctx_pack_hub, - .gpc = gf117_grctx_pack_gpc, + .gpc_0 = gf117_grctx_pack_gpc_0, + .gpc_1 = gf117_grctx_pack_gpc_1, .zcull = gf100_grctx_pack_zcull, .tpc = gf117_grctx_pack_tpc, .ppc = gf117_grctx_pack_ppc, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c index cc1a9354fecc6..0cfe46366af60 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c @@ -431,15 +431,12 @@ gf119_grctx_init_crstr_0[] = { }; static const struct gf100_gr_pack -gf119_grctx_pack_gpc[] = { +gf119_grctx_pack_gpc_0[] = { { gf100_grctx_init_gpc_unk_0 }, { gf119_grctx_init_prop_0 }, { gf119_grctx_init_gpc_unk_1 }, { gf119_grctx_init_setup_0 }, { gf100_grctx_init_zcull_0 }, - { gf119_grctx_init_crstr_0 }, - { gf108_grctx_init_gpm_0 }, - { gf100_grctx_init_gcc_0 }, {} }; @@ -503,7 +500,8 @@ gf119_grctx = { .main = gf100_grctx_generate_main, .unkn = gf108_grctx_generate_unkn, .hub = gf119_grctx_pack_hub, - .gpc = gf119_grctx_pack_gpc, + .gpc_0 = gf119_grctx_pack_gpc_0, + .gpc_1 = gf117_grctx_pack_gpc_1, .zcull = gf100_grctx_pack_zcull, .tpc = gf119_grctx_pack_tpc, .icmd = gf119_grctx_pack_icmd, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c index bdf2a1e6d3b6a..304e9d268bad4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c @@ -739,13 +739,18 @@ gk104_grctx_init_gpm_0[] = { {} }; -const struct gf100_gr_pack -gk104_grctx_pack_gpc[] = { +static const struct gf100_gr_pack +gk104_grctx_pack_gpc_0[] = { { gf100_grctx_init_gpc_unk_0 }, { gf119_grctx_init_prop_0 }, { gf119_grctx_init_gpc_unk_1 }, { gk104_grctx_init_setup_0 }, { gf100_grctx_init_zcull_0 }, + {} +}; + +static const struct gf100_gr_pack +gk104_grctx_pack_gpc_1[] = { { gf119_grctx_init_crstr_0 }, { gk104_grctx_init_gpm_0 }, { gf100_grctx_init_gcc_0 }, @@ -973,7 +978,8 @@ gk104_grctx = { .main = gf100_grctx_generate_main, .unkn = gk104_grctx_generate_unkn, .hub = gk104_grctx_pack_hub, - .gpc = gk104_grctx_pack_gpc, + .gpc_0 = gk104_grctx_pack_gpc_0, + .gpc_1 = gk104_grctx_pack_gpc_1, .zcull = gf100_grctx_pack_zcull, .tpc = gk104_grctx_pack_tpc, .ppc = gk104_grctx_pack_ppc, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c index 2ba35d727dc1d..86547cfc38dce 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c @@ -704,12 +704,17 @@ gk110_grctx_init_gpc_unk_2[] = { }; const struct gf100_gr_pack -gk110_grctx_pack_gpc[] = { +gk110_grctx_pack_gpc_0[] = { { gf100_grctx_init_gpc_unk_0 }, { gf119_grctx_init_prop_0 }, { gf119_grctx_init_gpc_unk_1 }, { gk110_grctx_init_setup_0 }, { gf100_grctx_init_zcull_0 }, + {} +}; + +const struct gf100_gr_pack +gk110_grctx_pack_gpc_1[] = { { gf119_grctx_init_crstr_0 }, { gk104_grctx_init_gpm_0 }, { gk110_grctx_init_gpc_unk_2 }, @@ -820,7 +825,8 @@ gk110_grctx = { .main = gf100_grctx_generate_main, .unkn = gk104_grctx_generate_unkn, .hub = gk110_grctx_pack_hub, - .gpc = gk110_grctx_pack_gpc, + .gpc_0 = gk110_grctx_pack_gpc_0, + .gpc_1 = gk110_grctx_pack_gpc_1, .zcull = gf100_grctx_pack_zcull, .tpc = gk110_grctx_pack_tpc, .ppc = gk110_grctx_pack_ppc, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c index 1112f8dc70e2c..ebb947bd1446b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c @@ -74,7 +74,8 @@ gk110b_grctx = { .main = gf100_grctx_generate_main, .unkn = gk104_grctx_generate_unkn, .hub = gk110_grctx_pack_hub, - .gpc = gk110_grctx_pack_gpc, + .gpc_0 = gk110_grctx_pack_gpc_0, + .gpc_1 = gk110_grctx_pack_gpc_1, .zcull = gf100_grctx_pack_zcull, .tpc = gk110b_grctx_pack_tpc, .ppc = gk110_grctx_pack_ppc, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c index 613c5cf8b3bf7..4d40512b5c998 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c @@ -443,12 +443,17 @@ gk208_grctx_init_gpm_0[] = { }; static const struct gf100_gr_pack -gk208_grctx_pack_gpc[] = { +gk208_grctx_pack_gpc_0[] = { { gf100_grctx_init_gpc_unk_0 }, { gk208_grctx_init_prop_0 }, { gk208_grctx_init_gpc_unk_1 }, { gk208_grctx_init_setup_0 }, { gf100_grctx_init_zcull_0 }, + {} +}; + +static const struct gf100_gr_pack +gk208_grctx_pack_gpc_1[] = { { gk208_grctx_init_crstr_0 }, { gk208_grctx_init_gpm_0 }, { gk110_grctx_init_gpc_unk_2 }, @@ -535,7 +540,8 @@ gk208_grctx = { .main = gf100_grctx_generate_main, .unkn = gk104_grctx_generate_unkn, .hub = gk208_grctx_pack_hub, - .gpc = gk208_grctx_pack_gpc, + .gpc_0 = gk208_grctx_pack_gpc_0, + .gpc_1 = gk208_grctx_pack_gpc_1, .zcull = gf100_grctx_pack_zcull, .tpc = gk208_grctx_pack_tpc, .ppc = gk208_grctx_pack_ppc, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c index 7816dcb7c9743..0b3964e6b36e2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c @@ -744,12 +744,17 @@ gm107_grctx_init_gpc_unk_2[] = { }; static const struct gf100_gr_pack -gm107_grctx_pack_gpc[] = { +gm107_grctx_pack_gpc_0[] = { { gm107_grctx_init_gpc_unk_0 }, { gk208_grctx_init_prop_0 }, { gm107_grctx_init_gpc_unk_1 }, { gm107_grctx_init_setup_0 }, { gf100_grctx_init_zcull_0 }, + {} +}; + +static const struct gf100_gr_pack +gm107_grctx_pack_gpc_1[] = { { gk208_grctx_init_crstr_0 }, { gk104_grctx_init_gpm_0 }, { gm107_grctx_init_gpc_unk_2 }, @@ -960,7 +965,8 @@ gm107_grctx = { .main = gf100_grctx_generate_main, .unkn = gk104_grctx_generate_unkn, .hub = gm107_grctx_pack_hub, - .gpc = gm107_grctx_pack_gpc, + .gpc_0 = gm107_grctx_pack_gpc_0, + .gpc_1 = gm107_grctx_pack_gpc_1, .zcull = gf100_grctx_pack_zcull, .tpc = gm107_grctx_pack_tpc, .ppc = gm107_grctx_pack_ppc, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index b2070c87c91ce..69418619dc79c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1612,7 +1612,8 @@ gf100_gr_init_ctxctl_int(struct gf100_gr *gr) /* load register lists */ gf100_gr_init_csdata(gr, grctx->hub, 0x409000, 0x000, 0x000000); - gf100_gr_init_csdata(gr, grctx->gpc, 0x41a000, 0x000, 0x418000); + gf100_gr_init_csdata(gr, grctx->gpc_0, 0x41a000, 0x000, 0x418000); + gf100_gr_init_csdata(gr, grctx->gpc_1, 0x41a000, 0x000, 0x418000); gf100_gr_init_csdata(gr, grctx->tpc, 0x41a000, 0x004, 0x419800); gf100_gr_init_csdata(gr, grctx->ppc, 0x41a000, 0x008, 0x41be00); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 55dedd87fc380..9e608dff28462 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -338,6 +338,7 @@ extern const struct gf100_gr_init gf117_gr_init_wwdx_0[]; extern const struct gf100_gr_init gf117_gr_init_cbm_0[]; extern const struct gf100_gr_init gk104_gr_init_main_0[]; +extern const struct gf100_gr_init gk104_gr_init_gpc_unk_2[]; extern const struct gf100_gr_init gk104_gr_init_tpccs_0[]; extern const struct gf100_gr_init gk104_gr_init_pe_0[]; extern const struct gf100_gr_init gk104_gr_init_be_0[]; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index cce250a85ba60..9abacb2183618 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -82,6 +82,12 @@ gk104_gr_init_gpc_unk_1[] = { {} }; +const struct gf100_gr_init +gk104_gr_init_gpc_unk_2[] = { + { 0x418884, 1, 0x04, 0x00000000 }, + {} +}; + const struct gf100_gr_init gk104_gr_init_tpccs_0[] = { { 0x419d0c, 1, 0x04, 0x00000000 }, @@ -160,6 +166,7 @@ gk104_gr_pack_mmio[] = { { gf119_gr_init_gpm_0 }, { gk104_gr_init_gpc_unk_1 }, { gf100_gr_init_gcc_0 }, + { gk104_gr_init_gpc_unk_2 }, { gk104_gr_init_tpccs_0 }, { gf119_gr_init_tex_0 }, { gk104_gr_init_pe_0 }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index 558b497692abe..dba70d50bb8e6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -143,6 +143,7 @@ gk110_gr_pack_mmio[] = { { gf119_gr_init_gpm_0 }, { gk110_gr_init_gpc_unk_1 }, { gf100_gr_init_gcc_0 }, + { gk104_gr_init_gpc_unk_2 }, { gk104_gr_init_tpccs_0 }, { gk110_gr_init_tex_0 }, { gk104_gr_init_pe_0 }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index c8c48a26f4355..48bc8d85dbb84 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c @@ -82,6 +82,7 @@ gk110b_gr_pack_mmio[] = { { gf119_gr_init_gpm_0 }, { gk110_gr_init_gpc_unk_1 }, { gf100_gr_init_gcc_0 }, + { gk104_gr_init_gpc_unk_2 }, { gk104_gr_init_tpccs_0 }, { gk110_gr_init_tex_0 }, { gk104_gr_init_pe_0 }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c index 477a7dea79f5f..7f45b122dcb0f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c @@ -121,6 +121,7 @@ gk208_gr_pack_mmio[] = { { gf119_gr_init_gpm_0 }, { gk110_gr_init_gpc_unk_1 }, { gf100_gr_init_gcc_0 }, + { gk104_gr_init_gpc_unk_2 }, { gk104_gr_init_tpccs_0 }, { gk208_gr_init_tex_0 }, { gk104_gr_init_pe_0 }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index a6937f8c3cfdf..f5411aff0e44f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -38,6 +38,10 @@ static const struct gf100_gr_init gm107_gr_init_main_0[] = { + { 0x40880c, 1, 0x04, 0x00000000 }, + { 0x408910, 1, 0x04, 0x00000000 }, + { 0x408984, 1, 0x04, 0x00000000 }, + { 0x41a8a0, 1, 0x04, 0x00000000 }, { 0x400080, 1, 0x04, 0x003003c2 }, { 0x400088, 1, 0x04, 0x0001bfe7 }, { 0x40008c, 1, 0x04, 0x00060000 }, @@ -212,14 +216,13 @@ gm107_gr_init_cbm_0[] = { static const struct gf100_gr_init gm107_gr_init_be_0[] = { { 0x408890, 1, 0x04, 0x000000ff }, - { 0x40880c, 1, 0x04, 0x00000000 }, { 0x408850, 1, 0x04, 0x00000004 }, { 0x408878, 1, 0x04, 0x00c81603 }, { 0x40887c, 1, 0x04, 0x80543432 }, { 0x408880, 1, 0x04, 0x0010581e }, { 0x408884, 1, 0x04, 0x00001205 }, { 0x408974, 1, 0x04, 0x000000ff }, - { 0x408910, 9, 0x04, 0x00000000 }, + { 0x408914, 8, 0x04, 0x00000000 }, { 0x408950, 1, 0x04, 0x00000000 }, { 0x408954, 1, 0x04, 0x0000ffff }, { 0x408958, 1, 0x04, 0x00000034 }, @@ -229,7 +232,6 @@ gm107_gr_init_be_0[] = { { 0x408968, 1, 0x04, 0x02808833 }, { 0x40896c, 1, 0x04, 0x01f02438 }, { 0x408970, 1, 0x04, 0x00012c00 }, - { 0x408984, 1, 0x04, 0x00000000 }, { 0x408988, 1, 0x04, 0x08040201 }, { 0x40898c, 1, 0x04, 0x80402010 }, {} @@ -262,6 +264,7 @@ gm107_gr_pack_mmio[] = { { gf100_gr_init_gpm_0 }, { gm107_gr_init_gpc_unk_1 }, { gf100_gr_init_gcc_0 }, + { gk104_gr_init_gpc_unk_2 }, { gm107_gr_init_tpccs_0 }, { gm107_gr_init_tex_0 }, { gm107_gr_init_pe_0 }, From 17f2d4df32104b327178771fb323391fbf53921c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 094/165] drm/nouveau/gr/gp100-: fix pagepool setup Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c index 2344fd8086f72..c51e3a27af144 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c @@ -36,7 +36,7 @@ gp100_grctx_generate_pagepool(struct gf100_grctx *info) const int s = 8; const int b = mmio_vram(info, grctx->pagepool_size, (1 << s), true); mmio_refn(info, 0x40800c, 0x00000000, s, b); - mmio_wr32(info, 0x408010, 0x80000000); + mmio_wr32(info, 0x408010, 0x8007d800); mmio_refn(info, 0x419004, 0x00000000, s, b); mmio_wr32(info, 0x419008, 0x00000000); } From 7a058a900ccb010c32ca1f29f6f9728a3654a519 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 095/165] drm/nouveau/gr/gp100-: fix attrib cb setup Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c | 17 +++++++------ .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c | 24 ++++++++++++------- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp104.c | 3 ++- .../gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 2 ++ .../gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 1 + 7 files changed, 32 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index 1c06c675f09e9..9ce3d00755735 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -49,6 +49,7 @@ struct gf100_grctx_func { u32 attrib_nr; u32 alpha_nr_max; u32 alpha_nr; + u32 gfxp_nr; /* other patch buffer stuff */ void (*patch_ltc)(struct gf100_grctx *); /* floorsweeping */ diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c index c51e3a27af144..0b3326262e123 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c @@ -48,14 +48,17 @@ gp100_grctx_generate_attrib(struct gf100_grctx *info) const struct gf100_grctx_func *grctx = gr->func->grctx; const u32 alpha = grctx->alpha_nr; const u32 attrib = grctx->attrib_nr; - const u32 pertpc = 0x20 * (grctx->attrib_nr_max + grctx->alpha_nr_max); - const u32 size = roundup(gr->tpc_total * pertpc, 0x80); const int s = 12; - const int b = mmio_vram(info, size, (1 << s), false); const int max_batches = 0xffff; + u32 size = grctx->alpha_nr_max * gr->tpc_total; u32 ao = 0; - u32 bo = ao + grctx->alpha_nr_max * gr->tpc_total; - int gpc, ppc, n = 0; + u32 bo = ao + size; + int gpc, ppc, b, n = 0; + + for (gpc = 0; gpc < gr->gpc_nr; gpc++) + size += grctx->attrib_nr_max * gr->ppc_nr[gpc] * gr->ppc_tpc_max; + size = ((size * 0x20) + 128) & ~127; + b = mmio_vram(info, size, (1 << s), false); mmio_refn(info, 0x418810, 0x80000000, s, b); mmio_refn(info, 0x419848, 0x10000000, s, b); @@ -69,7 +72,7 @@ gp100_grctx_generate_attrib(struct gf100_grctx *info) for (gpc = 0; gpc < gr->gpc_nr; gpc++) { for (ppc = 0; ppc < gr->ppc_nr[gpc]; ppc++, n++) { const u32 as = alpha * gr->ppc_tpc_nr[gpc][ppc]; - const u32 bs = attrib * gr->ppc_tpc_nr[gpc][ppc]; + const u32 bs = attrib * gr->ppc_tpc_max; const u32 u = 0x418ea0 + (n * 0x04); const u32 o = PPC_UNIT(gpc, ppc, 0); if (!(gr->ppc_mask[gpc] & (1 << ppc))) @@ -77,7 +80,7 @@ gp100_grctx_generate_attrib(struct gf100_grctx *info) mmio_wr32(info, o + 0xc0, bs); mmio_wr32(info, o + 0xf4, bo); mmio_wr32(info, o + 0xf0, bs); - bo += grctx->attrib_nr_max * gr->ppc_tpc_nr[gpc][ppc]; + bo += grctx->attrib_nr_max * gr->ppc_tpc_max; mmio_wr32(info, o + 0xe4, as); mmio_wr32(info, o + 0xf8, ao); ao += grctx->alpha_nr_max * gr->ppc_tpc_nr[gpc][ppc]; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c index 8a438c2efc3e6..daee17bf7d0df 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c @@ -43,14 +43,18 @@ gp102_grctx_generate_attrib(struct gf100_grctx *info) const struct gf100_grctx_func *grctx = gr->func->grctx; const u32 alpha = grctx->alpha_nr; const u32 attrib = grctx->attrib_nr; - const u32 pertpc = 0x20 * (grctx->attrib_nr_max + grctx->alpha_nr_max); - const u32 size = roundup(gr->tpc_total * pertpc, 0x80); + const u32 gfxp = grctx->gfxp_nr; const int s = 12; - const int b = mmio_vram(info, size, (1 << s), false); const int max_batches = 0xffff; + u32 size = grctx->alpha_nr_max * gr->tpc_total; u32 ao = 0; - u32 bo = ao + grctx->alpha_nr_max * gr->tpc_total; - int gpc, ppc, n = 0; + u32 bo = ao + size; + int gpc, ppc, b, n = 0; + + for (gpc = 0; gpc < gr->gpc_nr; gpc++) + size += grctx->gfxp_nr * gr->ppc_nr[gpc] * gr->ppc_tpc_max; + size = ((size * 0x20) + 128) & ~127; + b = mmio_vram(info, size, (1 << s), false); mmio_refn(info, 0x418810, 0x80000000, s, b); mmio_refn(info, 0x419848, 0x10000000, s, b); @@ -64,17 +68,18 @@ gp102_grctx_generate_attrib(struct gf100_grctx *info) for (gpc = 0; gpc < gr->gpc_nr; gpc++) { for (ppc = 0; ppc < gr->ppc_nr[gpc]; ppc++, n++) { const u32 as = alpha * gr->ppc_tpc_nr[gpc][ppc]; - const u32 bs = attrib * gr->ppc_tpc_nr[gpc][ppc]; + const u32 bs = attrib * gr->ppc_tpc_max; + const u32 gs = gfxp * gr->ppc_tpc_max; const u32 u = 0x418ea0 + (n * 0x04); const u32 o = PPC_UNIT(gpc, ppc, 0); const u32 p = GPC_UNIT(gpc, 0xc44 + (ppc * 4)); if (!(gr->ppc_mask[gpc] & (1 << ppc))) continue; - mmio_wr32(info, o + 0xc0, bs); + mmio_wr32(info, o + 0xc0, gs); mmio_wr32(info, p, bs); mmio_wr32(info, o + 0xf4, bo); mmio_wr32(info, o + 0xf0, bs); - bo += grctx->attrib_nr_max * gr->ppc_tpc_nr[gpc][ppc]; + bo += gs; mmio_wr32(info, o + 0xe4, as); mmio_wr32(info, o + 0xf8, ao); ao += grctx->alpha_nr_max * gr->ppc_tpc_nr[gpc][ppc]; @@ -97,10 +102,11 @@ gp102_grctx = { .pagepool = gp100_grctx_generate_pagepool, .pagepool_size = 0x20000, .attrib = gp102_grctx_generate_attrib, - .attrib_nr_max = 0x5d4, + .attrib_nr_max = 0x4b0, .attrib_nr = 0x320, .alpha_nr_max = 0xc00, .alpha_nr = 0x800, + .gfxp_nr = 0xba8, .sm_id = gm107_grctx_generate_sm_id, .rop_mapping = gf117_grctx_generate_rop_mapping, .dist_skip_table = gm200_grctx_generate_dist_skip_table, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp104.c index 5f799c7369bbc..3b85e3d326b25 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp104.c @@ -32,10 +32,11 @@ gp104_grctx = { .pagepool = gp100_grctx_generate_pagepool, .pagepool_size = 0x20000, .attrib = gp102_grctx_generate_attrib, - .attrib_nr_max = 0x5d4, + .attrib_nr_max = 0x4b0, .attrib_nr = 0x320, .alpha_nr_max = 0xc00, .alpha_nr = 0x800, + .gfxp_nr = 0xba8, .sm_id = gm107_grctx_generate_sm_id, .rop_mapping = gf117_grctx_generate_rop_mapping, .dist_skip_table = gm200_grctx_generate_dist_skip_table, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c index a69e824676c9d..5060c5ee5ce04 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c @@ -44,6 +44,7 @@ gp107_grctx = { .attrib_nr = 0x540, .alpha_nr_max = 0xc00, .alpha_nr = 0x800, + .gfxp_nr = 0xe94, .sm_id = gm107_grctx_generate_sm_id, .rop_mapping = gf117_grctx_generate_rop_mapping, .dist_skip_table = gm200_grctx_generate_dist_skip_table, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 69418619dc79c..084a5d1dcf9c2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1780,6 +1780,8 @@ gf100_gr_oneinit(struct nvkm_gr *base) if (gr->ppc_tpc_min == 0 || gr->ppc_tpc_min > gr->ppc_tpc_nr[i][j]) gr->ppc_tpc_min = gr->ppc_tpc_nr[i][j]; + if (gr->ppc_tpc_max < gr->ppc_tpc_nr[i][j]) + gr->ppc_tpc_max = gr->ppc_tpc_nr[i][j]; } } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 9e608dff28462..390bcc16f91f6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -106,6 +106,7 @@ struct gf100_gr { u8 ppc_tpc_mask[GPC_MAX][4]; u8 ppc_tpc_nr[GPC_MAX][4]; u8 ppc_tpc_min; + u8 ppc_tpc_max; u8 screen_tile_row_offset; u8 tile[TPC_MAX]; From e9d03335f604a1123b8de3103ce8e06db4ad777a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 096/165] drm/nouveau/gr/gp100-: use correct registers for zbc colour/depth setup These were missed the first time around due to the driver version I traced using the older registers still. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 37 +++++++++++------- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 10 +++++ .../gpu/drm/nouveau/nvkm/engine/gr/gf104.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf108.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf110.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf117.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gf119.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk104.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk208.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gk20a.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gm107.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gm200.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gm20b.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp100.c | 39 +++++++++++++++++++ .../gpu/drm/nouveau/nvkm/engine/gr/gp102.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp104.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp107.c | 1 + .../gpu/drm/nouveau/nvkm/engine/gr/gp10b.c | 1 + 20 files changed, 88 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 084a5d1dcf9c2..0cffafb0130f5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -92,7 +92,7 @@ gf100_gr_zbc_color_get(struct gf100_gr *gr, int format, memcpy(gr->zbc_color[zbc].l2, l2, sizeof(gr->zbc_color[zbc].l2)); gr->zbc_color[zbc].format = format; nvkm_ltc_zbc_color_get(ltc, zbc, l2); - gf100_gr_zbc_clear_color(gr, zbc); + gr->func->zbc->clear_color(gr, zbc); return zbc; } @@ -137,10 +137,16 @@ gf100_gr_zbc_depth_get(struct gf100_gr *gr, int format, gr->zbc_depth[zbc].ds = ds; gr->zbc_depth[zbc].l2 = l2; nvkm_ltc_zbc_depth_get(ltc, zbc, l2); - gf100_gr_zbc_clear_depth(gr, zbc); + gr->func->zbc->clear_depth(gr, zbc); return zbc; } +const struct gf100_gr_func_zbc +gf100_gr_zbc = { + .clear_color = gf100_gr_zbc_clear_color, + .clear_depth = gf100_gr_zbc_clear_depth, +}; + /******************************************************************************* * Graphics object classes ******************************************************************************/ @@ -744,21 +750,21 @@ gf100_gr_zbc_init(struct gf100_gr *gr) const u32 f32_1[] = { 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000 }; struct nvkm_ltc *ltc = gr->base.engine.subdev.device->ltc; - int index; + int index, c = ltc->zbc_min, d = ltc->zbc_min; if (!gr->zbc_color[0].format) { - gf100_gr_zbc_color_get(gr, 1, & zero[0], &zero[4]); - gf100_gr_zbc_color_get(gr, 2, & one[0], &one[4]); - gf100_gr_zbc_color_get(gr, 4, &f32_0[0], &f32_0[4]); - gf100_gr_zbc_color_get(gr, 4, &f32_1[0], &f32_1[4]); - gf100_gr_zbc_depth_get(gr, 1, 0x00000000, 0x00000000); - gf100_gr_zbc_depth_get(gr, 1, 0x3f800000, 0x3f800000); - } - - for (index = ltc->zbc_min; index <= ltc->zbc_max; index++) - gf100_gr_zbc_clear_color(gr, index); - for (index = ltc->zbc_min; index <= ltc->zbc_max; index++) - gf100_gr_zbc_clear_depth(gr, index); + gf100_gr_zbc_color_get(gr, 1, & zero[0], &zero[4]); c++; + gf100_gr_zbc_color_get(gr, 2, & one[0], &one[4]); c++; + gf100_gr_zbc_color_get(gr, 4, &f32_0[0], &f32_0[4]); c++; + gf100_gr_zbc_color_get(gr, 4, &f32_1[0], &f32_1[4]); c++; + gf100_gr_zbc_depth_get(gr, 1, 0x00000000, 0x00000000); d++; + gf100_gr_zbc_depth_get(gr, 1, 0x3f800000, 0x3f800000); d++; + } + + for (index = c; index <= ltc->zbc_max; index++) + gr->func->zbc->clear_color(gr, index); + for (index = d; index <= ltc->zbc_max; index++) + gr->func->zbc->clear_depth(gr, index); } /** @@ -2242,6 +2248,7 @@ gf100_gr = { .gpccs.ucode = &gf100_gr_gpccs_ucode, .rops = gf100_gr_rops, .grctx = &gf100_grctx, + .zbc = &gf100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_MEMORY_TO_MEMORY_FORMAT_A }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 390bcc16f91f6..d82951ab5ef1b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -129,6 +129,11 @@ int gf100_gr_new_(const struct gf100_gr_func *, struct nvkm_device *, int, struct nvkm_gr **); void *gf100_gr_dtor(struct nvkm_gr *); +struct gf100_gr_func_zbc { + void (*clear_color)(struct gf100_gr *, int zbc); + void (*clear_depth)(struct gf100_gr *, int zbc); +}; + struct gf100_gr_func { void (*dtor)(struct gf100_gr *); void (*oneinit_tiles)(struct gf100_gr *); @@ -170,6 +175,7 @@ struct gf100_gr_func { int ppc_nr; const struct gf100_grctx_func *grctx; const struct nvkm_therm_clkgate_pack *clkgate_pack; + const struct gf100_gr_func_zbc *zbc; struct nvkm_sclass sclass[]; }; @@ -187,6 +193,7 @@ void gf100_gr_init_419eb4(struct gf100_gr *); void gf100_gr_init_tex_hww_esr(struct gf100_gr *, int, int); void gf100_gr_init_shader_exceptions(struct gf100_gr *, int, int); void gf100_gr_init_400054(struct gf100_gr *); +extern const struct gf100_gr_func_zbc gf100_gr_zbc; void gf117_gr_init_zcull(struct gf100_gr *); @@ -212,6 +219,9 @@ void gm200_gr_init_ds_hww_esr_2(struct gf100_gr *); void gp100_gr_init_rop_active_fbps(struct gf100_gr *); void gp100_gr_init_fecs_exceptions(struct gf100_gr *); void gp100_gr_init_shader_exceptions(struct gf100_gr *, int, int); +extern const struct gf100_gr_func_zbc gp100_gr_zbc; +void gp100_gr_zbc_clear_color(struct gf100_gr *, int); +void gp100_gr_zbc_clear_depth(struct gf100_gr *, int); void gp102_gr_init_swdx_pes_mask(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c index 1d8e16a571360..42c2fd9fc04e6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c @@ -134,6 +134,7 @@ gf104_gr = { .gpccs.ucode = &gf100_gr_gpccs_ucode, .rops = gf100_gr_rops, .grctx = &gf104_grctx, + .zbc = &gf100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_MEMORY_TO_MEMORY_FORMAT_A }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c index a5a74df4edffd..4731a460adc7b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c @@ -132,6 +132,7 @@ gf108_gr = { .gpccs.ucode = &gf100_gr_gpccs_ucode, .rops = gf100_gr_rops, .grctx = &gf108_grctx, + .zbc = &gf100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_MEMORY_TO_MEMORY_FORMAT_A }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c index 45fada0990098..cdf759c8cd7fb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c @@ -106,6 +106,7 @@ gf110_gr = { .gpccs.ucode = &gf100_gr_gpccs_ucode, .rops = gf100_gr_rops, .grctx = &gf110_grctx, + .zbc = &gf100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_MEMORY_TO_MEMORY_FORMAT_A }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c index 5ee167d0f5aa9..a4158f84c6499 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c @@ -171,6 +171,7 @@ gf117_gr = { .rops = gf100_gr_rops, .ppc_nr = 1, .grctx = &gf117_grctx, + .zbc = &gf100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_MEMORY_TO_MEMORY_FORMAT_A }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c index 2096552fc537c..4197844870b37 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c @@ -197,6 +197,7 @@ gf119_gr = { .gpccs.ucode = &gf100_gr_gpccs_ucode, .rops = gf100_gr_rops, .grctx = &gf119_grctx, + .zbc = &gf100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, FERMI_MEMORY_TO_MEMORY_FORMAT_A }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index 9abacb2183618..477fee3e37153 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -479,6 +479,7 @@ gk104_gr = { .ppc_nr = 1, .grctx = &gk104_grctx, .clkgate_pack = gk104_clkgate_pack, + .zbc = &gf100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, KEPLER_INLINE_TO_MEMORY_A }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index dba70d50bb8e6..7cd628c84e075 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -375,6 +375,7 @@ gk110_gr = { .ppc_nr = 2, .grctx = &gk110_grctx, .clkgate_pack = gk110_clkgate_pack, + .zbc = &gf100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index 48bc8d85dbb84..a38faa2156352 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c @@ -126,6 +126,7 @@ gk110b_gr = { .rops = gf100_gr_rops, .ppc_nr = 2, .grctx = &gk110b_grctx, + .zbc = &gf100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c index 7f45b122dcb0f..58456660e603d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c @@ -184,6 +184,7 @@ gk208_gr = { .rops = gf100_gr_rops, .ppc_nr = 1, .grctx = &gk208_grctx, + .zbc = &gf100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c index 11a32fa01586c..500cb08dd6080 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c @@ -292,6 +292,7 @@ gk20a_gr = { .rops = gf100_gr_rops, .ppc_nr = 1, .grctx = &gk20a_grctx, + .zbc = &gf100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, KEPLER_INLINE_TO_MEMORY_A }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index f5411aff0e44f..92e31d3972075 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -419,6 +419,7 @@ gm107_gr = { .rops = gf100_gr_rops, .ppc_nr = 2, .grctx = &gm107_grctx, + .zbc = &gf100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index 8966d2a7235ca..eff30662b9841 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -187,6 +187,7 @@ gm200_gr = { .tpc_nr = 4, .ppc_nr = 2, .grctx = &gm200_grctx, + .zbc = &gf100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c index afa1c6e322307..a667770ce3cbe 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c @@ -75,6 +75,7 @@ gm20b_gr = { .rops = gm200_gr_rops, .ppc_nr = 1, .grctx = &gm20b_grctx, + .zbc = &gf100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c index 1d9d8760e13e0..ef16fee613278 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c @@ -29,6 +29,44 @@ /******************************************************************************* * PGRAPH engine/subdev functions ******************************************************************************/ +void +gp100_gr_zbc_clear_color(struct gf100_gr *gr, int zbc) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + const int znum = zbc - 1; + const u32 zoff = znum * 4; + + if (gr->zbc_color[zbc].format) { + nvkm_wr32(device, 0x418010 + zoff, gr->zbc_color[zbc].ds[0]); + nvkm_wr32(device, 0x41804c + zoff, gr->zbc_color[zbc].ds[1]); + nvkm_wr32(device, 0x418088 + zoff, gr->zbc_color[zbc].ds[2]); + nvkm_wr32(device, 0x4180c4 + zoff, gr->zbc_color[zbc].ds[3]); + } + + nvkm_mask(device, 0x418100 + ((znum / 4) * 4), + 0x0000007f << ((znum % 4) * 7), + gr->zbc_color[zbc].format << ((znum % 4) * 7)); +} + +void +gp100_gr_zbc_clear_depth(struct gf100_gr *gr, int zbc) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + const int znum = zbc - 1; + const u32 zoff = znum * 4; + + if (gr->zbc_depth[zbc].format) + nvkm_wr32(device, 0x418110 + zoff, gr->zbc_depth[zbc].ds); + nvkm_mask(device, 0x41814c + ((znum / 4) * 4), + 0x0000007f << ((znum % 4) * 7), + gr->zbc_depth[zbc].format << ((znum % 4) * 7)); +} + +const struct gf100_gr_func_zbc +gp100_gr_zbc = { + .clear_color = gp100_gr_zbc_clear_color, + .clear_depth = gp100_gr_zbc_clear_depth, +}; void gp100_gr_init_shader_exceptions(struct gf100_gr *gr, int gpc, int tpc) @@ -87,6 +125,7 @@ gp100_gr = { .tpc_nr = 5, .ppc_nr = 2, .grctx = &gp100_grctx, + .zbc = &gp100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c index 2d9a2c3ec2613..8fc95a015e13b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c @@ -65,6 +65,7 @@ gp102_gr = { .tpc_nr = 5, .ppc_nr = 3, .grctx = &gp102_grctx, + .zbc = &gp100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c index e466ae460d3ce..56f92c7235049 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c @@ -49,6 +49,7 @@ gp104_gr = { .tpc_nr = 5, .ppc_nr = 3, .grctx = &gp104_grctx, + .zbc = &gp100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c index 2fa046a1da608..4bb0340e3fdac 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c @@ -51,6 +51,7 @@ gp107_gr = { .tpc_nr = 3, .ppc_nr = 1, .grctx = &gp107_grctx, + .zbc = &gp100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c index 0a01a306da2a6..b2a39ad2fa445 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c @@ -49,6 +49,7 @@ gp10b_gr = { .tpc_nr = 2, .ppc_nr = 1, .grctx = &gp102_grctx, + .zbc = &gp100_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, From 4b2c71edf0d7832ef4d2fe5b17402d1130b415dc Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 097/165] drm/nouveau/gr/gp102-: setup stencil zbc Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/include/nvkm/subdev/ltc.h | 3 + .../gpu/drm/nouveau/nvkm/engine/device/base.c | 12 ++-- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 12 +++- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 12 +++- .../gpu/drm/nouveau/nvkm/engine/gr/gp100.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/gp102.c | 58 ++++++++++++++++++- .../gpu/drm/nouveau/nvkm/engine/gr/gp104.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/gp107.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/gr/gp10b.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/ltc/base.c | 10 ++++ .../gpu/drm/nouveau/nvkm/subdev/ltc/gp100.c | 6 +- .../gpu/drm/nouveau/nvkm/subdev/ltc/gp102.c | 51 ++++++++++++++++ .../gpu/drm/nouveau/nvkm/subdev/ltc/priv.h | 5 ++ 14 files changed, 162 insertions(+), 16 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp102.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h index 95b611554d535..9db5f8293198a 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h @@ -21,12 +21,14 @@ struct nvkm_ltc { int zbc_max; u32 zbc_color[NVKM_LTC_MAX_ZBC_CNT][4]; u32 zbc_depth[NVKM_LTC_MAX_ZBC_CNT]; + u32 zbc_stencil[NVKM_LTC_MAX_ZBC_CNT]; }; void nvkm_ltc_tags_clear(struct nvkm_device *, u32 first, u32 count); int nvkm_ltc_zbc_color_get(struct nvkm_ltc *, int index, const u32[4]); int nvkm_ltc_zbc_depth_get(struct nvkm_ltc *, int index, const u32); +int nvkm_ltc_zbc_stencil_get(struct nvkm_ltc *, int index, const u32); void nvkm_ltc_invalidate(struct nvkm_ltc *); void nvkm_ltc_flush(struct nvkm_ltc *); @@ -37,4 +39,5 @@ int gk20a_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **); int gm107_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **); int gm200_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **); int gp100_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **); +int gp102_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 16e8090082ab3..5c79c795acaa5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2204,7 +2204,7 @@ nv132_chipset = { .i2c = gm200_i2c_new, .ibus = gm200_ibus_new, .imem = nv50_instmem_new, - .ltc = gp100_ltc_new, + .ltc = gp102_ltc_new, .mc = gp100_mc_new, .mmu = gp100_mmu_new, .therm = gp100_therm_new, @@ -2240,7 +2240,7 @@ nv134_chipset = { .i2c = gm200_i2c_new, .ibus = gm200_ibus_new, .imem = nv50_instmem_new, - .ltc = gp100_ltc_new, + .ltc = gp102_ltc_new, .mc = gp100_mc_new, .mmu = gp100_mmu_new, .therm = gp100_therm_new, @@ -2276,7 +2276,7 @@ nv136_chipset = { .i2c = gm200_i2c_new, .ibus = gm200_ibus_new, .imem = nv50_instmem_new, - .ltc = gp100_ltc_new, + .ltc = gp102_ltc_new, .mc = gp100_mc_new, .mmu = gp100_mmu_new, .therm = gp100_therm_new, @@ -2312,7 +2312,7 @@ nv137_chipset = { .i2c = gm200_i2c_new, .ibus = gm200_ibus_new, .imem = nv50_instmem_new, - .ltc = gp100_ltc_new, + .ltc = gp102_ltc_new, .mc = gp100_mc_new, .mmu = gp100_mmu_new, .therm = gp100_therm_new, @@ -2348,7 +2348,7 @@ nv138_chipset = { .i2c = gm200_i2c_new, .ibus = gm200_ibus_new, .imem = nv50_instmem_new, - .ltc = gp100_ltc_new, + .ltc = gp102_ltc_new, .mc = gp100_mc_new, .mmu = gp100_mmu_new, .therm = gp100_therm_new, @@ -2380,7 +2380,7 @@ nv13b_chipset = { .fuse = gm107_fuse_new, .ibus = gp10b_ibus_new, .imem = gk20a_instmem_new, - .ltc = gp100_ltc_new, + .ltc = gp102_ltc_new, .mc = gp10b_mc_new, .mmu = gp10b_mmu_new, .secboot = gp10b_secboot_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 0cffafb0130f5..86ae5c706aa07 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -750,7 +750,7 @@ gf100_gr_zbc_init(struct gf100_gr *gr) const u32 f32_1[] = { 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000 }; struct nvkm_ltc *ltc = gr->base.engine.subdev.device->ltc; - int index, c = ltc->zbc_min, d = ltc->zbc_min; + int index, c = ltc->zbc_min, d = ltc->zbc_min, s = ltc->zbc_min; if (!gr->zbc_color[0].format) { gf100_gr_zbc_color_get(gr, 1, & zero[0], &zero[4]); c++; @@ -759,12 +759,22 @@ gf100_gr_zbc_init(struct gf100_gr *gr) gf100_gr_zbc_color_get(gr, 4, &f32_1[0], &f32_1[4]); c++; gf100_gr_zbc_depth_get(gr, 1, 0x00000000, 0x00000000); d++; gf100_gr_zbc_depth_get(gr, 1, 0x3f800000, 0x3f800000); d++; + if (gr->func->zbc->stencil_get) { + gr->func->zbc->stencil_get(gr, 1, 0x00, 0x00); s++; + gr->func->zbc->stencil_get(gr, 1, 0x01, 0x01); s++; + gr->func->zbc->stencil_get(gr, 1, 0xff, 0xff); s++; + } } for (index = c; index <= ltc->zbc_max; index++) gr->func->zbc->clear_color(gr, index); for (index = d; index <= ltc->zbc_max; index++) gr->func->zbc->clear_depth(gr, index); + + if (gr->func->zbc->clear_stencil) { + for (index = s; index <= ltc->zbc_max; index++) + gr->func->zbc->clear_stencil(gr, index); + } } /** diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index d82951ab5ef1b..edf6edabf6dfb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -72,6 +72,12 @@ struct gf100_gr_zbc_depth { u32 l2; }; +struct gf100_gr_zbc_stencil { + u32 format; + u32 ds; + u32 l2; +}; + struct gf100_gr { const struct gf100_gr_func *func; struct nvkm_gr base; @@ -95,6 +101,7 @@ struct gf100_gr { struct gf100_gr_zbc_color zbc_color[NVKM_LTC_MAX_ZBC_CNT]; struct gf100_gr_zbc_depth zbc_depth[NVKM_LTC_MAX_ZBC_CNT]; + struct gf100_gr_zbc_stencil zbc_stencil[NVKM_LTC_MAX_ZBC_CNT]; u8 rop_nr; u8 gpc_nr; @@ -132,6 +139,9 @@ void *gf100_gr_dtor(struct nvkm_gr *); struct gf100_gr_func_zbc { void (*clear_color)(struct gf100_gr *, int zbc); void (*clear_depth)(struct gf100_gr *, int zbc); + int (*stencil_get)(struct gf100_gr *, int format, + const u32 ds, const u32 l2); + void (*clear_stencil)(struct gf100_gr *, int zbc); }; struct gf100_gr_func { @@ -219,11 +229,11 @@ void gm200_gr_init_ds_hww_esr_2(struct gf100_gr *); void gp100_gr_init_rop_active_fbps(struct gf100_gr *); void gp100_gr_init_fecs_exceptions(struct gf100_gr *); void gp100_gr_init_shader_exceptions(struct gf100_gr *, int, int); -extern const struct gf100_gr_func_zbc gp100_gr_zbc; void gp100_gr_zbc_clear_color(struct gf100_gr *, int); void gp100_gr_zbc_clear_depth(struct gf100_gr *, int); void gp102_gr_init_swdx_pes_mask(struct gf100_gr *); +extern const struct gf100_gr_func_zbc gp102_gr_zbc; #define gf100_gr_chan(p) container_of((p), struct gf100_gr_chan, object) #include diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c index ef16fee613278..9d0521ce309a2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp100.c @@ -62,7 +62,7 @@ gp100_gr_zbc_clear_depth(struct gf100_gr *gr, int zbc) gr->zbc_depth[zbc].format << ((znum % 4) * 7)); } -const struct gf100_gr_func_zbc +static const struct gf100_gr_func_zbc gp100_gr_zbc = { .clear_color = gp100_gr_zbc_clear_color, .clear_depth = gp100_gr_zbc_clear_depth, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c index 8fc95a015e13b..37f7d739bf80d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp102.c @@ -26,6 +26,62 @@ #include +static void +gp102_gr_zbc_clear_stencil(struct gf100_gr *gr, int zbc) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + const int znum = zbc - 1; + const u32 zoff = znum * 4; + + if (gr->zbc_stencil[zbc].format) + nvkm_wr32(device, 0x41815c + zoff, gr->zbc_stencil[zbc].ds); + nvkm_mask(device, 0x418198 + ((znum / 4) * 4), + 0x0000007f << ((znum % 4) * 7), + gr->zbc_stencil[zbc].format << ((znum % 4) * 7)); +} + +static int +gp102_gr_zbc_stencil_get(struct gf100_gr *gr, int format, + const u32 ds, const u32 l2) +{ + struct nvkm_ltc *ltc = gr->base.engine.subdev.device->ltc; + int zbc = -ENOSPC, i; + + for (i = ltc->zbc_min; i <= ltc->zbc_max; i++) { + if (gr->zbc_stencil[i].format) { + if (gr->zbc_stencil[i].format != format) + continue; + if (gr->zbc_stencil[i].ds != ds) + continue; + if (gr->zbc_stencil[i].l2 != l2) { + WARN_ON(1); + return -EINVAL; + } + return i; + } else { + zbc = (zbc < 0) ? i : zbc; + } + } + + if (zbc < 0) + return zbc; + + gr->zbc_stencil[zbc].format = format; + gr->zbc_stencil[zbc].ds = ds; + gr->zbc_stencil[zbc].l2 = l2; + nvkm_ltc_zbc_stencil_get(ltc, zbc, l2); + gr->func->zbc->clear_stencil(gr, zbc); + return zbc; +} + +const struct gf100_gr_func_zbc +gp102_gr_zbc = { + .clear_color = gp100_gr_zbc_clear_color, + .clear_depth = gp100_gr_zbc_clear_depth, + .stencil_get = gp102_gr_zbc_stencil_get, + .clear_stencil = gp102_gr_zbc_clear_stencil, +}; + void gp102_gr_init_swdx_pes_mask(struct gf100_gr *gr) { @@ -65,7 +121,7 @@ gp102_gr = { .tpc_nr = 5, .ppc_nr = 3, .grctx = &gp102_grctx, - .zbc = &gp100_gr_zbc, + .zbc = &gp102_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c index 56f92c7235049..4573c914c021e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp104.c @@ -49,7 +49,7 @@ gp104_gr = { .tpc_nr = 5, .ppc_nr = 3, .grctx = &gp104_grctx, - .zbc = &gp100_gr_zbc, + .zbc = &gp102_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c index 4bb0340e3fdac..812aba91653fa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp107.c @@ -51,7 +51,7 @@ gp107_gr = { .tpc_nr = 3, .ppc_nr = 1, .grctx = &gp107_grctx, - .zbc = &gp100_gr_zbc, + .zbc = &gp102_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c index b2a39ad2fa445..303dceddd4a85 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gp10b.c @@ -49,7 +49,7 @@ gp10b_gr = { .tpc_nr = 2, .ppc_nr = 1, .grctx = &gp102_grctx, - .zbc = &gp100_gr_zbc, + .zbc = &gp102_gr_zbc, .sclass = { { -1, -1, FERMI_TWOD_A }, { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild index 12d6f4f102cb6..290ff1c425a98 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild @@ -4,3 +4,4 @@ nvkm-y += nvkm/subdev/ltc/gk104.o nvkm-y += nvkm/subdev/ltc/gm107.o nvkm-y += nvkm/subdev/ltc/gm200.o nvkm-y += nvkm/subdev/ltc/gp100.o +nvkm-y += nvkm/subdev/ltc/gp102.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c index 1f185274d3e63..23242179e6005 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c @@ -55,6 +55,14 @@ nvkm_ltc_zbc_depth_get(struct nvkm_ltc *ltc, int index, const u32 depth) return index; } +int +nvkm_ltc_zbc_stencil_get(struct nvkm_ltc *ltc, int index, const u32 stencil) +{ + ltc->zbc_stencil[index] = stencil; + ltc->func->zbc_clear_stencil(ltc, index, stencil); + return index; +} + void nvkm_ltc_invalidate(struct nvkm_ltc *ltc) { @@ -92,6 +100,8 @@ nvkm_ltc_init(struct nvkm_subdev *subdev) for (i = ltc->zbc_min; i <= ltc->zbc_max; i++) { ltc->func->zbc_clear_color(ltc, i, ltc->zbc_color[i]); ltc->func->zbc_clear_depth(ltc, i, ltc->zbc_depth[i]); + if (ltc->func->zbc_clear_stencil) + ltc->func->zbc_clear_stencil(ltc, i, ltc->zbc_stencil[i]); } ltc->func->init(ltc); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp100.c index e34d421080196..e923ed76d37ae 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp100.c @@ -23,7 +23,7 @@ */ #include "priv.h" -static void +void gp100_ltc_intr(struct nvkm_ltc *ltc) { struct nvkm_device *device = ltc->subdev.device; @@ -38,7 +38,7 @@ gp100_ltc_intr(struct nvkm_ltc *ltc) } } -static int +int gp100_ltc_oneinit(struct nvkm_ltc *ltc) { struct nvkm_device *device = ltc->subdev.device; @@ -48,7 +48,7 @@ gp100_ltc_oneinit(struct nvkm_ltc *ltc) return 0; } -static void +void gp100_ltc_init(struct nvkm_ltc *ltc) { /*XXX: PMU LS call to setup tagram address */ diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp102.c new file mode 100644 index 0000000000000..601747ada6555 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp102.c @@ -0,0 +1,51 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "priv.h" + +void +gp102_ltc_zbc_clear_stencil(struct nvkm_ltc *ltc, int i, const u32 stencil) +{ + struct nvkm_device *device = ltc->subdev.device; + nvkm_mask(device, 0x17e338, 0x0000000f, i); + nvkm_wr32(device, 0x17e204, stencil); +} + +static const struct nvkm_ltc_func +gp102_ltc = { + .oneinit = gp100_ltc_oneinit, + .init = gp100_ltc_init, + .intr = gp100_ltc_intr, + .cbc_clear = gm107_ltc_cbc_clear, + .cbc_wait = gm107_ltc_cbc_wait, + .zbc = 16, + .zbc_clear_color = gm107_ltc_zbc_clear_color, + .zbc_clear_depth = gm107_ltc_zbc_clear_depth, + .zbc_clear_stencil = gp102_ltc_zbc_clear_stencil, + .invalidate = gf100_ltc_invalidate, + .flush = gf100_ltc_flush, +}; + +int +gp102_ltc_new(struct nvkm_device *device, int index, struct nvkm_ltc **pltc) +{ + return nvkm_ltc_new_(&gp102_ltc, device, index, pltc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/priv.h index e71cc25cc775e..9dcde43c0f3c6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/priv.h @@ -19,6 +19,7 @@ struct nvkm_ltc_func { int zbc; void (*zbc_clear_color)(struct nvkm_ltc *, int, const u32[4]); void (*zbc_clear_depth)(struct nvkm_ltc *, int, const u32); + void (*zbc_clear_stencil)(struct nvkm_ltc *, int, const u32); void (*invalidate)(struct nvkm_ltc *); void (*flush)(struct nvkm_ltc *); @@ -41,4 +42,8 @@ void gm107_ltc_cbc_clear(struct nvkm_ltc *, u32, u32); void gm107_ltc_cbc_wait(struct nvkm_ltc *); void gm107_ltc_zbc_clear_color(struct nvkm_ltc *, int, const u32[4]); void gm107_ltc_zbc_clear_depth(struct nvkm_ltc *, int, const u32); + +int gp100_ltc_oneinit(struct nvkm_ltc *); +void gp100_ltc_init(struct nvkm_ltc *); +void gp100_ltc_intr(struct nvkm_ltc *); #endif From 19ca10d82e33bcfe92412c461fc3534ec1e14747 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 098/165] drm/nouveau/gem: lookup VMAs for buffers referenced by pushbuf ioctl We previously only did this for push buffers, but an upcoming patch will need to attach fences to all VMAs to resolve another issue. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_dma.c | 10 +--------- drivers/gpu/drm/nouveau/nouveau_dma.h | 5 ++--- drivers/gpu/drm/nouveau/nouveau_gem.c | 19 ++++++++++++++++--- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 10e84f6ca2b73..e0664d28802bf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -80,18 +80,10 @@ READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout) } void -nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo, - int delta, int length) +nv50_dma_push(struct nouveau_channel *chan, u64 offset, int length) { - struct nouveau_cli *cli = (void *)chan->user.client; struct nouveau_bo *pb = chan->push.buffer; - struct nouveau_vma *vma; int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base; - u64 offset; - - vma = nouveau_vma_find(bo, &cli->vmm); - BUG_ON(!vma); - offset = vma->addr + delta; BUG_ON(chan->dma.ib_free < 1); diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h index 74e10b14a7da2..89c87111bbbdd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.h +++ b/drivers/gpu/drm/nouveau/nouveau_dma.h @@ -31,8 +31,7 @@ #include "nouveau_chan.h" int nouveau_dma_wait(struct nouveau_channel *, int slots, int size); -void nv50_dma_push(struct nouveau_channel *, struct nouveau_bo *, - int delta, int length); +void nv50_dma_push(struct nouveau_channel *, u64 addr, int length); /* * There's a hw race condition where you can't jump to your PUT offset, @@ -151,7 +150,7 @@ FIRE_RING(struct nouveau_channel *chan) chan->accel_done = true; if (chan->dma.ib_max) { - nv50_dma_push(chan, chan->push.buffer, chan->dma.put << 2, + nv50_dma_push(chan, chan->push.addr + (chan->dma.put << 2), (chan->dma.cur - chan->dma.put) << 2); } else { WRITE_PUT(chan->dma.cur); diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index e72a7e37eb0af..707e02c80f182 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -432,7 +432,20 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, } } - b->user_priv = (uint64_t)(unsigned long)nvbo; + if (cli->vmm.vmm.object.oclass >= NVIF_CLASS_VMM_NV50) { + struct nouveau_vmm *vmm = &cli->vmm; + struct nouveau_vma *vma = nouveau_vma_find(nvbo, vmm); + if (!vma) { + NV_PRINTK(err, cli, "vma not found!\n"); + ret = -EINVAL; + break; + } + + b->user_priv = (uint64_t)(unsigned long)vma; + } else { + b->user_priv = (uint64_t)(unsigned long)nvbo; + } + nvbo->reserved_by = file_priv; nvbo->pbbo_index = i; if ((b->valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && @@ -763,10 +776,10 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, } for (i = 0; i < req->nr_push; i++) { - struct nouveau_bo *nvbo = (void *)(unsigned long) + struct nouveau_vma *vma = (void *)(unsigned long) bo[push[i].bo_index].user_priv; - nv50_dma_push(chan, nvbo, push[i].offset, + nv50_dma_push(chan, vma->addr + push[i].offset, push[i].length); } } else From 0db912af8f5ad4fa4dc08a9c8e411a10953c5403 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 099/165] drm/nouveau/gem: attach fences to VMAs to track GPU usage An upcoming patch will use these to fix issues related to the deferred unmapping of GEM objects. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_gem.c | 14 +++++++++++++- drivers/gpu/drm/nouveau/nouveau_vmm.c | 1 + drivers/gpu/drm/nouveau/nouveau_vmm.h | 2 ++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 707e02c80f182..2016d9eb338e1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -99,6 +99,7 @@ struct nouveau_gem_object_unmap { static void nouveau_gem_object_delete(struct nouveau_vma *vma) { + nouveau_fence_unref(&vma->fence); nouveau_vma_del(&vma); } @@ -344,9 +345,20 @@ validate_fini_no_ticket(struct validate_op *op, struct nouveau_fence *fence, nvbo = list_entry(op->list.next, struct nouveau_bo, entry); b = &pbbo[nvbo->pbbo_index]; - if (likely(fence)) + if (likely(fence)) { + struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); + struct nouveau_vma *vma; + nouveau_bo_fence(nvbo, fence, !!b->write_domains); + if (drm->client.vmm.vmm.object.oclass >= NVIF_CLASS_VMM_NV50) { + vma = (void *)(unsigned long)b->user_priv; + nouveau_fence_unref(&vma->fence); + dma_fence_get(&fence->base); + vma->fence = fence; + } + } + if (unlikely(nvbo->validate_mapped)) { ttm_bo_kunmap(&nvbo->kmap); nvbo->validate_mapped = false; diff --git a/drivers/gpu/drm/nouveau/nouveau_vmm.c b/drivers/gpu/drm/nouveau/nouveau_vmm.c index f5371d96b003c..2032c3e4f6e5d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vmm.c +++ b/drivers/gpu/drm/nouveau/nouveau_vmm.c @@ -92,6 +92,7 @@ nouveau_vma_new(struct nouveau_bo *nvbo, struct nouveau_vmm *vmm, vma->refs = 1; vma->addr = ~0ULL; vma->mem = NULL; + vma->fence = NULL; list_add_tail(&vma->head, &nvbo->vma_list); if (nvbo->bo.mem.mem_type != TTM_PL_SYSTEM && diff --git a/drivers/gpu/drm/nouveau/nouveau_vmm.h b/drivers/gpu/drm/nouveau/nouveau_vmm.h index 5c31f43678d3f..7e3b118cf7c4d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vmm.h +++ b/drivers/gpu/drm/nouveau/nouveau_vmm.h @@ -11,6 +11,8 @@ struct nouveau_vma { u64 addr; struct nouveau_mem *mem; + + struct nouveau_fence *fence; }; struct nouveau_vma *nouveau_vma_find(struct nouveau_bo *, struct nouveau_vmm *); From 470db8b78186efe840b6452c6c4934178058059e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 100/165] drm/nouveau/gem: tie deferred unmapping of buffers to VMA fence completion As VMAs are per-client, unlike buffers, this allows us to avoid referencing foreign fences (those that belong to another client/driver) from the client deferred work handler, and prevent some not-fun race conditions that can be triggered when a fence stalls. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_gem.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 2016d9eb338e1..300daee74209a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -115,25 +115,12 @@ nouveau_gem_object_delete_work(struct nouveau_cli_work *w) static void nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nouveau_vma *vma) { - const bool mapped = nvbo->bo.mem.mem_type != TTM_PL_SYSTEM; - struct reservation_object *resv = nvbo->bo.resv; - struct reservation_object_list *fobj; + struct dma_fence *fence = vma->fence ? &vma->fence->base : NULL; struct nouveau_gem_object_unmap *work; - struct dma_fence *fence = NULL; - - fobj = reservation_object_get_list(resv); list_del_init(&vma->head); - if (fobj && fobj->shared_count > 1) - ttm_bo_wait(&nvbo->bo, false, false); - else if (fobj && fobj->shared_count == 1) - fence = rcu_dereference_protected(fobj->shared[0], - reservation_object_held(resv)); - else - fence = reservation_object_get_excl(nvbo->bo.resv); - - if (!fence || !mapped) { + if (!fence) { nouveau_gem_object_delete(vma); return; } From 11e451e74050d9e9030581ce40337838acfcea5b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 101/165] drm/nouveau: remove fence wait code from deferred client work handler Fences attached to deferred client work items now originate from channels belonging to the client, meaning we can be certain they've been signalled before we destroy a client. This closes a race that could happen if the dma_fence_wait_timeout() call didn't succeed. When the fence was later signalled, a use-after-free was possible. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drm.c | 30 +++++++++++++-------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 6caece4f2f5f6..64b8fd0c4d68f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -113,24 +113,22 @@ nouveau_name(struct drm_device *dev) } static inline bool -nouveau_cli_work_ready(struct dma_fence *fence, bool wait) +nouveau_cli_work_ready(struct dma_fence *fence) { - if (!dma_fence_is_signaled(fence)) { - if (!wait) - return false; - WARN_ON(dma_fence_wait_timeout(fence, false, 2 * HZ) <= 0); - } + if (!dma_fence_is_signaled(fence)) + return false; dma_fence_put(fence); return true; } static void -nouveau_cli_work_flush(struct nouveau_cli *cli, bool wait) +nouveau_cli_work(struct work_struct *w) { + struct nouveau_cli *cli = container_of(w, typeof(*cli), work); struct nouveau_cli_work *work, *wtmp; mutex_lock(&cli->lock); list_for_each_entry_safe(work, wtmp, &cli->worker, head) { - if (!work->fence || nouveau_cli_work_ready(work->fence, wait)) { + if (!work->fence || nouveau_cli_work_ready(work->fence)) { list_del(&work->head); work->func(work); } @@ -158,17 +156,17 @@ nouveau_cli_work_queue(struct nouveau_cli *cli, struct dma_fence *fence, mutex_unlock(&cli->lock); } -static void -nouveau_cli_work(struct work_struct *w) -{ - struct nouveau_cli *cli = container_of(w, typeof(*cli), work); - nouveau_cli_work_flush(cli, false); -} - static void nouveau_cli_fini(struct nouveau_cli *cli) { - nouveau_cli_work_flush(cli, true); + /* All our channels are dead now, which means all the fences they + * own are signalled, and all callback functions have been called. + * + * So, after flushing the workqueue, there should be nothing left. + */ + flush_work(&cli->work); + WARN_ON(!list_empty(&cli->worker)); + usif_client_fini(cli); nouveau_vmm_fini(&cli->vmm); nvif_mmu_fini(&cli->mmu); From 92b4eaaf9a84a7bd35db6f903c0ecbda4f9594ee Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 102/165] drm/nouveau: no need to create ctxdma for push buffers on fermi and up Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_chan.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 67950a5c56ce9..97900e9cfe3f5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -163,12 +163,15 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, return ret; } + chan->push.addr = chan->push.vma->addr; + + if (device->info.family >= NV_DEVICE_INFO_V0_FERMI) + return 0; + args.target = NV_DMA_V0_TARGET_VM; args.access = NV_DMA_V0_ACCESS_VM; args.start = 0; args.limit = cli->vmm.vmm.limit - 1; - - chan->push.addr = chan->push.vma->addr; } else if (chan->push.buffer->bo.mem.mem_type == TTM_PL_VRAM) { if (device->info.family == NV_DEVICE_INFO_V0_TNT) { From 512fa0b8a398539c3c2db251f6c40da4ef065d09 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 103/165] drm/nouveau/drm/nv50-: remove allocation of sw class Hasn't been required for a long time. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_dma.h | 1 - drivers/gpu/drm/nouveau/nouveau_drm.c | 40 +++++++++++++-------------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h index 89c87111bbbdd..fc5e3f41282dd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.h +++ b/drivers/gpu/drm/nouveau/nouveau_dma.h @@ -54,7 +54,6 @@ enum { NvSub2D = 3, /* DO NOT CHANGE - hardcoded for kepler gr fifo */ NvSubCopy = 4, /* DO NOT CHANGE - hardcoded for kepler gr fifo */ - FermiSw = 5, /* DO NOT CHANGE (well.. 6/7 will work...) */ }; /* Object handles - for stuff that's doesn't use handle == oclass. */ diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 64b8fd0c4d68f..8e506c5d5a731 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -388,38 +388,36 @@ nouveau_accel_init(struct nouveau_drm *drm) return; } - ret = nvif_object_init(&drm->channel->user, NVDRM_NVSW, - nouveau_abi16_swclass(drm), NULL, 0, &drm->nvsw); - if (ret == 0) { - ret = RING_SPACE(drm->channel, 2); + if (device->info.family < NV_DEVICE_INFO_V0_TESLA) { + ret = nvif_object_init(&drm->channel->user, NVDRM_NVSW, + nouveau_abi16_swclass(drm), NULL, 0, + &drm->nvsw); if (ret == 0) { - if (device->info.family < NV_DEVICE_INFO_V0_FERMI) { + ret = RING_SPACE(drm->channel, 2); + if (ret == 0) { BEGIN_NV04(drm->channel, NvSubSw, 0, 1); - OUT_RING (drm->channel, NVDRM_NVSW); - } else - if (device->info.family < NV_DEVICE_INFO_V0_KEPLER) { - BEGIN_NVC0(drm->channel, FermiSw, 0, 1); - OUT_RING (drm->channel, 0x001f0000); + OUT_RING (drm->channel, drm->nvsw.handle); + } + + ret = nvif_notify_init(&drm->nvsw, + nouveau_flip_complete, + false, NV04_NVSW_NTFY_UEVENT, + NULL, 0, 0, &drm->flip); + if (ret == 0) + ret = nvif_notify_get(&drm->flip); + if (ret) { + nouveau_accel_fini(drm); + return; } } - ret = nvif_notify_init(&drm->nvsw, nouveau_flip_complete, - false, NV04_NVSW_NTFY_UEVENT, - NULL, 0, 0, &drm->flip); - if (ret == 0) - ret = nvif_notify_get(&drm->flip); if (ret) { + NV_ERROR(drm, "failed to allocate sw class, %d\n", ret); nouveau_accel_fini(drm); return; } } - if (ret) { - NV_ERROR(drm, "failed to allocate software object, %d\n", ret); - nouveau_accel_fini(drm); - return; - } - if (device->info.family < NV_DEVICE_INFO_V0_FERMI) { ret = nvkm_gpuobj_new(nvxx_device(&drm->client.device), 32, 0, false, NULL, &drm->notify); From 0d4a2c5767dc6136079b11ed45934143d309026e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 104/165] drm/nouveau/kms: move display class instantiation to library This function is useful outside of DRM code. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/disp.h | 12 ++++ drivers/gpu/drm/nouveau/include/nvif/object.h | 16 +++++ drivers/gpu/drm/nouveau/nouveau_connector.c | 14 ++--- drivers/gpu/drm/nouveau/nouveau_display.c | 35 +++-------- drivers/gpu/drm/nouveau/nouveau_display.h | 3 +- drivers/gpu/drm/nouveau/nv50_display.c | 50 ++++++++-------- drivers/gpu/drm/nouveau/nvif/Kbuild | 1 + drivers/gpu/drm/nouveau/nvif/disp.c | 59 +++++++++++++++++++ 8 files changed, 129 insertions(+), 61 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/include/nvif/disp.h create mode 100644 drivers/gpu/drm/nouveau/nvif/disp.c diff --git a/drivers/gpu/drm/nouveau/include/nvif/disp.h b/drivers/gpu/drm/nouveau/include/nvif/disp.h new file mode 100644 index 0000000000000..7c0eda375c015 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/disp.h @@ -0,0 +1,12 @@ +#ifndef __NVIF_DISP_H__ +#define __NVIF_DISP_H__ +#include +struct nvif_device; + +struct nvif_disp { + struct nvif_object object; +}; + +int nvif_disp_ctor(struct nvif_device *, s32 oclass, struct nvif_disp *); +void nvif_disp_dtor(struct nvif_disp *); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/object.h b/drivers/gpu/drm/nouveau/include/nvif/object.h index a2d5244ff2b77..20754d9e68838 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/object.h +++ b/drivers/gpu/drm/nouveau/include/nvif/object.h @@ -99,6 +99,22 @@ struct nvif_mclass { ret; \ }) +#define nvif_sclass(o,m,u) ({ \ + const typeof(m[0]) *_mclass = (m); \ + s32 _oclass = (u); \ + int _cid; \ + if (_oclass) { \ + for (_cid = 0; _mclass[_cid].oclass; _cid++) { \ + if (_mclass[_cid].oclass == _oclass) \ + break; \ + } \ + _cid = _mclass[_cid].oclass ? _cid : -ENOSYS; \ + } else { \ + _cid = nvif_mclass((o), _mclass); \ + } \ + _cid; \ +}) + /*XXX*/ #include #define nvxx_object(a) ({ \ diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 6ed9cb053dfa5..18e3239f76584 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -151,7 +151,7 @@ nouveau_conn_atomic_set_property(struct drm_connector *connector, /* ... except prior to G80, where the code * doesn't support such things. */ - if (disp->disp.oclass < NV50_DISP) + if (disp->disp.object.oclass < NV50_DISP) return -EINVAL; break; default: @@ -260,7 +260,7 @@ nouveau_conn_reset(struct drm_connector *connector) asyc->procamp.color_vibrance = 150; asyc->procamp.vibrant_hue = 90; - if (nouveau_display(connector->dev)->disp.oclass < NV50_DISP) { + if (nouveau_display(connector->dev)->disp.object.oclass < NV50_DISP) { switch (connector->connector_type) { case DRM_MODE_CONNECTOR_LVDS: /* See note in nouveau_conn_atomic_set_property(). */ @@ -314,7 +314,7 @@ nouveau_conn_attach_properties(struct drm_connector *connector) case DRM_MODE_CONNECTOR_TV: break; case DRM_MODE_CONNECTOR_VGA: - if (disp->disp.oclass < NV50_DISP) + if (disp->disp.object.oclass < NV50_DISP) break; /* Can only scale on DFPs. */ /* Fall-through. */ default: @@ -1321,7 +1321,7 @@ nouveau_connector_create(struct drm_device *dev, int index) } /* HDMI 3D support */ - if ((disp->disp.oclass >= G82_DISP) + if ((disp->disp.object.oclass >= G82_DISP) && ((type == DRM_MODE_CONNECTOR_DisplayPort) || (type == DRM_MODE_CONNECTOR_eDP) || (type == DRM_MODE_CONNECTOR_HDMIA))) @@ -1343,7 +1343,7 @@ nouveau_connector_create(struct drm_device *dev, int index) case DCB_CONNECTOR_LVDS_SPWG: case DCB_CONNECTOR_eDP: /* see note in nouveau_connector_set_property() */ - if (disp->disp.oclass < NV50_DISP) { + if (disp->disp.object.oclass < NV50_DISP) { nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN; break; } @@ -1366,8 +1366,8 @@ nouveau_connector_create(struct drm_device *dev, int index) break; } - ret = nvif_notify_init(&disp->disp, nouveau_connector_hotplug, true, - NV04_DISP_NTFY_CONN, + ret = nvif_notify_init(&disp->disp.object, nouveau_connector_hotplug, + true, NV04_DISP_NTFY_CONN, &(struct nvif_notify_conn_req_v0) { .mask = NVIF_NOTIFY_CONN_V0_ANY, .conn = index, diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 7d0bec8dd03de..774b429142bc8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -116,7 +116,7 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, bool ret = false; do { - ret = nvif_mthd(&disp->disp, 0, &args, sizeof(args)); + ret = nvif_mthd(&disp->disp.object, 0, &args, sizeof(args)); if (ret != 0) return false; @@ -175,7 +175,7 @@ nouveau_display_vblank_init(struct drm_device *dev) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - ret = nvif_notify_init(&disp->disp, + ret = nvif_notify_init(&disp->disp.object, nouveau_display_vblank_handler, false, NV04_DISP_NTFY_VBLANK, &(struct nvif_notify_head_req_v0) { @@ -454,10 +454,10 @@ nouveau_display_create_properties(struct drm_device *dev) struct nouveau_display *disp = nouveau_display(dev); int gen; - if (disp->disp.oclass < NV50_DISP) + if (disp->disp.object.oclass < NV50_DISP) gen = 0; else - if (disp->disp.oclass < GF110_DISP) + if (disp->disp.object.oclass < GF110_DISP) gen = 1; else gen = 2; @@ -533,31 +533,10 @@ nouveau_display_create(struct drm_device *dev) drm_kms_helper_poll_disable(dev); if (nouveau_modeset != 2 && drm->vbios.dcb.entries) { - static const u16 oclass[] = { - GP102_DISP, - GP100_DISP, - GM200_DISP, - GM107_DISP, - GK110_DISP, - GK104_DISP, - GF110_DISP, - GT214_DISP, - GT206_DISP, - GT200_DISP, - G82_DISP, - NV50_DISP, - NV04_DISP, - }; - int i; - - for (i = 0, ret = -ENODEV; ret && i < ARRAY_SIZE(oclass); i++) { - ret = nvif_object_init(&drm->client.device.object, 0, - oclass[i], NULL, 0, &disp->disp); - } - + ret = nvif_disp_ctor(&drm->client.device, 0, &disp->disp); if (ret == 0) { nouveau_display_create_properties(dev); - if (disp->disp.oclass < NV50_DISP) + if (disp->disp.object.oclass < NV50_DISP) ret = nv04_display_create(dev); else ret = nv50_display_create(dev); @@ -611,7 +590,7 @@ nouveau_display_destroy(struct drm_device *dev) if (disp->dtor) disp->dtor(dev); - nvif_object_fini(&disp->disp); + nvif_disp_dtor(&disp->disp); nouveau_drm(dev)->display = NULL; kfree(disp); diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 270ba56f27560..54aa7c3fa42dd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -2,6 +2,7 @@ #ifndef __NOUVEAU_DISPLAY_H__ #define __NOUVEAU_DISPLAY_H__ #include "nouveau_drv.h" +#include struct nouveau_framebuffer { struct drm_framebuffer base; @@ -38,7 +39,7 @@ struct nouveau_display { int (*init)(struct drm_device *); void (*fini)(struct drm_device *); - struct nvif_object disp; + struct nvif_disp disp; struct drm_property *dithering_mode; struct drm_property *dithering_depth; diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index e90330e4e8c51..f2156c8ca90f5 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -663,7 +663,7 @@ struct nv50_head { #define nv50_vers(c) nv50_chan(c)->user.oclass struct nv50_disp { - struct nvif_object *disp; + struct nvif_disp *disp; struct nv50_mast mast; struct nouveau_bo *sync; @@ -1201,7 +1201,7 @@ nv50_curs_new(struct nouveau_drm *drm, struct nv50_head *head, struct nv50_curs *curs; int cid, ret; - cid = nvif_mclass(disp->disp, curses); + cid = nvif_mclass(&disp->disp->object, curses); if (cid < 0) { NV_ERROR(drm, "No supported cursor immediate class\n"); return cid; @@ -1219,8 +1219,8 @@ nv50_curs_new(struct nouveau_drm *drm, struct nv50_head *head, return ret; } - ret = nvif_object_init(disp->disp, 0, curses[cid].oclass, &args, - sizeof(args), &curs->chan); + ret = nvif_object_init(&disp->disp->object, 0, curses[cid].oclass, + &args, sizeof(args), &curs->chan); if (ret) { NV_ERROR(drm, "curs%04x allocation failed: %d\n", curses[cid].oclass, ret); @@ -1517,8 +1517,8 @@ nv50_base_new(struct nouveau_drm *drm, struct nv50_head *head, return ret; } - ret = nv50_base_create(&drm->client.device, disp->disp, base->id, - disp->sync->bo.offset, &base->chan); + ret = nv50_base_create(&drm->client.device, &disp->disp->object, + base->id, disp->sync->bo.offset, &base->chan); if (ret) return ret; @@ -2105,7 +2105,7 @@ nv50_head_atomic_check_lut(struct nv50_head *head, return; } - if (disp->disp->oclass < GF110_DISP) { + if (disp->disp->object.oclass < GF110_DISP) { asyh->lut.mode = (asyh->base.cpp == 1) ? 0 : 1; asyh->set.ilut = true; } else { @@ -2404,12 +2404,12 @@ nv50_head_create(struct drm_device *dev, int index) } /* allocate overlay resources */ - ret = nv50_oimm_create(device, disp->disp, index, &head->oimm); + ret = nv50_oimm_create(device, &disp->disp->object, index, &head->oimm); if (ret) goto out; - ret = nv50_ovly_create(device, disp->disp, index, disp->sync->bo.offset, - &head->ovly); + ret = nv50_ovly_create(device, &disp->disp->object, index, + disp->sync->bo.offset, &head->ovly); if (ret) goto out; @@ -2435,7 +2435,7 @@ nv50_outp_release(struct nouveau_encoder *nv_encoder) .base.hashm = nv_encoder->dcb->hashm, }; - nvif_mthd(disp->disp, 0, &args, sizeof(args)); + nvif_mthd(&disp->disp->object, 0, &args, sizeof(args)); nv_encoder->or = -1; nv_encoder->link = 0; } @@ -2456,7 +2456,7 @@ nv50_outp_acquire(struct nouveau_encoder *nv_encoder) }; int ret; - ret = nvif_mthd(disp->disp, 0, &args, sizeof(args)); + ret = nvif_mthd(&disp->disp->object, 0, &args, sizeof(args)); if (ret) { NV_ERROR(drm, "error acquiring output path: %d\n", ret); return ret; @@ -2618,7 +2618,7 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) if (args.load.data == 0) args.load.data = 340; - ret = nvif_mthd(disp->disp, 0, &args, sizeof(args)); + ret = nvif_mthd(&disp->disp->object, 0, &args, sizeof(args)); if (ret || !args.load.load) return connector_status_disconnected; @@ -2694,7 +2694,7 @@ nv50_audio_disable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc) (0x0100 << nv_crtc->index), }; - nvif_mthd(disp->disp, 0, &args, sizeof(args)); + nvif_mthd(&disp->disp->object, 0, &args, sizeof(args)); } static void @@ -2724,7 +2724,7 @@ nv50_audio_enable(struct drm_encoder *encoder, struct drm_display_mode *mode) memcpy(args.data, nv_connector->base.eld, sizeof(args.data)); - nvif_mthd(disp->disp, 0, &args, + nvif_mthd(&disp->disp->object, 0, &args, sizeof(args.base) + drm_eld_size(args.data)); } @@ -2747,7 +2747,7 @@ nv50_hdmi_disable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc) (0x0100 << nv_crtc->index), }; - nvif_mthd(disp->disp, 0, &args, sizeof(args)); + nvif_mthd(&disp->disp->object, 0, &args, sizeof(args)); } static void @@ -2808,7 +2808,7 @@ nv50_hdmi_enable(struct drm_encoder *encoder, struct drm_display_mode *mode) + sizeof(args.pwr) + args.pwr.avi_infoframe_length + args.pwr.vendor_infoframe_length; - nvif_mthd(disp->disp, 0, &args, size); + nvif_mthd(&disp->disp->object, 0, &args, size); nv50_audio_enable(encoder, mode); } @@ -2923,7 +2923,7 @@ nv50_msto_prepare(struct nv50_msto *msto) msto->encoder.name, msto->head->base.base.name, args.vcpi.start_slot, args.vcpi.num_slots, args.vcpi.pbn, args.vcpi.aligned_pbn); - nvif_mthd(&drm->display->disp, 0, &args, sizeof(args)); + nvif_mthd(&drm->display->disp.object, 0, &args, sizeof(args)); } static int @@ -3341,7 +3341,7 @@ nv50_mstm_enable(struct nv50_mstm *mstm, u8 dpcd, int state) .mst.state = state, }; struct nouveau_drm *drm = nouveau_drm(outp->base.base.dev); - struct nvif_object *disp = &drm->display->disp; + struct nvif_object *disp = &drm->display->disp.object; int ret; if (dpcd >= 0x12) { @@ -3610,7 +3610,7 @@ nv50_sor_enable(struct drm_encoder *encoder) lvds.lvds.script |= 0x0200; } - nvif_mthd(disp->disp, 0, &lvds, sizeof(lvds)); + nvif_mthd(&disp->disp->object, 0, &lvds, sizeof(lvds)); break; case DCB_OUTPUT_DP: if (nv_connector->base.display_info.bpc == 6) @@ -3696,7 +3696,7 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe) struct nvkm_i2c_aux *aux = nvkm_i2c_aux_find(i2c, dcbe->i2c_index); if (aux) { - if (disp->disp->oclass < GF110_DISP) { + if (disp->disp->object.oclass < GF110_DISP) { /* HW has no support for address-only * transactions, so we're required to * use custom I2C-over-AUX code. @@ -3709,7 +3709,7 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe) } /*TODO: Use DP Info Table to check for support. */ - if (disp->disp->oclass >= GF110_DISP) { + if (disp->disp->object.oclass >= GF110_DISP) { ret = nv50_mstm_new(nv_encoder, &nv_connector->aux, 16, nv_connector->base.base.id, &nv_encoder->dp.mstm); @@ -4474,13 +4474,13 @@ nv50_display_create(struct drm_device *dev) goto out; /* allocate master evo channel */ - ret = nv50_core_create(device, disp->disp, disp->sync->bo.offset, - &disp->mast); + ret = nv50_core_create(device, &disp->disp->object, + disp->sync->bo.offset, &disp->mast); if (ret) goto out; /* create crtc objects to represent the hw heads */ - if (disp->disp->oclass >= GF110_DISP) + if (disp->disp->object.oclass >= GF110_DISP) crtcs = nvif_rd32(&device->object, 0x612004) & 0xf; else crtcs = 0x3; diff --git a/drivers/gpu/drm/nouveau/nvif/Kbuild b/drivers/gpu/drm/nouveau/nvif/Kbuild index c817b02b7acf2..3db12504140ff 100644 --- a/drivers/gpu/drm/nouveau/nvif/Kbuild +++ b/drivers/gpu/drm/nouveau/nvif/Kbuild @@ -1,6 +1,7 @@ nvif-y := nvif/object.o nvif-y += nvif/client.o nvif-y += nvif/device.o +nvif-y += nvif/disp.o nvif-y += nvif/driver.o nvif-y += nvif/fifo.o nvif-y += nvif/mem.o diff --git a/drivers/gpu/drm/nouveau/nvif/disp.c b/drivers/gpu/drm/nouveau/nvif/disp.c new file mode 100644 index 0000000000000..7006482e8e297 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvif/disp.c @@ -0,0 +1,59 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 +#include + +#include + +void +nvif_disp_dtor(struct nvif_disp *disp) +{ + nvif_object_fini(&disp->object); +} + +int +nvif_disp_ctor(struct nvif_device *device, s32 oclass, struct nvif_disp *disp) +{ + static const struct nvif_mclass disps[] = { + { GP102_DISP, -1 }, + { GP100_DISP, -1 }, + { GM200_DISP, -1 }, + { GM107_DISP, -1 }, + { GK110_DISP, -1 }, + { GK104_DISP, -1 }, + { GF110_DISP, -1 }, + { GT214_DISP, -1 }, + { GT206_DISP, -1 }, + { GT200_DISP, -1 }, + { G82_DISP, -1 }, + { NV50_DISP, -1 }, + { NV04_DISP, -1 }, + {} + }; + int cid = nvif_sclass(&device->object, disps, oclass); + disp->object.client = NULL; + if (cid < 0) + return cid; + + return nvif_object_init(&device->object, 0, disps[cid].oclass, + NULL, 0, &disp->object); +} From 30ed49b55b6e44e004c3095671e74fea93ee84cb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 105/165] drm/nouveau/kms/nv50-: move code underneath dispnv50/ The code is about to be split up, and this matches dispnv04. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Kbuild | 8 +++----- drivers/gpu/drm/nouveau/dispnv50/Kbuild | 1 + .../gpu/drm/nouveau/{nv50_display.c => dispnv50/disp.c} | 0 3 files changed, 4 insertions(+), 5 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/dispnv50/Kbuild rename drivers/gpu/drm/nouveau/{nv50_display.c => dispnv50/disp.c} (100%) diff --git a/drivers/gpu/drm/nouveau/Kbuild b/drivers/gpu/drm/nouveau/Kbuild index 9c0c650655e93..b17843dd050d3 100644 --- a/drivers/gpu/drm/nouveau/Kbuild +++ b/drivers/gpu/drm/nouveau/Kbuild @@ -38,14 +38,16 @@ nouveau-y += nouveau_vmm.o # DRM - modesetting nouveau-$(CONFIG_DRM_NOUVEAU_BACKLIGHT) += nouveau_backlight.o +nouveau-y += nouveau_bios.o nouveau-y += nouveau_connector.o nouveau-y += nouveau_display.o -nouveau-y += nv50_display.o nouveau-y += nouveau_dp.o nouveau-y += nouveau_fbcon.o nouveau-y += nv04_fbcon.o nouveau-y += nv50_fbcon.o nouveau-y += nvc0_fbcon.o +include $(src)/dispnv04/Kbuild +include $(src)/dispnv50/Kbuild # DRM - command submission nouveau-y += nouveau_abi16.o @@ -59,8 +61,4 @@ nouveau-y += nv50_fence.o nouveau-y += nv84_fence.o nouveau-y += nvc0_fence.o -# DRM - prehistoric modesetting (NV04-G7x) -nouveau-y += nouveau_bios.o -include $(src)/dispnv04/Kbuild - obj-$(CONFIG_DRM_NOUVEAU) += nouveau.o diff --git a/drivers/gpu/drm/nouveau/dispnv50/Kbuild b/drivers/gpu/drm/nouveau/dispnv50/Kbuild new file mode 100644 index 0000000000000..43fc8be49391d --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/Kbuild @@ -0,0 +1 @@ +nouveau-y += dispnv50/disp.o diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c similarity index 100% rename from drivers/gpu/drm/nouveau/nv50_display.c rename to drivers/gpu/drm/nouveau/dispnv50/disp.c From 62b290fc7b36e8fec2a370b946d7117c1899b6c1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 106/165] drm/nouveau/kms/nv50-: fix i2c-over-aux on anx9805 We don't support address-only transactions there. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index f2156c8ca90f5..9aa17500d57c0 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -3836,7 +3836,6 @@ nv50_pior_func = { static int nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe) { - struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_drm *drm = nouveau_drm(connector->dev); struct nvkm_i2c *i2c = nvxx_i2c(&drm->client.device); struct nvkm_i2c_bus *bus = NULL; @@ -3854,7 +3853,7 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe) break; case DCB_OUTPUT_DP: aux = nvkm_i2c_aux_find(i2c, NVKM_I2C_AUX_EXT(dcbe->extdev)); - ddc = aux ? &nv_connector->aux.ddc : NULL; + ddc = aux ? &aux->i2c : NULL; type = DRM_MODE_ENCODER_TMDS; break; default: From 5bca1621c07c3ad37b5a4943450a892e18984df0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 107/165] drm/nouveau/kms/nv50-: move fb ctxdma tracking into windows Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 163 ++++++++++++------------ 1 file changed, 84 insertions(+), 79 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 9aa17500d57c0..fc3055d5c8c9f 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -395,7 +395,7 @@ nv50_oimm_create(struct nvif_device *device, struct nvif_object *disp, * DMA EVO channel *****************************************************************************/ -struct nv50_dmac_ctxdma { +struct nv50_wndw_ctxdma { struct list_head head; struct nvif_object object; }; @@ -408,7 +408,6 @@ struct nv50_dmac { struct nvif_object sync; struct nvif_object vram; - struct list_head ctxdma; /* Protects against concurrent pushbuf access to this channel, lock is * grabbed by evo_wait (if the pushbuf reservation is successful) and @@ -416,83 +415,9 @@ struct nv50_dmac { struct mutex lock; }; -static void -nv50_dmac_ctxdma_del(struct nv50_dmac_ctxdma *ctxdma) -{ - nvif_object_fini(&ctxdma->object); - list_del(&ctxdma->head); - kfree(ctxdma); -} - -static struct nv50_dmac_ctxdma * -nv50_dmac_ctxdma_new(struct nv50_dmac *dmac, struct nouveau_framebuffer *fb) -{ - struct nouveau_drm *drm = nouveau_drm(fb->base.dev); - struct nv50_dmac_ctxdma *ctxdma; - const u8 kind = fb->nvbo->kind; - const u32 handle = 0xfb000000 | kind; - struct { - struct nv_dma_v0 base; - union { - struct nv50_dma_v0 nv50; - struct gf100_dma_v0 gf100; - struct gf119_dma_v0 gf119; - }; - } args = {}; - u32 argc = sizeof(args.base); - int ret; - - list_for_each_entry(ctxdma, &dmac->ctxdma, head) { - if (ctxdma->object.handle == handle) - return ctxdma; - } - - if (!(ctxdma = kzalloc(sizeof(*ctxdma), GFP_KERNEL))) - return ERR_PTR(-ENOMEM); - list_add(&ctxdma->head, &dmac->ctxdma); - - args.base.target = NV_DMA_V0_TARGET_VRAM; - args.base.access = NV_DMA_V0_ACCESS_RDWR; - args.base.start = 0; - args.base.limit = drm->client.device.info.ram_user - 1; - - if (drm->client.device.info.chipset < 0x80) { - args.nv50.part = NV50_DMA_V0_PART_256; - argc += sizeof(args.nv50); - } else - if (drm->client.device.info.chipset < 0xc0) { - args.nv50.part = NV50_DMA_V0_PART_256; - args.nv50.kind = kind; - argc += sizeof(args.nv50); - } else - if (drm->client.device.info.chipset < 0xd0) { - args.gf100.kind = kind; - argc += sizeof(args.gf100); - } else { - args.gf119.page = GF119_DMA_V0_PAGE_LP; - args.gf119.kind = kind; - argc += sizeof(args.gf119); - } - - ret = nvif_object_init(&dmac->base.user, handle, NV_DMA_IN_MEMORY, - &args, argc, &ctxdma->object); - if (ret) { - nv50_dmac_ctxdma_del(ctxdma); - return ERR_PTR(ret); - } - - return ctxdma; -} - static void nv50_dmac_destroy(struct nv50_dmac *dmac) { - struct nv50_dmac_ctxdma *ctxdma, *ctxtmp; - - list_for_each_entry_safe(ctxdma, ctxtmp, &dmac->ctxdma, head) { - nv50_dmac_ctxdma_del(ctxdma); - } - nvif_object_fini(&dmac->vram); nvif_object_fini(&dmac->sync); @@ -511,7 +436,6 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, int ret; mutex_init(&dmac->lock); - INIT_LIST_HEAD(&dmac->ctxdma); ret = nvif_mem_init_map(&cli->mmu, NVIF_MEM_COHERENT, 0x1000, &dmac->push); @@ -740,6 +664,11 @@ struct nv50_wndw { const struct nv50_wndw_func *func; struct nv50_dmac *dmac; + struct { + struct nvif_object *parent; + struct list_head list; + } ctxdma; + struct drm_plane plane; struct nvif_notify notify; @@ -770,6 +699,74 @@ struct nv50_wndw_func { u32 (*update)(struct nv50_wndw *, u32 interlock); }; +static void +nv50_wndw_ctxdma_del(struct nv50_wndw_ctxdma *ctxdma) +{ + nvif_object_fini(&ctxdma->object); + list_del(&ctxdma->head); + kfree(ctxdma); +} + +static struct nv50_wndw_ctxdma * +nv50_wndw_ctxdma_new(struct nv50_wndw *wndw, struct nouveau_framebuffer *fb) +{ + struct nouveau_drm *drm = nouveau_drm(fb->base.dev); + struct nv50_wndw_ctxdma *ctxdma; + const u8 kind = fb->nvbo->kind; + const u32 handle = 0xfb000000 | kind; + struct { + struct nv_dma_v0 base; + union { + struct nv50_dma_v0 nv50; + struct gf100_dma_v0 gf100; + struct gf119_dma_v0 gf119; + }; + } args = {}; + u32 argc = sizeof(args.base); + int ret; + + list_for_each_entry(ctxdma, &wndw->ctxdma.list, head) { + if (ctxdma->object.handle == handle) + return ctxdma; + } + + if (!(ctxdma = kzalloc(sizeof(*ctxdma), GFP_KERNEL))) + return ERR_PTR(-ENOMEM); + list_add(&ctxdma->head, &wndw->ctxdma.list); + + args.base.target = NV_DMA_V0_TARGET_VRAM; + args.base.access = NV_DMA_V0_ACCESS_RDWR; + args.base.start = 0; + args.base.limit = drm->client.device.info.ram_user - 1; + + if (drm->client.device.info.chipset < 0x80) { + args.nv50.part = NV50_DMA_V0_PART_256; + argc += sizeof(args.nv50); + } else + if (drm->client.device.info.chipset < 0xc0) { + args.nv50.part = NV50_DMA_V0_PART_256; + args.nv50.kind = kind; + argc += sizeof(args.nv50); + } else + if (drm->client.device.info.chipset < 0xd0) { + args.gf100.kind = kind; + argc += sizeof(args.gf100); + } else { + args.gf119.page = GF119_DMA_V0_PAGE_LP; + args.gf119.kind = kind; + argc += sizeof(args.gf119); + } + + ret = nvif_object_init(wndw->ctxdma.parent, handle, NV_DMA_IN_MEMORY, + &args, argc, &ctxdma->object); + if (ret) { + nv50_wndw_ctxdma_del(ctxdma); + return ERR_PTR(ret); + } + + return ctxdma; +} + static int nv50_wndw_wait_armed(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { @@ -944,7 +941,7 @@ nv50_wndw_prepare_fb(struct drm_plane *plane, struct drm_plane_state *state) struct nv50_wndw *wndw = nv50_wndw(plane); struct nv50_wndw_atom *asyw = nv50_wndw_atom(state); struct nv50_head_atom *asyh; - struct nv50_dmac_ctxdma *ctxdma; + struct nv50_wndw_ctxdma *ctxdma; int ret; NV_ATOMIC(drm, "%s prepare: %p\n", plane->name, state->fb); @@ -955,7 +952,7 @@ nv50_wndw_prepare_fb(struct drm_plane *plane, struct drm_plane_state *state) if (ret) return ret; - ctxdma = nv50_dmac_ctxdma_new(wndw->dmac, fb); + ctxdma = nv50_wndw_ctxdma_new(wndw, fb); if (IS_ERR(ctxdma)) { nouveau_bo_unpin(fb->nvbo); return PTR_ERR(ctxdma); @@ -1030,7 +1027,13 @@ static void nv50_wndw_destroy(struct drm_plane *plane) { struct nv50_wndw *wndw = nv50_wndw(plane); + struct nv50_wndw_ctxdma *ctxdma, *ctxtmp; void *data; + + list_for_each_entry_safe(ctxdma, ctxtmp, &wndw->ctxdma.list, head) { + nv50_wndw_ctxdma_del(ctxdma); + } + nvif_notify_fini(&wndw->notify); data = wndw->func->dtor(wndw); drm_plane_cleanup(&wndw->plane); @@ -1069,6 +1072,7 @@ nv50_wndw_ctor(const struct nv50_wndw_func *func, struct drm_device *dev, wndw->func = func; wndw->dmac = dmac; + wndw->ctxdma.parent = &dmac->base.user; ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw, format, nformat, NULL, @@ -1077,6 +1081,7 @@ nv50_wndw_ctor(const struct nv50_wndw_func *func, struct drm_device *dev, return ret; drm_plane_helper_add(&wndw->plane, &nv50_wndw_helper); + INIT_LIST_HEAD(&wndw->ctxdma.list); return 0; } From a97c530eb968bad8d945d4f64fb550fa37a9d362 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 108/165] drm/nouveau/kms/nv50-: modify overlay allocation so the code can be split Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 277 +++++++++++++++--------- 1 file changed, 179 insertions(+), 98 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index fc3055d5c8c9f..26caca270ec8a 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -340,57 +340,6 @@ nv50_chan_destroy(struct nv50_chan *chan) nvif_object_fini(&chan->user); } -/****************************************************************************** - * PIO EVO channel - *****************************************************************************/ - -struct nv50_pioc { - struct nv50_chan base; -}; - -static void -nv50_pioc_destroy(struct nv50_pioc *pioc) -{ - nv50_chan_destroy(&pioc->base); -} - -static int -nv50_pioc_create(struct nvif_device *device, struct nvif_object *disp, - const s32 *oclass, u8 head, void *data, u32 size, - struct nv50_pioc *pioc) -{ - return nv50_chan_create(device, disp, oclass, head, data, size, - &pioc->base); -} - -/****************************************************************************** - * Overlay Immediate - *****************************************************************************/ - -struct nv50_oimm { - struct nv50_pioc base; -}; - -static int -nv50_oimm_create(struct nvif_device *device, struct nvif_object *disp, - int head, struct nv50_oimm *oimm) -{ - struct nv50_disp_cursor_v0 args = { - .head = head, - }; - static const s32 oclass[] = { - GK104_DISP_OVERLAY, - GF110_DISP_OVERLAY, - GT214_DISP_OVERLAY, - G82_DISP_OVERLAY, - NV50_DISP_OVERLAY, - 0 - }; - - return nv50_pioc_create(device, disp, oclass, head, &args, sizeof(args), - &oimm->base); -} - /****************************************************************************** * DMA EVO channel *****************************************************************************/ @@ -541,43 +490,12 @@ nv50_base_create(struct nvif_device *device, struct nvif_object *disp, syncbuf, &base->base); } -/****************************************************************************** - * Overlay - *****************************************************************************/ - -struct nv50_ovly { - struct nv50_dmac base; -}; - -static int -nv50_ovly_create(struct nvif_device *device, struct nvif_object *disp, - int head, u64 syncbuf, struct nv50_ovly *ovly) -{ - struct nv50_disp_overlay_channel_dma_v0 args = { - .head = head, - }; - static const s32 oclass[] = { - GK104_DISP_OVERLAY_CONTROL_DMA, - GF110_DISP_OVERLAY_CONTROL_DMA, - GT214_DISP_OVERLAY_CHANNEL_DMA, - GT200_DISP_OVERLAY_CHANNEL_DMA, - G82_DISP_OVERLAY_CHANNEL_DMA, - NV50_DISP_OVERLAY_CHANNEL_DMA, - 0 - }; - - return nv50_dmac_create(device, disp, oclass, head, &args, sizeof(args), - syncbuf, &ovly->base); -} - struct nv50_head { struct nouveau_crtc base; struct { struct nouveau_bo *nvbo[2]; int next; } lut; - struct nv50_ovly ovly; - struct nv50_oimm oimm; }; #define nv50_head(c) ((struct nv50_head *)nouveau_crtc(c)) @@ -662,7 +580,9 @@ evo_kick(u32 *push, void *evoc) struct nv50_wndw { const struct nv50_wndw_func *func; + const struct nv50_wimm_func *immd; struct nv50_dmac *dmac; + int id; struct { struct nvif_object *parent; @@ -671,6 +591,9 @@ struct nv50_wndw { struct drm_plane plane; + struct nv50_dmac wndw; + struct nv50_dmac wimm; + struct nvif_notify notify; u16 ntfy; u16 sema; @@ -699,6 +622,9 @@ struct nv50_wndw_func { u32 (*update)(struct nv50_wndw *, u32 interlock); }; +struct nv50_wimm_func { +}; + static void nv50_wndw_ctxdma_del(struct nv50_wndw_ctxdma *ctxdma) { @@ -1028,14 +954,17 @@ nv50_wndw_destroy(struct drm_plane *plane) { struct nv50_wndw *wndw = nv50_wndw(plane); struct nv50_wndw_ctxdma *ctxdma, *ctxtmp; - void *data; + void *data = wndw; list_for_each_entry_safe(ctxdma, ctxtmp, &wndw->ctxdma.list, head) { nv50_wndw_ctxdma_del(ctxdma); } nvif_notify_fini(&wndw->notify); - data = wndw->func->dtor(wndw); + if (wndw->func->dtor) + data = wndw->func->dtor(wndw); + nv50_dmac_destroy(&wndw->wimm); + nv50_dmac_destroy(&wndw->wndw); drm_plane_cleanup(&wndw->plane); kfree(data); } @@ -1085,6 +1014,170 @@ nv50_wndw_ctor(const struct nv50_wndw_func *func, struct drm_device *dev, return 0; } +static int +nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, + enum drm_plane_type type, const char *name, int index, + const u32 *format, struct nv50_wndw **pwndw) +{ + struct nv50_wndw *wndw; + int nformat; + int ret; + + if (!(wndw = *pwndw = kzalloc(sizeof(*wndw), GFP_KERNEL))) + return -ENOMEM; + wndw->id = index; + + for (nformat = 0; format[nformat]; nformat++); + + ret = nv50_wndw_ctor(func, dev, type, name, index, + &wndw->wndw, format, nformat, wndw); + if (ret) { + kfree(*pwndw); + *pwndw = NULL; + } + + return ret; +} + +/****************************************************************************** + * Overlay + *****************************************************************************/ + +static const struct nv50_wimm_func +oimm507b = { +}; + +static int +oimm507b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, + s32 oclass, struct nv50_wndw *wndw) +{ + struct nv50_disp_overlay_v0 args = { + .head = wndw->id, + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + int ret; + + ret = nvif_object_init(&disp->disp->object, 0, oclass, &args, + sizeof(args), &wndw->wimm.base.user); + if (ret) { + NV_ERROR(drm, "oimm%04x allocation failed: %d\n", oclass, ret); + return ret; + } + + nvif_object_map(&wndw->wimm.base.user, NULL, 0); + wndw->immd = func; + return 0; +} + +static int +oimm507b_init(struct nouveau_drm *drm, s32 oclass, struct nv50_wndw *wndw) +{ + return oimm507b_init_(&oimm507b, drm, oclass, wndw); +} + +static int +nv50_oimm_init(struct nouveau_drm *drm, struct nv50_wndw *wndw) +{ + static const struct { + s32 oclass; + int version; + int (*init)(struct nouveau_drm *, s32, struct nv50_wndw *); + } oimms[] = { + { GK104_DISP_OVERLAY, 0, oimm507b_init }, + { GF110_DISP_OVERLAY, 0, oimm507b_init }, + { GT214_DISP_OVERLAY, 0, oimm507b_init }, + { G82_DISP_OVERLAY, 0, oimm507b_init }, + { NV50_DISP_OVERLAY, 0, oimm507b_init }, + {} + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + int cid; + + cid = nvif_mclass(&disp->disp->object, oimms); + if (cid < 0) { + NV_ERROR(drm, "No supported overlay immediate class\n"); + return cid; + } + + return oimms[cid].init(drm, oimms[cid].oclass, wndw); +} + +static const struct nv50_wndw_func +ovly507e = { +}; + +static const u32 +ovly507e_format[] = { + 0 +}; + +static int +ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format, + struct nouveau_drm *drm, int head, s32 oclass, + struct nv50_wndw **pwndw) +{ + struct nv50_disp_overlay_channel_dma_v0 args = { + .head = head, + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + struct nv50_wndw *wndw; + int ret; + + ret = nv50_wndw_new_(func, drm->dev, DRM_PLANE_TYPE_OVERLAY, + "ovly", head, format, &wndw); + if (*pwndw = wndw, ret) + return ret; + + ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, + &oclass, 0, &args, sizeof(args), + disp->sync->bo.offset, &wndw->wndw); + if (ret) { + NV_ERROR(drm, "ovly%04x allocation failed: %d\n", oclass, ret); + return ret; + } + + return 0; +} + +static int +ovly507e_new(struct nouveau_drm *drm, int head, s32 oclass, + struct nv50_wndw **pwndw) +{ + return ovly507e_new_(&ovly507e, ovly507e_format, drm, head, oclass, pwndw); +} + +static int +nv50_ovly_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) +{ + static const struct { + s32 oclass; + int version; + int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); + } ovlys[] = { + { GK104_DISP_OVERLAY_CONTROL_DMA, 0, ovly507e_new }, + { GF110_DISP_OVERLAY_CONTROL_DMA, 0, ovly507e_new }, + { GT214_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new }, + { GT200_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new }, + { G82_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new }, + { NV50_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new }, + {} + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + int cid, ret; + + cid = nvif_mclass(&disp->disp->object, ovlys); + if (cid < 0) { + NV_ERROR(drm, "No supported overlay class\n"); + return cid; + } + + ret = ovlys[cid].new(drm, head, ovlys[cid].oclass, pwndw); + if (ret) + return ret; + + return nv50_oimm_init(drm, *pwndw); +} + /****************************************************************************** * Cursor plane *****************************************************************************/ @@ -2347,9 +2440,6 @@ nv50_head_destroy(struct drm_crtc *crtc) struct nv50_head *head = nv50_head(crtc); int i; - nv50_dmac_destroy(&head->ovly.base); - nv50_pioc_destroy(&head->oimm.base); - for (i = 0; i < ARRAY_SIZE(head->lut.nvbo); i++) nouveau_bo_unmap_unpin_unref(&head->lut.nvbo[i]); @@ -2372,11 +2462,10 @@ static int nv50_head_create(struct drm_device *dev, int index) { struct nouveau_drm *drm = nouveau_drm(dev); - struct nvif_device *device = &drm->client.device; - struct nv50_disp *disp = nv50_disp(dev); struct nv50_head *head; struct nv50_base *base; struct nv50_curs *curs; + struct nv50_wndw *wndw; struct drm_crtc *crtc; int ret, i; @@ -2409,15 +2498,7 @@ nv50_head_create(struct drm_device *dev, int index) } /* allocate overlay resources */ - ret = nv50_oimm_create(device, &disp->disp->object, index, &head->oimm); - if (ret) - goto out; - - ret = nv50_ovly_create(device, &disp->disp->object, index, - disp->sync->bo.offset, &head->ovly); - if (ret) - goto out; - + ret = nv50_ovly_new(drm, head->base.index, &wndw); out: if (ret) nv50_head_destroy(crtc); From b97ace4072267ea44a254ef2c3b001d2122313dc Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 109/165] drm/nouveau/kms/nv50-: modify cursor allocation so the code can be split Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 136 +++++++++++++----------- 1 file changed, 71 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 26caca270ec8a..33cb358ebeebc 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -617,12 +617,14 @@ struct nv50_wndw_func { void (*image_set)(struct nv50_wndw *, struct nv50_wndw_atom *); void (*image_clr)(struct nv50_wndw *); void (*lut)(struct nv50_wndw *, struct nv50_wndw_atom *); - void (*point)(struct nv50_wndw *, struct nv50_wndw_atom *); u32 (*update)(struct nv50_wndw *, u32 interlock); }; struct nv50_wimm_func { + void (*point)(struct nv50_wndw *, struct nv50_wndw_atom *); + + u32 (*update)(struct nv50_wndw *, u32 interlock); }; static void @@ -728,9 +730,12 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 interlock, if (asyw->set.ntfy ) wndw->func->ntfy_set (wndw, asyw); if (asyw->set.image) wndw->func->image_set(wndw, asyw); if (asyw->set.lut ) wndw->func->lut (wndw, asyw); - if (asyw->set.point) wndw->func->point (wndw, asyw); + if (asyw->set.point) { + wndw->immd->point(wndw, asyw); + wndw->immd->update(wndw, interlock); + } - return wndw->func->update(wndw, interlock); + return wndw->func->update ? wndw->func->update(wndw, interlock) : 0; } static void @@ -1181,28 +1186,26 @@ nv50_ovly_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) /****************************************************************************** * Cursor plane *****************************************************************************/ -#define nv50_curs(p) container_of((p), struct nv50_curs, wndw) - -struct nv50_curs { - struct nv50_wndw wndw; - struct nvif_object chan; -}; - static u32 nv50_curs_update(struct nv50_wndw *wndw, u32 interlock) { - struct nv50_curs *curs = nv50_curs(wndw); - nvif_wr32(&curs->chan, 0x0080, 0x00000000); + nvif_wr32(&wndw->wimm.base.user, 0x0080, 0x00000000); return 0; } static void nv50_curs_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - struct nv50_curs *curs = nv50_curs(wndw); - nvif_wr32(&curs->chan, 0x0084, (asyw->point.y << 16) | asyw->point.x); + nvif_wr32(&wndw->wimm.base.user, 0x0084, (asyw->point.y << 16) | + asyw->point.x); } +static const struct nv50_wimm_func +curs507a = { + .point = nv50_curs_point, + .update = nv50_curs_update, +}; + static void nv50_curs_prepare(struct nv50_wndw *wndw, struct nv50_head_atom *asyh, struct nv50_wndw_atom *asyw) @@ -1257,77 +1260,82 @@ nv50_curs_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, return 0; } -static void * -nv50_curs_dtor(struct nv50_wndw *wndw) -{ - struct nv50_curs *curs = nv50_curs(wndw); - nvif_object_fini(&curs->chan); - return curs; -} - static const u32 nv50_curs_format[] = { DRM_FORMAT_ARGB8888, + 0 }; static const struct nv50_wndw_func nv50_curs = { - .dtor = nv50_curs_dtor, .acquire = nv50_curs_acquire, .release = nv50_curs_release, .prepare = nv50_curs_prepare, - .point = nv50_curs_point, - .update = nv50_curs_update, }; static int -nv50_curs_new(struct nouveau_drm *drm, struct nv50_head *head, - struct nv50_curs **pcurs) -{ - static const struct nvif_mclass curses[] = { - { GK104_DISP_CURSOR, 0 }, - { GF110_DISP_CURSOR, 0 }, - { GT214_DISP_CURSOR, 0 }, - { G82_DISP_CURSOR, 0 }, - { NV50_DISP_CURSOR, 0 }, - {} - }; +curs507a_new_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, + int head, s32 oclass, struct nv50_wndw **pwndw) +{ struct nv50_disp_cursor_v0 args = { - .head = head->base.index, + .head = head, }; struct nv50_disp *disp = nv50_disp(drm->dev); - struct nv50_curs *curs; - int cid, ret; - - cid = nvif_mclass(&disp->disp->object, curses); - if (cid < 0) { - NV_ERROR(drm, "No supported cursor immediate class\n"); - return cid; - } - - if (!(curs = *pcurs = kzalloc(sizeof(*curs), GFP_KERNEL))) - return -ENOMEM; + struct nv50_wndw *wndw; + int ret; - ret = nv50_wndw_ctor(&nv50_curs, drm->dev, DRM_PLANE_TYPE_CURSOR, - "curs", head->base.index, &disp->mast.base, - nv50_curs_format, ARRAY_SIZE(nv50_curs_format), - &curs->wndw); - if (ret) { - kfree(curs); + ret = nv50_wndw_new_(&nv50_curs, drm->dev, DRM_PLANE_TYPE_CURSOR, + "curs", head, nv50_curs_format, &wndw); + if (*pwndw = wndw, ret) return ret; - } - ret = nvif_object_init(&disp->disp->object, 0, curses[cid].oclass, - &args, sizeof(args), &curs->chan); + ret = nvif_object_init(&disp->disp->object, 0, oclass, &args, + sizeof(args), &wndw->wimm.base.user); if (ret) { - NV_ERROR(drm, "curs%04x allocation failed: %d\n", - curses[cid].oclass, ret); + NV_ERROR(drm, "curs%04x allocation failed: %d\n", oclass, ret); return ret; } + nvif_object_map(&wndw->wimm.base.user, NULL, 0); + wndw->immd = func; + wndw->ctxdma.parent = &disp->mast.base.base.user; return 0; } +static int +curs507a_new(struct nouveau_drm *drm, int head, s32 oclass, + struct nv50_wndw **pwndw) +{ + return curs507a_new_(&curs507a, drm, head, oclass, pwndw); +} + +static int +nv50_curs_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) +{ + struct { + s32 oclass; + int version; + int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); + } curses[] = { + { GK104_DISP_CURSOR, 0, curs507a_new }, + { GF110_DISP_CURSOR, 0, curs507a_new }, + { GT214_DISP_CURSOR, 0, curs507a_new }, + { G82_DISP_CURSOR, 0, curs507a_new }, + { NV50_DISP_CURSOR, 0, curs507a_new }, + {} + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + int cid; + + cid = nvif_mclass(&disp->disp->object, curses); + if (cid < 0) { + NV_ERROR(drm, "No supported cursor immediate class\n"); + return cid; + } + + return curses[cid].new(drm, head, curses[cid].oclass, pwndw); +} + /****************************************************************************** * Primary plane *****************************************************************************/ @@ -2464,8 +2472,7 @@ nv50_head_create(struct drm_device *dev, int index) struct nouveau_drm *drm = nouveau_drm(dev); struct nv50_head *head; struct nv50_base *base; - struct nv50_curs *curs; - struct nv50_wndw *wndw; + struct nv50_wndw *curs, *wndw; struct drm_crtc *crtc; int ret, i; @@ -2476,16 +2483,15 @@ nv50_head_create(struct drm_device *dev, int index) head->base.index = index; ret = nv50_base_new(drm, head, &base); if (ret == 0) - ret = nv50_curs_new(drm, head, &curs); + ret = nv50_curs_new(drm, head->base.index, &curs); if (ret) { kfree(head); return ret; } crtc = &head->base.base; - drm_crtc_init_with_planes(dev, crtc, &base->wndw.plane, - &curs->wndw.plane, &nv50_head_func, - "head-%d", head->base.index); + drm_crtc_init_with_planes(dev, crtc, &base->wndw.plane, &curs->plane, + &nv50_head_func, "head-%d", head->base.index); drm_crtc_helper_add(crtc, &nv50_head_help); drm_mode_crtc_set_gamma_size(crtc, 256); From d7c6e97a32329032ba7af1f53cab2767832fed77 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 110/165] drm/nouveau/kms/nv50-: modify base allocation so the code can be split Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 238 +++++++++++------------- 1 file changed, 105 insertions(+), 133 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 33cb358ebeebc..f0edf9b5337a7 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -468,28 +468,6 @@ struct nv50_sync { u32 data; }; -static int -nv50_base_create(struct nvif_device *device, struct nvif_object *disp, - int head, u64 syncbuf, struct nv50_sync *base) -{ - struct nv50_disp_base_channel_dma_v0 args = { - .head = head, - }; - static const s32 oclass[] = { - GK110_DISP_BASE_CHANNEL_DMA, - GK104_DISP_BASE_CHANNEL_DMA, - GF110_DISP_BASE_CHANNEL_DMA, - GT214_DISP_BASE_CHANNEL_DMA, - GT200_DISP_BASE_CHANNEL_DMA, - G82_DISP_BASE_CHANNEL_DMA, - NV50_DISP_BASE_CHANNEL_DMA, - 0 - }; - - return nv50_dmac_create(device, disp, oclass, head, &args, sizeof(args), - syncbuf, &base->base); -} - struct nv50_head { struct nouveau_crtc base; struct { @@ -581,7 +559,6 @@ evo_kick(u32 *push, void *evoc) struct nv50_wndw { const struct nv50_wndw_func *func; const struct nv50_wimm_func *immd; - struct nv50_dmac *dmac; int id; struct { @@ -601,7 +578,6 @@ struct nv50_wndw { }; struct nv50_wndw_func { - void *(*dtor)(struct nv50_wndw *); int (*acquire)(struct nv50_wndw *, struct nv50_wndw_atom *asyw, struct nv50_head_atom *asyh); void (*release)(struct nv50_wndw *, struct nv50_wndw_atom *asyw, @@ -959,19 +935,16 @@ nv50_wndw_destroy(struct drm_plane *plane) { struct nv50_wndw *wndw = nv50_wndw(plane); struct nv50_wndw_ctxdma *ctxdma, *ctxtmp; - void *data = wndw; list_for_each_entry_safe(ctxdma, ctxtmp, &wndw->ctxdma.list, head) { nv50_wndw_ctxdma_del(ctxdma); } nvif_notify_fini(&wndw->notify); - if (wndw->func->dtor) - data = wndw->func->dtor(wndw); nv50_dmac_destroy(&wndw->wimm); nv50_dmac_destroy(&wndw->wndw); drm_plane_cleanup(&wndw->plane); - kfree(data); + kfree(wndw); } static const struct drm_plane_funcs @@ -984,6 +957,12 @@ nv50_wndw = { .atomic_destroy_state = nv50_wndw_atomic_destroy_state, }; +static int +nv50_wndw_notify(struct nvif_notify *notify) +{ + return NVIF_NOTIFY_KEEP; +} + static void nv50_wndw_fini(struct nv50_wndw *wndw) { @@ -996,29 +975,6 @@ nv50_wndw_init(struct nv50_wndw *wndw) nvif_notify_get(&wndw->notify); } -static int -nv50_wndw_ctor(const struct nv50_wndw_func *func, struct drm_device *dev, - enum drm_plane_type type, const char *name, int index, - struct nv50_dmac *dmac, const u32 *format, int nformat, - struct nv50_wndw *wndw) -{ - int ret; - - wndw->func = func; - wndw->dmac = dmac; - wndw->ctxdma.parent = &dmac->base.user; - - ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw, - format, nformat, NULL, - type, "%s-%d", name, index); - if (ret) - return ret; - - drm_plane_helper_add(&wndw->plane, &nv50_wndw_helper); - INIT_LIST_HEAD(&wndw->ctxdma.list); - return 0; -} - static int nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, enum drm_plane_type type, const char *name, int index, @@ -1030,18 +986,27 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, if (!(wndw = *pwndw = kzalloc(sizeof(*wndw), GFP_KERNEL))) return -ENOMEM; + wndw->func = func; wndw->id = index; + wndw->ctxdma.parent = &wndw->wndw.base.user; + INIT_LIST_HEAD(&wndw->ctxdma.list); + for (nformat = 0; format[nformat]; nformat++); - ret = nv50_wndw_ctor(func, dev, type, name, index, - &wndw->wndw, format, nformat, wndw); + ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw, + format, nformat, NULL, + type, "%s-%d", name, index); if (ret) { kfree(*pwndw); *pwndw = NULL; + return ret; } - return ret; + drm_plane_helper_add(&wndw->plane, &nv50_wndw_helper); + + wndw->notify.func = nv50_wndw_notify; + return 0; } /****************************************************************************** @@ -1339,53 +1304,36 @@ nv50_curs_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) /****************************************************************************** * Primary plane *****************************************************************************/ -#define nv50_base(p) container_of((p), struct nv50_base, wndw) - -struct nv50_base { - struct nv50_wndw wndw; - struct nv50_sync chan; - int id; -}; - -static int -nv50_base_notify(struct nvif_notify *notify) -{ - return NVIF_NOTIFY_KEEP; -} - static void nv50_base_lut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - struct nv50_base *base = nv50_base(wndw); u32 *push; - if ((push = evo_wait(&base->chan, 2))) { + if ((push = evo_wait(&wndw->wndw, 2))) { evo_mthd(push, 0x00e0, 1); evo_data(push, asyw->lut.enable << 30); - evo_kick(push, &base->chan); + evo_kick(push, &wndw->wndw); } } static void nv50_base_image_clr(struct nv50_wndw *wndw) { - struct nv50_base *base = nv50_base(wndw); u32 *push; - if ((push = evo_wait(&base->chan, 4))) { + if ((push = evo_wait(&wndw->wndw, 4))) { evo_mthd(push, 0x0084, 1); evo_data(push, 0x00000000); evo_mthd(push, 0x00c0, 1); evo_data(push, 0x00000000); - evo_kick(push, &base->chan); + evo_kick(push, &wndw->wndw); } } static void nv50_base_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - struct nv50_base *base = nv50_base(wndw); - const s32 oclass = base->chan.base.base.user.oclass; + const s32 oclass = wndw->wndw.base.user.oclass; u32 *push; - if ((push = evo_wait(&base->chan, 10))) { + if ((push = evo_wait(&wndw->wndw, 10))) { evo_mthd(push, 0x0084, 1); evo_data(push, (asyw->image.mode << 8) | (asyw->image.interval << 4)); @@ -1421,77 +1369,72 @@ nv50_base_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) asyw->image.block); evo_data(push, asyw->image.format << 8); } - evo_kick(push, &base->chan); + evo_kick(push, &wndw->wndw); } } static void nv50_base_ntfy_clr(struct nv50_wndw *wndw) { - struct nv50_base *base = nv50_base(wndw); u32 *push; - if ((push = evo_wait(&base->chan, 2))) { + if ((push = evo_wait(&wndw->wndw, 2))) { evo_mthd(push, 0x00a4, 1); evo_data(push, 0x00000000); - evo_kick(push, &base->chan); + evo_kick(push, &wndw->wndw); } } static void nv50_base_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - struct nv50_base *base = nv50_base(wndw); u32 *push; - if ((push = evo_wait(&base->chan, 3))) { + if ((push = evo_wait(&wndw->wndw, 3))) { evo_mthd(push, 0x00a0, 2); evo_data(push, (asyw->ntfy.awaken << 30) | asyw->ntfy.offset); evo_data(push, asyw->ntfy.handle); - evo_kick(push, &base->chan); + evo_kick(push, &wndw->wndw); } } static void nv50_base_sema_clr(struct nv50_wndw *wndw) { - struct nv50_base *base = nv50_base(wndw); u32 *push; - if ((push = evo_wait(&base->chan, 2))) { + if ((push = evo_wait(&wndw->wndw, 2))) { evo_mthd(push, 0x0094, 1); evo_data(push, 0x00000000); - evo_kick(push, &base->chan); + evo_kick(push, &wndw->wndw); } } static void nv50_base_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - struct nv50_base *base = nv50_base(wndw); u32 *push; - if ((push = evo_wait(&base->chan, 5))) { + if ((push = evo_wait(&wndw->wndw, 5))) { evo_mthd(push, 0x0088, 4); evo_data(push, asyw->sema.offset); evo_data(push, asyw->sema.acquire); evo_data(push, asyw->sema.release); evo_data(push, asyw->sema.handle); - evo_kick(push, &base->chan); + evo_kick(push, &wndw->wndw); } } static u32 nv50_base_update(struct nv50_wndw *wndw, u32 interlock) { - struct nv50_base *base = nv50_base(wndw); u32 *push; - if (!(push = evo_wait(&base->chan, 2))) + if (!(push = evo_wait(&wndw->wndw, 2))) return 0; evo_mthd(push, 0x0080, 1); evo_data(push, interlock); - evo_kick(push, &base->chan); + evo_kick(push, &wndw->wndw); - if (base->chan.base.base.user.oclass < GF110_DISP_BASE_CHANNEL_DMA) - return interlock ? 2 << (base->id * 8) : 0; - return interlock ? 2 << (base->id * 4) : 0; + if (wndw->wndw.base.user.oclass < GF110_DISP_BASE_CHANNEL_DMA) + return interlock ? 2 << (wndw->id * 8) : 0; + return interlock ? 2 << (wndw->id * 4) : 0; } static int @@ -1561,14 +1504,6 @@ nv50_base_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, return 0; } -static void * -nv50_base_dtor(struct nv50_wndw *wndw) -{ - struct nv50_base *base = nv50_base(wndw); - nv50_dmac_destroy(&base->chan.base); - return base; -} - static const u32 nv50_base_format[] = { DRM_FORMAT_C8, @@ -1581,11 +1516,11 @@ nv50_base_format[] = { DRM_FORMAT_ABGR2101010, DRM_FORMAT_XBGR8888, DRM_FORMAT_ABGR8888, + 0 }; static const struct nv50_wndw_func nv50_base = { - .dtor = nv50_base_dtor, .acquire = nv50_base_acquire, .release = nv50_base_release, .sema_set = nv50_base_sema_set, @@ -1600,41 +1535,79 @@ nv50_base = { }; static int -nv50_base_new(struct nouveau_drm *drm, struct nv50_head *head, - struct nv50_base **pbase) +base507c_new_(const struct nv50_wndw_func *func, const u32 *format, + struct nouveau_drm *drm, int head, s32 oclass, + struct nv50_wndw **pwndw) { + struct nv50_disp_base_channel_dma_v0 args = { + .head = head, + }; struct nv50_disp *disp = nv50_disp(drm->dev); - struct nv50_base *base; + struct nv50_wndw *wndw; int ret; - if (!(base = *pbase = kzalloc(sizeof(*base), GFP_KERNEL))) - return -ENOMEM; - base->id = head->base.index; - base->wndw.ntfy = EVO_FLIP_NTFY0(base->id); - base->wndw.sema = EVO_FLIP_SEM0(base->id); - base->wndw.data = 0x00000000; - - ret = nv50_wndw_ctor(&nv50_base, drm->dev, DRM_PLANE_TYPE_PRIMARY, - "base", base->id, &base->chan.base, - nv50_base_format, ARRAY_SIZE(nv50_base_format), - &base->wndw); + ret = nv50_wndw_new_(func, drm->dev, DRM_PLANE_TYPE_PRIMARY, + "base", head, format, &wndw); + if (*pwndw = wndw, ret) + return ret; + + ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, + &oclass, head, &args, sizeof(args), + disp->sync->bo.offset, &wndw->wndw); if (ret) { - kfree(base); + NV_ERROR(drm, "base%04x allocation failed: %d\n", oclass, ret); return ret; } - ret = nv50_base_create(&drm->client.device, &disp->disp->object, - base->id, disp->sync->bo.offset, &base->chan); + ret = nvif_notify_init(&wndw->wndw.base.user, wndw->notify.func, + false, NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT, + &(struct nvif_notify_uevent_req) {}, + sizeof(struct nvif_notify_uevent_req), + sizeof(struct nvif_notify_uevent_rep), + &wndw->notify); if (ret) return ret; - return nvif_notify_init(&base->chan.base.base.user, nv50_base_notify, - false, - NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT, - &(struct nvif_notify_uevent_req) {}, - sizeof(struct nvif_notify_uevent_req), - sizeof(struct nvif_notify_uevent_rep), - &base->wndw.notify); + wndw->ntfy = EVO_FLIP_NTFY0(wndw->id); + wndw->sema = EVO_FLIP_SEM0(wndw->id); + wndw->data = 0x00000000; + return 0; +} + +static int +base507c_new(struct nouveau_drm *drm, int head, s32 oclass, + struct nv50_wndw **pwndw) +{ + return base507c_new_(&nv50_base, nv50_base_format, drm, head, oclass, pwndw); +} + +static int +nv50_base_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) +{ + struct { + s32 oclass; + int version; + int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); + } bases[] = { + { GK110_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, + { GK104_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, + { GF110_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, + { GT214_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, + { GT200_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, + { G82_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, + { NV50_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, + {} + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + int cid; + + cid = nvif_mclass(&disp->disp->object, bases); + if (cid < 0) { + NV_ERROR(drm, "No supported base class\n"); + return cid; + } + + return bases[cid].new(drm, head, bases[cid].oclass, pwndw); } /****************************************************************************** @@ -2471,7 +2444,6 @@ nv50_head_create(struct drm_device *dev, int index) { struct nouveau_drm *drm = nouveau_drm(dev); struct nv50_head *head; - struct nv50_base *base; struct nv50_wndw *curs, *wndw; struct drm_crtc *crtc; int ret, i; @@ -2481,7 +2453,7 @@ nv50_head_create(struct drm_device *dev, int index) return -ENOMEM; head->base.index = index; - ret = nv50_base_new(drm, head, &base); + ret = nv50_base_new(drm, head->base.index, &wndw); if (ret == 0) ret = nv50_curs_new(drm, head->base.index, &curs); if (ret) { @@ -2490,7 +2462,7 @@ nv50_head_create(struct drm_device *dev, int index) } crtc = &head->base.base; - drm_crtc_init_with_planes(dev, crtc, &base->wndw.plane, &curs->plane, + drm_crtc_init_with_planes(dev, crtc, &wndw->plane, &curs->plane, &nv50_head_func, "head-%d", head->base.index); drm_crtc_helper_add(crtc, &nv50_head_help); drm_mode_crtc_set_gamma_size(crtc, 256); @@ -4256,7 +4228,7 @@ nv50_disp_atomic_commit(struct drm_device *dev, struct nv50_wndw *wndw = nv50_wndw(plane); if (asyw->set.image) { - asyw->ntfy.handle = wndw->dmac->sync.handle; + asyw->ntfy.handle = wndw->wndw.sync.handle; asyw->ntfy.offset = wndw->ntfy; asyw->ntfy.awaken = false; asyw->set.ntfy = true; From 9ca6f1ebba10240ad02f7c659481899a28220fbc Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 111/165] drm/nouveau/kms/nv50: modify core allocation so the code can be split Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 215 +++++++++++++++--------- 1 file changed, 134 insertions(+), 81 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index f0edf9b5337a7..abdf39ed9d261 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -425,39 +425,6 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, return ret; } -/****************************************************************************** - * Core - *****************************************************************************/ - -struct nv50_mast { - struct nv50_dmac base; -}; - -static int -nv50_core_create(struct nvif_device *device, struct nvif_object *disp, - u64 syncbuf, struct nv50_mast *core) -{ - struct nv50_disp_core_channel_dma_v0 args = {}; - static const s32 oclass[] = { - GP102_DISP_CORE_CHANNEL_DMA, - GP100_DISP_CORE_CHANNEL_DMA, - GM200_DISP_CORE_CHANNEL_DMA, - GM107_DISP_CORE_CHANNEL_DMA, - GK110_DISP_CORE_CHANNEL_DMA, - GK104_DISP_CORE_CHANNEL_DMA, - GF110_DISP_CORE_CHANNEL_DMA, - GT214_DISP_CORE_CHANNEL_DMA, - GT206_DISP_CORE_CHANNEL_DMA, - GT200_DISP_CORE_CHANNEL_DMA, - G82_DISP_CORE_CHANNEL_DMA, - NV50_DISP_CORE_CHANNEL_DMA, - 0 - }; - - return nv50_dmac_create(device, disp, oclass, 0, &args, sizeof(args), - syncbuf, &core->base); -} - /****************************************************************************** * Base *****************************************************************************/ @@ -477,14 +444,10 @@ struct nv50_head { }; #define nv50_head(c) ((struct nv50_head *)nouveau_crtc(c)) -#define nv50_ovly(c) (&nv50_head(c)->ovly) -#define nv50_oimm(c) (&nv50_head(c)->oimm) -#define nv50_chan(c) (&(c)->base.base) -#define nv50_vers(c) nv50_chan(c)->user.oclass struct nv50_disp { struct nvif_disp *disp; - struct nv50_mast mast; + struct nv50_core *core; struct nouveau_bo *sync; @@ -497,7 +460,41 @@ nv50_disp(struct drm_device *dev) return nouveau_display(dev)->priv; } -#define nv50_mast(d) (&nv50_disp(d)->mast) +/****************************************************************************** + * Core + *****************************************************************************/ + +struct nv50_core { + const struct nv50_core_func *func; + struct nv50_dmac chan; +}; + +struct nv50_core_func { +}; + +static int +core507d_new_(const struct nv50_core_func *func, struct nouveau_drm *drm, + s32 oclass, struct nv50_core **pcore) +{ + struct nv50_disp_core_channel_dma_v0 args = {}; + struct nv50_disp *disp = nv50_disp(drm->dev); + struct nv50_core *core; + int ret; + + if (!(core = *pcore = kzalloc(sizeof(*core), GFP_KERNEL))) + return -ENOMEM; + core->func = func; + + ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, + &oclass, 0, &args, sizeof(args), + disp->sync->bo.offset, &core->chan); + if (ret) { + NV_ERROR(drm, "core%04x allocation failed: %d\n", oclass, ret); + return ret; + } + + return 0; +} /****************************************************************************** * EVO channel helpers @@ -1175,7 +1172,7 @@ static void nv50_curs_prepare(struct nv50_wndw *wndw, struct nv50_head_atom *asyh, struct nv50_wndw_atom *asyw) { - u32 handle = nv50_disp(wndw->plane.dev)->mast.base.vram.handle; + u32 handle = nv50_disp(wndw->plane.dev)->core->chan.vram.handle; u32 offset = asyw->image.offset; if (asyh->curs.handle != handle || asyh->curs.offset != offset) { asyh->curs.handle = handle; @@ -1263,7 +1260,7 @@ curs507a_new_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, nvif_object_map(&wndw->wimm.base.user, NULL, 0); wndw->immd = func; - wndw->ctxdma.parent = &disp->mast.base.base.user; + wndw->ctxdma.parent = &disp->core->chan.base.user; return 0; } @@ -1616,7 +1613,7 @@ nv50_base_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) static void nv50_head_procamp(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if ((push = evo_wait(core, 2))) { if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) @@ -1632,7 +1629,7 @@ nv50_head_procamp(struct nv50_head *head, struct nv50_head_atom *asyh) static void nv50_head_dither(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if ((push = evo_wait(core, 2))) { if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) @@ -1652,7 +1649,7 @@ nv50_head_dither(struct nv50_head *head, struct nv50_head_atom *asyh) static void nv50_head_ovly(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 bounds = 0; u32 *push; @@ -1681,7 +1678,7 @@ nv50_head_ovly(struct nv50_head *head, struct nv50_head_atom *asyh) static void nv50_head_base(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 bounds = 0; u32 *push; @@ -1711,7 +1708,7 @@ nv50_head_base(struct nv50_head *head, struct nv50_head_atom *asyh) static void nv50_head_curs_clr(struct nv50_head *head) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if ((push = evo_wait(core, 4))) { if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { @@ -1736,7 +1733,7 @@ nv50_head_curs_clr(struct nv50_head *head) static void nv50_head_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if ((push = evo_wait(core, 5))) { if (core->base.user.oclass < G82_DISP_BASE_CHANNEL_DMA) { @@ -1767,7 +1764,7 @@ nv50_head_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh) static void nv50_head_core_clr(struct nv50_head *head) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if ((push = evo_wait(core, 2))) { if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) @@ -1782,7 +1779,7 @@ nv50_head_core_clr(struct nv50_head *head) static void nv50_head_core_set(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if ((push = evo_wait(core, 9))) { if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { @@ -1836,7 +1833,7 @@ nv50_head_core_set(struct nv50_head *head, struct nv50_head_atom *asyh) static void nv50_head_lut_clr(struct nv50_head *head) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if ((push = evo_wait(core, 4))) { if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { @@ -1909,7 +1906,7 @@ nv50_head_lut_load(struct drm_property_blob *blob, int mode, static void nv50_head_lut_set(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if ((push = evo_wait(core, 7))) { if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { @@ -1939,7 +1936,7 @@ nv50_head_lut_set(struct nv50_head *head, struct nv50_head_atom *asyh) static void nv50_head_mode(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; struct nv50_head_mode *m = &asyh->mode; u32 *push; if ((push = evo_wait(core, 14))) { @@ -1980,7 +1977,7 @@ nv50_head_mode(struct nv50_head *head, struct nv50_head_atom *asyh) static void nv50_head_view(struct nv50_head *head, struct nv50_head_atom *asyh) { - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if ((push = evo_wait(core, 10))) { if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { @@ -2191,7 +2188,7 @@ nv50_head_atomic_check_lut(struct nv50_head *head, asyh->lut.mode = 7; asyh->set.ilut = asyh->state.color_mgmt_changed; } - asyh->lut.handle = disp->mast.base.vram.handle; + asyh->lut.handle = disp->core->chan.vram.handle; } static void @@ -2311,7 +2308,7 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) asyh->core.w = asyh->state.mode.hdisplay; asyh->core.h = asyh->state.mode.vdisplay; } - asyh->core.handle = disp->mast.base.vram.handle; + asyh->core.handle = disp->core->chan.vram.handle; asyh->core.offset = 0; asyh->core.format = 0xcf; asyh->core.kind = 0; @@ -2483,6 +2480,61 @@ nv50_head_create(struct drm_device *dev, int index) return ret; } +static const struct nv50_core_func +core507d = { +}; + +static int +core507d_new(struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore) +{ + return core507d_new_(&core507d, drm, oclass, pcore); +} + +static void +nv50_core_del(struct nv50_core **pcore) +{ + struct nv50_core *core = *pcore; + if (core) { + nv50_dmac_destroy(&core->chan); + kfree(*pcore); + *pcore = NULL; + } +} + +static int +nv50_core_new(struct nouveau_drm *drm, struct nv50_core **pcore) +{ + struct { + s32 oclass; + int version; + int (*new)(struct nouveau_drm *, s32, struct nv50_core **); + } cores[] = { + { GP102_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GP100_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GM200_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GM107_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GK110_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GK104_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GF110_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GT214_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GT206_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GT200_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { G82_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { NV50_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + {} + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + int cid; + + cid = nvif_mclass(&disp->disp->object, cores); + if (cid < 0) { + NV_ERROR(drm, "No supported core channel class\n"); + return cid; + } + + return cores[cid].new(drm, cores[cid].oclass, pcore); +} + /****************************************************************************** * Output path helpers *****************************************************************************/ @@ -2591,21 +2643,21 @@ static void nv50_dac_disable(struct drm_encoder *encoder) { struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nv50_mast *mast = nv50_mast(encoder->dev); + struct nv50_dmac *core = &nv50_disp(encoder->dev)->core->chan; const int or = nv_encoder->or; u32 *push; if (nv_encoder->crtc) { - push = evo_wait(mast, 4); + push = evo_wait(core, 4); if (push) { - if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { evo_mthd(push, 0x0400 + (or * 0x080), 1); evo_data(push, 0x00000000); } else { evo_mthd(push, 0x0180 + (or * 0x020), 1); evo_data(push, 0x00000000); } - evo_kick(push, mast); + evo_kick(push, core); } } @@ -2616,7 +2668,7 @@ nv50_dac_disable(struct drm_encoder *encoder) static void nv50_dac_enable(struct drm_encoder *encoder) { - struct nv50_mast *mast = nv50_mast(encoder->dev); + struct nv50_dmac *core = &nv50_disp(encoder->dev)->core->chan; struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); struct drm_display_mode *mode = &nv_crtc->base.state->adjusted_mode; @@ -2624,9 +2676,9 @@ nv50_dac_enable(struct drm_encoder *encoder) nv50_outp_acquire(nv_encoder); - push = evo_wait(mast, 8); + push = evo_wait(core, 8); if (push) { - if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { u32 syncs = 0x00000000; if (mode->flags & DRM_MODE_FLAG_NHSYNC) @@ -2656,7 +2708,7 @@ nv50_dac_enable(struct drm_encoder *encoder) evo_data(push, 1 << nv_crtc->index); } - evo_kick(push, mast); + evo_kick(push, core); } nv_encoder->crtc = encoder->crtc; @@ -3526,7 +3578,8 @@ static void nv50_sor_update(struct nouveau_encoder *nv_encoder, u8 head, struct drm_display_mode *mode, u8 proto, u8 depth) { - struct nv50_dmac *core = &nv50_mast(nv_encoder->base.base.dev)->base; + struct nv50_disp *disp = nv50_disp(nv_encoder->base.base.dev); + struct nv50_dmac *core = &disp->core->chan; u32 *push; if (!mode) { @@ -3809,18 +3862,18 @@ static void nv50_pior_disable(struct drm_encoder *encoder) { struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nv50_mast *mast = nv50_mast(encoder->dev); + struct nv50_dmac *core = &nv50_disp(encoder->dev)->core->chan; const int or = nv_encoder->or; u32 *push; if (nv_encoder->crtc) { - push = evo_wait(mast, 4); + push = evo_wait(core, 4); if (push) { - if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { evo_mthd(push, 0x0700 + (or * 0x040), 1); evo_data(push, 0x00000000); } - evo_kick(push, mast); + evo_kick(push, core); } } @@ -3831,7 +3884,7 @@ nv50_pior_disable(struct drm_encoder *encoder) static void nv50_pior_enable(struct drm_encoder *encoder) { - struct nv50_mast *mast = nv50_mast(encoder->dev); + struct nv50_dmac *core = &nv50_disp(encoder->dev)->core->chan; struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); struct nouveau_connector *nv_connector; @@ -3860,9 +3913,9 @@ nv50_pior_enable(struct drm_encoder *encoder) break; } - push = evo_wait(mast, 8); + push = evo_wait(core, 8); if (push) { - if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { u32 ctrl = (depth << 16) | (proto << 8) | owner; if (mode->flags & DRM_MODE_FLAG_NHSYNC) ctrl |= 0x00001000; @@ -3872,7 +3925,7 @@ nv50_pior_enable(struct drm_encoder *encoder) evo_data(push, ctrl); } - evo_kick(push, mast); + evo_kick(push, core); } nv_encoder->crtc = encoder->crtc; @@ -3950,7 +4003,7 @@ static void nv50_disp_atomic_commit_core(struct nouveau_drm *drm, u32 interlock) { struct nv50_disp *disp = nv50_disp(drm->dev); - struct nv50_dmac *core = &disp->mast.base; + struct nv50_dmac *core = &disp->core->chan; struct nv50_mstm *mstm; struct drm_encoder *encoder; u32 *push; @@ -4134,11 +4187,11 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) /* Flush update. */ if (interlock_core) { if (!interlock_chan && atom->state.legacy_cursor_update) { - u32 *push = evo_wait(&disp->mast, 2); + u32 *push = evo_wait(&disp->core->chan, 2); if (push) { evo_mthd(push, 0x0080, 1); evo_data(push, 0x00000000); - evo_kick(push, &disp->mast); + evo_kick(push, &disp->core->chan); } } else { nv50_disp_atomic_commit_core(drm, interlock_chan); @@ -4442,17 +4495,18 @@ nv50_display_fini(struct drm_device *dev) int nv50_display_init(struct drm_device *dev) { + struct nv50_dmac *core = &nv50_disp(dev)->core->chan; struct drm_encoder *encoder; struct drm_plane *plane; u32 *push; - push = evo_wait(nv50_mast(dev), 32); + push = evo_wait(core, 32); if (!push) return -EBUSY; evo_mthd(push, 0x0088, 1); - evo_data(push, nv50_mast(dev)->base.sync.handle); - evo_kick(push, nv50_mast(dev)); + evo_data(push, core->sync.handle); + evo_kick(push, core); list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) { @@ -4477,7 +4531,7 @@ nv50_display_destroy(struct drm_device *dev) { struct nv50_disp *disp = nv50_disp(dev); - nv50_dmac_destroy(&disp->mast.base); + nv50_core_del(&disp->core); nouveau_bo_unmap(disp->sync); if (disp->sync) @@ -4537,8 +4591,7 @@ nv50_display_create(struct drm_device *dev) goto out; /* allocate master evo channel */ - ret = nv50_core_create(device, &disp->disp->object, - disp->sync->bo.offset, &disp->mast); + ret = nv50_core_new(drm, &disp->core); if (ret) goto out; From 10ffe0fad53308ff54da0c6b1c5befca4e6915a1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 112/165] drm/nouveau/kms/nv50-: abstract head interfaces so the code can be split Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 64 +++++++++++++++++++------ 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index abdf39ed9d261..a23a33de401dc 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -436,6 +436,7 @@ struct nv50_sync { }; struct nv50_head { + const struct nv50_head_func *func; struct nouveau_crtc base; struct { struct nouveau_bo *nvbo[2]; @@ -443,7 +444,22 @@ struct nv50_head { } lut; }; -#define nv50_head(c) ((struct nv50_head *)nouveau_crtc(c)) +struct nv50_head_func { + void (*view)(struct nv50_head *, struct nv50_head_atom *); + void (*mode)(struct nv50_head *, struct nv50_head_atom *); + void (*ilut_set)(struct nv50_head *, struct nv50_head_atom *); + void (*ilut_clr)(struct nv50_head *); + void (*core_set)(struct nv50_head *, struct nv50_head_atom *); + void (*core_clr)(struct nv50_head *); + void (*curs_set)(struct nv50_head *, struct nv50_head_atom *); + void (*curs_clr)(struct nv50_head *); + void (*base)(struct nv50_head *, struct nv50_head_atom *); + void (*ovly)(struct nv50_head *, struct nv50_head_atom *); + void (*dither)(struct nv50_head *, struct nv50_head_atom *); + void (*procamp)(struct nv50_head *, struct nv50_head_atom *); +}; + +#define nv50_head(c) container_of((c), struct nv50_head, base.base) struct nv50_disp { struct nvif_disp *disp; @@ -470,6 +486,7 @@ struct nv50_core { }; struct nv50_core_func { + const struct nv50_head_func *head; }; static int @@ -2002,22 +2019,38 @@ nv50_head_view(struct nv50_head *head, struct nv50_head_atom *asyh) } } +static const struct nv50_head_func +head507d = { + .view = nv50_head_view, + .mode = nv50_head_mode, + .ilut_set = nv50_head_lut_set, + .ilut_clr = nv50_head_lut_clr, + .core_set = nv50_head_core_set, + .core_clr = nv50_head_core_clr, + .curs_set = nv50_head_curs_set, + .curs_clr = nv50_head_curs_clr, + .base = nv50_head_base, + .ovly = nv50_head_ovly, + .dither = nv50_head_dither, + .procamp = nv50_head_procamp, +}; + static void nv50_head_flush_clr(struct nv50_head *head, struct nv50_head_atom *asyh, bool y) { if (asyh->clr.ilut && (!asyh->set.ilut || y)) - nv50_head_lut_clr(head); + head->func->ilut_clr(head); if (asyh->clr.core && (!asyh->set.core || y)) - nv50_head_core_clr(head); + head->func->core_clr(head); if (asyh->clr.curs && (!asyh->set.curs || y)) - nv50_head_curs_clr(head); + head->func->curs_clr(head); } static void nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh) { - if (asyh->set.view ) nv50_head_view (head, asyh); - if (asyh->set.mode ) nv50_head_mode (head, asyh); + if (asyh->set.view ) head->func->view (head, asyh); + if (asyh->set.mode ) head->func->mode (head, asyh); if (asyh->set.ilut ) { struct nouveau_bo *nvbo = head->lut.nvbo[head->lut.next]; struct drm_property_blob *blob = asyh->state.gamma_lut; @@ -2025,14 +2058,14 @@ nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh) nv50_head_lut_load(blob, asyh->lut.mode, nvbo); asyh->lut.offset = nvbo->bo.offset; head->lut.next ^= 1; - nv50_head_lut_set(head, asyh); + head->func->ilut_set(head, asyh); } - if (asyh->set.core ) nv50_head_core_set(head, asyh); - if (asyh->set.curs ) nv50_head_curs_set(head, asyh); - if (asyh->set.base ) nv50_head_base (head, asyh); - if (asyh->set.ovly ) nv50_head_ovly (head, asyh); - if (asyh->set.dither ) nv50_head_dither (head, asyh); - if (asyh->set.procamp) nv50_head_procamp (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); + if (asyh->set.procamp) head->func->procamp (head, asyh); } static void @@ -2422,7 +2455,7 @@ nv50_head_destroy(struct drm_crtc *crtc) nouveau_bo_unmap_unpin_unref(&head->lut.nvbo[i]); drm_crtc_cleanup(crtc); - kfree(crtc); + kfree(head); } static const struct drm_crtc_funcs @@ -2440,6 +2473,7 @@ static int nv50_head_create(struct drm_device *dev, int index) { struct nouveau_drm *drm = nouveau_drm(dev); + struct nv50_disp *disp = nv50_disp(dev); struct nv50_head *head; struct nv50_wndw *curs, *wndw; struct drm_crtc *crtc; @@ -2449,6 +2483,7 @@ nv50_head_create(struct drm_device *dev, int index) if (!head) return -ENOMEM; + head->func = disp->core->func->head; head->base.index = index; ret = nv50_base_new(drm, head->base.index, &wndw); if (ret == 0) @@ -2482,6 +2517,7 @@ nv50_head_create(struct drm_device *dev, int index) static const struct nv50_core_func core507d = { + .head = &head507d, }; static int From 2ca7fb5c1cc69ee7fc1a3c048c6f2b75cf842df9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 113/165] drm/nouveau/kms/nv50: handle SetControlOutputResource from head Removes duplicated code from OR-specific functions. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 115 +++++++++++----------- drivers/gpu/drm/nouveau/nouveau_encoder.h | 3 +- 2 files changed, 57 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index a23a33de401dc..f22c6373fcc26 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -194,6 +194,12 @@ struct nv50_head_atom { } sat; } procamp; + struct { + u8 nhsync:1; + u8 nvsync:1; + u8 depth:4; + } or; + union { struct { bool ilut:1; @@ -214,6 +220,7 @@ struct nv50_head_atom { bool ovly:1; bool dither:1; bool procamp:1; + bool or:1; }; u16 mask; } set; @@ -457,6 +464,7 @@ struct nv50_head_func { void (*ovly)(struct nv50_head *, struct nv50_head_atom *); void (*dither)(struct nv50_head *, struct nv50_head_atom *); void (*procamp)(struct nv50_head *, struct nv50_head_atom *); + void (*or)(struct nv50_head *, struct nv50_head_atom *); }; #define nv50_head(c) container_of((c), struct nv50_head, base.base) @@ -1627,6 +1635,23 @@ nv50_base_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) /****************************************************************************** * Head *****************************************************************************/ +static void +head907d_or(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if (core->base.user.oclass >= GF110_DISP_CORE_CHANNEL_DMA && + (push = evo_wait(core, 2))) { + evo_mthd(push, 0x0404 + (head->base.index * 0x300), 2); + evo_data(push, 0x00000001 | (asyh->or.depth << 6) | + (asyh->or.nvsync << 4) | + (asyh->or.nhsync << 3)); + evo_data(push, 0x31ec6000 | (head->base.index << 25) | + asyh->mode.interlace); + evo_kick(push, core); + } +} + static void nv50_head_procamp(struct nv50_head *head, struct nv50_head_atom *asyh) { @@ -2033,6 +2058,7 @@ head507d = { .ovly = nv50_head_ovly, .dither = nv50_head_dither, .procamp = nv50_head_procamp, + .or = head907d_or, }; static void @@ -2066,6 +2092,7 @@ nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh) if (asyh->set.ovly ) head->func->ovly (head, asyh); if (asyh->set.dither ) head->func->dither (head, asyh); if (asyh->set.procamp) head->func->procamp (head, asyh); + if (asyh->set.or ) head->func->or (head, asyh); } static void @@ -2268,6 +2295,9 @@ nv50_head_atomic_check_mode(struct nv50_head *head, struct nv50_head_atom *asyh) } m->clock = mode->crtc_clock; + asyh->or.nhsync = !!(mode->flags & DRM_MODE_FLAG_NHSYNC); + asyh->or.nvsync = !!(mode->flags & DRM_MODE_FLAG_NVSYNC); + asyh->set.or = head->func->or != NULL; asyh->set.mode = true; } @@ -2304,6 +2334,7 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) if (asyc) asyc->set.mask = ~0; asyh->set.mask = ~0; + asyh->set.or = head->func->or != NULL; } if (asyh->state.mode_changed) @@ -2707,7 +2738,7 @@ nv50_dac_enable(struct drm_encoder *encoder) struct nv50_dmac *core = &nv50_disp(encoder->dev)->core->chan; struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); - struct drm_display_mode *mode = &nv_crtc->base.state->adjusted_mode; + struct nv50_head_atom *asyh = nv50_head_atom(nv_crtc->base.state); u32 *push; nv50_outp_acquire(nv_encoder); @@ -2715,37 +2746,17 @@ nv50_dac_enable(struct drm_encoder *encoder) push = evo_wait(core, 8); if (push) { if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - u32 syncs = 0x00000000; - - if (mode->flags & DRM_MODE_FLAG_NHSYNC) - syncs |= 0x00000001; - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - syncs |= 0x00000002; - evo_mthd(push, 0x0400 + (nv_encoder->or * 0x080), 2); evo_data(push, 1 << nv_crtc->index); - evo_data(push, syncs); + evo_data(push, (asyh->or.nvsync << 1) | asyh->or.nhsync); } else { - u32 magic = 0x31ec6000 | (nv_crtc->index << 25); - u32 syncs = 0x00000001; - - if (mode->flags & DRM_MODE_FLAG_NHSYNC) - syncs |= 0x00000008; - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - syncs |= 0x00000010; - - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - magic |= 0x00000001; - - evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2); - evo_data(push, syncs); - evo_data(push, magic); evo_mthd(push, 0x0180 + (nv_encoder->or * 0x020), 1); evo_data(push, 1 << nv_crtc->index); } evo_kick(push, core); } + asyh->or.depth = 0; nv_encoder->crtc = encoder->crtc; } @@ -3144,7 +3155,7 @@ nv50_msto_enable(struct drm_encoder *encoder) } mstm->outp->update(mstm->outp, head->base.index, - &head->base.base.state->adjusted_mode, proto, depth); + nv50_head_atom(head->base.base.state), proto, depth); msto->head = head; msto->mstc = mstc; @@ -3612,46 +3623,31 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max, *****************************************************************************/ static void nv50_sor_update(struct nouveau_encoder *nv_encoder, u8 head, - struct drm_display_mode *mode, u8 proto, u8 depth) + struct nv50_head_atom *asyh, u8 proto, u8 depth) { struct nv50_disp *disp = nv50_disp(nv_encoder->base.base.dev); struct nv50_dmac *core = &disp->core->chan; u32 *push; - if (!mode) { + if (!asyh) { nv_encoder->ctrl &= ~BIT(head); if (!(nv_encoder->ctrl & 0x0000000f)) nv_encoder->ctrl = 0; } else { nv_encoder->ctrl |= proto << 8; nv_encoder->ctrl |= BIT(head); + asyh->or.depth = depth; } if ((push = evo_wait(core, 6))) { if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - if (mode) { - if (mode->flags & DRM_MODE_FLAG_NHSYNC) - nv_encoder->ctrl |= 0x00001000; - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - nv_encoder->ctrl |= 0x00002000; - nv_encoder->ctrl |= depth << 16; + if (asyh) { + nv_encoder->ctrl |= asyh->or.depth << 16 | + asyh->or.nvsync << 13 | + asyh->or.nhsync << 12; } evo_mthd(push, 0x0600 + (nv_encoder->or * 0x40), 1); } else { - if (mode) { - u32 magic = 0x31ec6000 | (head << 25); - u32 syncs = 0x00000001; - if (mode->flags & DRM_MODE_FLAG_NHSYNC) - syncs |= 0x00000008; - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - syncs |= 0x00000010; - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - magic |= 0x00000001; - - evo_mthd(push, 0x0404 + (head * 0x300), 2); - evo_data(push, syncs | (depth << 6)); - evo_data(push, magic); - } evo_mthd(push, 0x0200 + (nv_encoder->or * 0x20), 1); } evo_data(push, nv_encoder->ctrl); @@ -3692,7 +3688,8 @@ nv50_sor_enable(struct drm_encoder *encoder) { struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); - struct drm_display_mode *mode = &nv_crtc->base.state->adjusted_mode; + struct nv50_head_atom *asyh = nv50_head_atom(nv_crtc->base.state); + struct drm_display_mode *mode = &asyh->state.adjusted_mode; struct { struct nv50_disp_mthd_v1 base; struct nv50_disp_sor_lvds_script_v0 lvds; @@ -3786,7 +3783,7 @@ nv50_sor_enable(struct drm_encoder *encoder) break; } - nv_encoder->update(nv_encoder, nv_crtc->index, mode, proto, depth); + nv_encoder->update(nv_encoder, nv_crtc->index, asyh, proto, depth); } static const struct drm_encoder_helper_funcs @@ -3924,19 +3921,19 @@ nv50_pior_enable(struct drm_encoder *encoder) struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); struct nouveau_connector *nv_connector; - struct drm_display_mode *mode = &nv_crtc->base.state->adjusted_mode; + struct nv50_head_atom *asyh = nv50_head_atom(nv_crtc->base.state); u8 owner = 1 << nv_crtc->index; - u8 proto, depth; + u8 proto; u32 *push; nv50_outp_acquire(nv_encoder); nv_connector = nouveau_encoder_connector_get(nv_encoder); switch (nv_connector->base.display_info.bpc) { - case 10: depth = 0x6; break; - case 8: depth = 0x5; break; - case 6: depth = 0x2; break; - default: depth = 0x0; break; + case 10: asyh->or.depth = 0x6; break; + case 8: asyh->or.depth = 0x5; break; + case 6: asyh->or.depth = 0x2; break; + default: asyh->or.depth = 0x0; break; } switch (nv_encoder->dcb->type) { @@ -3952,13 +3949,11 @@ nv50_pior_enable(struct drm_encoder *encoder) push = evo_wait(core, 8); if (push) { if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - u32 ctrl = (depth << 16) | (proto << 8) | owner; - if (mode->flags & DRM_MODE_FLAG_NHSYNC) - ctrl |= 0x00001000; - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - ctrl |= 0x00002000; evo_mthd(push, 0x0700 + (nv_encoder->or * 0x040), 1); - evo_data(push, ctrl); + evo_data(push, (asyh->or.depth << 16) | + (asyh->or.nvsync << 13) | + (asyh->or.nhsync << 12) | + (proto << 8) | owner); } evo_kick(push, core); diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h index e28d966946a1d..3517f920bf893 100644 --- a/drivers/gpu/drm/nouveau/nouveau_encoder.h +++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h @@ -32,6 +32,7 @@ #include #include #include "dispnv04/disp.h" +struct nv50_head_atom; #define NV_DPMS_CLEARED 0x80 @@ -68,7 +69,7 @@ struct nouveau_encoder { void (*enc_save)(struct drm_encoder *encoder); void (*enc_restore)(struct drm_encoder *encoder); void (*update)(struct nouveau_encoder *, u8 head, - struct drm_display_mode *, u8 proto, u8 depth); + struct nv50_head_atom *, u8 proto, u8 depth); }; struct nouveau_encoder * From 0a3687716bb0a53a363b63cb5ba2bddc14c3bd2a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 114/165] drm/nouveau/kms/nv50: abstract OR interfaces so the code can be split Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 180 ++++++++++++++---------- 1 file changed, 102 insertions(+), 78 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index f22c6373fcc26..995109ee57624 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -495,6 +495,14 @@ struct nv50_core { struct nv50_core_func { const struct nv50_head_func *head; + const struct nv50_outp_func *dac; + const struct nv50_outp_func *sor; + const struct nv50_outp_func *pior; +}; + +struct nv50_outp_func { + void (*ctrl)(struct nv50_core *, int or, u32 ctrl, + struct nv50_head_atom *); }; static int @@ -1641,7 +1649,7 @@ head907d_or(struct nv50_head *head, struct nv50_head_atom *asyh) struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if (core->base.user.oclass >= GF110_DISP_CORE_CHANNEL_DMA && - (push = evo_wait(core, 2))) { + (push = evo_wait(core, 3))) { evo_mthd(push, 0x0404 + (head->base.index * 0x300), 2); evo_data(push, 0x00000001 | (asyh->or.depth << 6) | (asyh->or.nvsync << 4) | @@ -2546,9 +2554,15 @@ nv50_head_create(struct drm_device *dev, int index) return ret; } +static const struct nv50_outp_func dac507d; +static const struct nv50_outp_func sor507d; +static const struct nv50_outp_func pior507d; static const struct nv50_core_func core507d = { .head = &head507d, + .dac = &dac507d, + .sor = &sor507d, + .pior = &pior507d, }; static int @@ -2707,27 +2721,39 @@ nv50_outp_atomic_check(struct drm_encoder *encoder, * DAC *****************************************************************************/ static void -nv50_dac_disable(struct drm_encoder *encoder) +dac507d_ctrl(struct nv50_core *core, int or, u32 ctrl, + struct nv50_head_atom *asyh) { - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nv50_dmac *core = &nv50_disp(encoder->dev)->core->chan; - const int or = nv_encoder->or; - u32 *push; - - if (nv_encoder->crtc) { - push = evo_wait(core, 4); - if (push) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0400 + (or * 0x080), 1); - evo_data(push, 0x00000000); - } else { - evo_mthd(push, 0x0180 + (or * 0x020), 1); - evo_data(push, 0x00000000); + u32 *push, sync = 0; + if ((push = evo_wait(&core->chan, 3))) { + if (core->chan.base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { + if (asyh) { + sync |= asyh->or.nvsync << 1; + sync |= asyh->or.nhsync; } - evo_kick(push, core); + evo_mthd(push, 0x0400 + (or * 0x080), 2); + evo_data(push, ctrl); + evo_data(push, sync); + } else { + evo_mthd(push, 0x0180 + (or * 0x020), 1); + evo_data(push, ctrl); } + evo_kick(push, &core->chan); } +} + +static const struct nv50_outp_func +dac507d = { + .ctrl = dac507d_ctrl, +}; +static void +nv50_dac_disable(struct drm_encoder *encoder) +{ + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); + struct nv50_core *core = nv50_disp(encoder->dev)->core; + if (nv_encoder->crtc) + core->func->dac->ctrl(core, nv_encoder->or, 0x00000000, NULL); nv_encoder->crtc = NULL; nv50_outp_release(nv_encoder); } @@ -2735,27 +2761,14 @@ nv50_dac_disable(struct drm_encoder *encoder) static void nv50_dac_enable(struct drm_encoder *encoder) { - struct nv50_dmac *core = &nv50_disp(encoder->dev)->core->chan; struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); struct nv50_head_atom *asyh = nv50_head_atom(nv_crtc->base.state); - u32 *push; + struct nv50_core *core = nv50_disp(encoder->dev)->core; nv50_outp_acquire(nv_encoder); - push = evo_wait(core, 8); - if (push) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0400 + (nv_encoder->or * 0x080), 2); - evo_data(push, 1 << nv_crtc->index); - evo_data(push, (asyh->or.nvsync << 1) | asyh->or.nhsync); - } else { - evo_mthd(push, 0x0180 + (nv_encoder->or * 0x020), 1); - evo_data(push, 1 << nv_crtc->index); - } - - evo_kick(push, core); - } + core->func->dac->ctrl(core, nv_encoder->or, 1 << nv_crtc->index, asyh); asyh->or.depth = 0; nv_encoder->crtc = encoder->crtc; @@ -3621,13 +3634,38 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max, /****************************************************************************** * SOR *****************************************************************************/ +static void +sor507d_ctrl(struct nv50_core *core, int or, u32 ctrl, + struct nv50_head_atom *asyh) +{ + u32 *push; + if ((push = evo_wait(&core->chan, 6))) { + if (core->chan.base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { + if (asyh) { + ctrl |= asyh->or.depth << 16; + ctrl |= asyh->or.nvsync << 13; + ctrl |= asyh->or.nhsync << 12; + } + evo_mthd(push, 0x0600 + (or * 0x40), 1); + } else { + evo_mthd(push, 0x0200 + (or * 0x20), 1); + } + evo_data(push, ctrl); + evo_kick(push, &core->chan); + } +} + +static const struct nv50_outp_func +sor507d = { + .ctrl = sor507d_ctrl, +}; + static void nv50_sor_update(struct nouveau_encoder *nv_encoder, u8 head, struct nv50_head_atom *asyh, u8 proto, u8 depth) { struct nv50_disp *disp = nv50_disp(nv_encoder->base.base.dev); - struct nv50_dmac *core = &disp->core->chan; - u32 *push; + struct nv50_core *core = disp->core; if (!asyh) { nv_encoder->ctrl &= ~BIT(head); @@ -3639,20 +3677,7 @@ nv50_sor_update(struct nouveau_encoder *nv_encoder, u8 head, asyh->or.depth = depth; } - if ((push = evo_wait(core, 6))) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - if (asyh) { - nv_encoder->ctrl |= asyh->or.depth << 16 | - asyh->or.nvsync << 13 | - asyh->or.nhsync << 12; - } - evo_mthd(push, 0x0600 + (nv_encoder->or * 0x40), 1); - } else { - evo_mthd(push, 0x0200 + (nv_encoder->or * 0x20), 1); - } - evo_data(push, nv_encoder->ctrl); - evo_kick(push, core); - } + core->func->sor->ctrl(core, nv_encoder->or, nv_encoder->ctrl, asyh); } static void @@ -3879,6 +3904,30 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe) /****************************************************************************** * PIOR *****************************************************************************/ +static void +pior507d_ctrl(struct nv50_core *core, int or, u32 ctrl, + struct nv50_head_atom *asyh) +{ + u32 *push; + if ((push = evo_wait(&core->chan, 8))) { + if (core->chan.base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { + if (asyh) { + ctrl |= asyh->or.depth << 16; + ctrl |= asyh->or.nvsync << 13; + ctrl |= asyh->or.nhsync << 12; + } + evo_mthd(push, 0x0700 + (or * 0x040), 1); + evo_data(push, ctrl); + } + evo_kick(push, &core->chan); + } +} + +static const struct nv50_outp_func +pior507d = { + .ctrl = pior507d_ctrl, +}; + static int nv50_pior_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, @@ -3895,21 +3944,9 @@ static void nv50_pior_disable(struct drm_encoder *encoder) { struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nv50_dmac *core = &nv50_disp(encoder->dev)->core->chan; - const int or = nv_encoder->or; - u32 *push; - - if (nv_encoder->crtc) { - push = evo_wait(core, 4); - if (push) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0700 + (or * 0x040), 1); - evo_data(push, 0x00000000); - } - evo_kick(push, core); - } - } - + struct nv50_core *core = nv50_disp(encoder->dev)->core; + if (nv_encoder->crtc) + core->func->pior->ctrl(core, nv_encoder->or, 0x00000000, NULL); nv_encoder->crtc = NULL; nv50_outp_release(nv_encoder); } @@ -3917,14 +3954,13 @@ nv50_pior_disable(struct drm_encoder *encoder) static void nv50_pior_enable(struct drm_encoder *encoder) { - struct nv50_dmac *core = &nv50_disp(encoder->dev)->core->chan; struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); struct nouveau_connector *nv_connector; struct nv50_head_atom *asyh = nv50_head_atom(nv_crtc->base.state); + struct nv50_core *core = nv50_disp(encoder->dev)->core; u8 owner = 1 << nv_crtc->index; u8 proto; - u32 *push; nv50_outp_acquire(nv_encoder); @@ -3946,19 +3982,7 @@ nv50_pior_enable(struct drm_encoder *encoder) break; } - push = evo_wait(core, 8); - if (push) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0700 + (nv_encoder->or * 0x040), 1); - evo_data(push, (asyh->or.depth << 16) | - (asyh->or.nvsync << 13) | - (asyh->or.nhsync << 12) | - (proto << 8) | owner); - } - - evo_kick(push, core); - } - + core->func->pior->ctrl(core, nv_encoder->or, (proto << 8) | owner, asyh); nv_encoder->crtc = encoder->crtc; } From 1590700d94ac53772491ed3103a4e8b8de01640a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 115/165] drm/nouveau/kms/nv50-: split each resource type into their own source files There should be no code changes here, just shuffling stuff around. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/Kbuild | 26 + drivers/gpu/drm/nouveau/dispnv50/atom.h | 207 ++ drivers/gpu/drm/nouveau/dispnv50/base.c | 53 + drivers/gpu/drm/nouveau/dispnv50/base.h | 8 + drivers/gpu/drm/nouveau/dispnv50/base507c.c | 307 +++ drivers/gpu/drm/nouveau/dispnv50/core.c | 69 + drivers/gpu/drm/nouveau/dispnv50/core.h | 26 + drivers/gpu/drm/nouveau/dispnv50/core507d.c | 65 + drivers/gpu/drm/nouveau/dispnv50/curs.c | 51 + drivers/gpu/drm/nouveau/dispnv50/curs.h | 8 + drivers/gpu/drm/nouveau/dispnv50/curs507a.c | 151 + drivers/gpu/drm/nouveau/dispnv50/dac507d.c | 51 + drivers/gpu/drm/nouveau/dispnv50/disp.c | 2751 +------------------ drivers/gpu/drm/nouveau/dispnv50/disp.h | 71 + drivers/gpu/drm/nouveau/dispnv50/head.c | 566 ++++ drivers/gpu/drm/nouveau/dispnv50/head.h | 39 + drivers/gpu/drm/nouveau/dispnv50/head507d.c | 403 +++ drivers/gpu/drm/nouveau/dispnv50/oimm.c | 51 + drivers/gpu/drm/nouveau/dispnv50/oimm.h | 8 + drivers/gpu/drm/nouveau/dispnv50/oimm507b.c | 56 + drivers/gpu/drm/nouveau/dispnv50/ovly.c | 57 + drivers/gpu/drm/nouveau/dispnv50/ovly.h | 8 + drivers/gpu/drm/nouveau/dispnv50/ovly507e.c | 70 + drivers/gpu/drm/nouveau/dispnv50/pior507d.c | 48 + drivers/gpu/drm/nouveau/dispnv50/sor507d.c | 50 + drivers/gpu/drm/nouveau/dispnv50/wndw.c | 434 +++ drivers/gpu/drm/nouveau/dispnv50/wndw.h | 73 + drivers/gpu/drm/nouveau/nv50_display.h | 1 - 28 files changed, 3096 insertions(+), 2612 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/dispnv50/atom.h create mode 100644 drivers/gpu/drm/nouveau/dispnv50/base.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/base.h create mode 100644 drivers/gpu/drm/nouveau/dispnv50/base507c.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/core.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/core.h create mode 100644 drivers/gpu/drm/nouveau/dispnv50/core507d.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/curs.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/curs.h create mode 100644 drivers/gpu/drm/nouveau/dispnv50/curs507a.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/dac507d.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/disp.h create mode 100644 drivers/gpu/drm/nouveau/dispnv50/head.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/head.h create mode 100644 drivers/gpu/drm/nouveau/dispnv50/head507d.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/oimm.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/oimm.h create mode 100644 drivers/gpu/drm/nouveau/dispnv50/oimm507b.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/ovly.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/ovly.h create mode 100644 drivers/gpu/drm/nouveau/dispnv50/ovly507e.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/pior507d.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/sor507d.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/wndw.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/wndw.h diff --git a/drivers/gpu/drm/nouveau/dispnv50/Kbuild b/drivers/gpu/drm/nouveau/dispnv50/Kbuild index 43fc8be49391d..f3877d2d88407 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/Kbuild +++ b/drivers/gpu/drm/nouveau/dispnv50/Kbuild @@ -1 +1,27 @@ nouveau-y += dispnv50/disp.o + +nouveau-y += dispnv50/core.o +nouveau-y += dispnv50/core507d.o + +nouveau-y += dispnv50/dac507d.o + +nouveau-y += dispnv50/pior507d.o + +nouveau-y += dispnv50/sor507d.o + +nouveau-y += dispnv50/head.o +nouveau-y += dispnv50/head507d.o + +nouveau-y += dispnv50/wndw.o + +nouveau-y += dispnv50/base.o +nouveau-y += dispnv50/base507c.o + +nouveau-y += dispnv50/curs.o +nouveau-y += dispnv50/curs507a.o + +nouveau-y += dispnv50/oimm.o +nouveau-y += dispnv50/oimm507b.o + +nouveau-y += dispnv50/ovly.o +nouveau-y += dispnv50/ovly507e.o diff --git a/drivers/gpu/drm/nouveau/dispnv50/atom.h b/drivers/gpu/drm/nouveau/dispnv50/atom.h new file mode 100644 index 0000000000000..8c97e25c881f0 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h @@ -0,0 +1,207 @@ +#ifndef __NV50_KMS_ATOM_H__ +#define __NV50_KMS_ATOM_H__ +#define nv50_atom(p) container_of((p), struct nv50_atom, state) +#include + +struct nv50_atom { + struct drm_atomic_state state; + + struct list_head outp; + bool lock_core; + bool flush_disable; +}; + +#define nv50_head_atom(p) container_of((p), struct nv50_head_atom, state) + +struct nv50_head_atom { + struct drm_crtc_state state; + + struct { + u16 iW; + u16 iH; + u16 oW; + u16 oH; + } view; + + struct nv50_head_mode { + bool interlace; + u32 clock; + struct { + u16 active; + u16 synce; + u16 blanke; + u16 blanks; + } h; + struct { + u32 active; + u16 synce; + u16 blanke; + u16 blanks; + u16 blank2s; + u16 blank2e; + u16 blankus; + } v; + } mode; + + struct { + bool visible; + u32 handle; + u64 offset:40; + u8 mode:4; + } ilut; + + struct { + bool visible; + u32 handle; + u64 offset:40; + u8 format; + u8 kind:7; + u8 layout:1; + u8 block:4; + u32 pitch:20; + u16 x; + u16 y; + u16 w; + u16 h; + } core; + + struct { + bool visible; + u32 handle; + u64 offset:40; + u8 layout:1; + u8 format:1; + } curs; + + struct { + u8 depth; + u8 cpp; + u16 x; + u16 y; + u16 w; + u16 h; + } base; + + struct { + u8 cpp; + } ovly; + + struct { + bool enable:1; + u8 bits:2; + u8 mode:4; + } dither; + + struct { + struct { + u16 cos:12; + u16 sin:12; + } sat; + } procamp; + + struct { + u8 nhsync:1; + u8 nvsync:1; + u8 depth:4; + } or; + + union { + struct { + bool ilut:1; + bool core:1; + bool curs:1; + }; + u8 mask; + } clr; + + union { + struct { + bool ilut:1; + bool core:1; + bool curs:1; + bool view:1; + bool mode:1; + bool base:1; + bool ovly:1; + bool dither:1; + bool procamp:1; + bool or:1; + }; + u16 mask; + } set; +}; + +static inline struct nv50_head_atom * +nv50_head_atom_get(struct drm_atomic_state *state, struct drm_crtc *crtc) +{ + struct drm_crtc_state *statec = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(statec)) + return (void *)statec; + return nv50_head_atom(statec); +} + +#define nv50_wndw_atom(p) container_of((p), struct nv50_wndw_atom, state) + +struct nv50_wndw_atom { + struct drm_plane_state state; + u8 interval; + + struct { + u32 handle; + u16 offset:12; + bool awaken:1; + } ntfy; + + struct { + u32 handle; + u16 offset:12; + u32 acquire; + u32 release; + } sema; + + struct { + u8 enable:2; + } lut; + + struct { + u8 mode:2; + u8 interval:4; + + u8 format; + u8 kind:7; + u8 layout:1; + u8 block:4; + u32 pitch:20; + u16 w; + u16 h; + + u32 handle; + u64 offset; + } image; + + struct { + u16 x; + u16 y; + } point; + + union { + struct { + bool ntfy:1; + bool sema:1; + bool image:1; + }; + u8 mask; + } clr; + + union { + struct { + bool ntfy:1; + bool sema:1; + bool image:1; + bool lut:1; + bool point:1; + }; + u8 mask; + } set; +}; +#endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/base.c b/drivers/gpu/drm/nouveau/dispnv50/base.c new file mode 100644 index 0000000000000..12ca5d70509c2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/base.c @@ -0,0 +1,53 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "base.h" + +#include + +int +nv50_base_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) +{ + struct { + s32 oclass; + int version; + int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); + } bases[] = { + { GK110_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, + { GK104_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, + { GF110_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, + { GT214_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, + { GT200_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, + { G82_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, + { NV50_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, + {} + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + int cid; + + cid = nvif_mclass(&disp->disp->object, bases); + if (cid < 0) { + NV_ERROR(drm, "No supported base class\n"); + return cid; + } + + return bases[cid].new(drm, head, bases[cid].oclass, pwndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/base.h b/drivers/gpu/drm/nouveau/dispnv50/base.h new file mode 100644 index 0000000000000..1daba7319ba98 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/base.h @@ -0,0 +1,8 @@ +#ifndef __NV50_KMS_BASE_H__ +#define __NV50_KMS_BASE_H__ +#include "wndw.h" + +int base507c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); + +int nv50_base_new(struct nouveau_drm *, int head, struct nv50_wndw **); +#endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/base507c.c b/drivers/gpu/drm/nouveau/dispnv50/base507c.c new file mode 100644 index 0000000000000..b73e7b4d86a56 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/base507c.c @@ -0,0 +1,307 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "base.h" + +#include +#include +#include + +#include +#include +#include "nouveau_bo.h" + +static u32 +base507c_update(struct nv50_wndw *wndw, u32 interlock) +{ + u32 *push; + + if (!(push = evo_wait(&wndw->wndw, 2))) + return 0; + evo_mthd(push, 0x0080, 1); + evo_data(push, interlock); + evo_kick(push, &wndw->wndw); + + if (wndw->wndw.base.user.oclass < GF110_DISP_BASE_CHANNEL_DMA) + return interlock ? 2 << (wndw->id * 8) : 0; + return interlock ? 2 << (wndw->id * 4) : 0; +} + +static void +base507c_lut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 2))) { + evo_mthd(push, 0x00e0, 1); + evo_data(push, asyw->lut.enable << 30); + evo_kick(push, &wndw->wndw); + } +} + +static void +base507c_image_clr(struct nv50_wndw *wndw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 4))) { + evo_mthd(push, 0x0084, 1); + evo_data(push, 0x00000000); + evo_mthd(push, 0x00c0, 1); + evo_data(push, 0x00000000); + evo_kick(push, &wndw->wndw); + } +} + +static void +base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + const s32 oclass = wndw->wndw.base.user.oclass; + u32 *push; + if ((push = evo_wait(&wndw->wndw, 10))) { + evo_mthd(push, 0x0084, 1); + evo_data(push, asyw->image.mode << 8 | + asyw->image.interval << 4); + evo_mthd(push, 0x00c0, 1); + evo_data(push, asyw->image.handle); + if (oclass < G82_DISP_BASE_CHANNEL_DMA) { + evo_mthd(push, 0x0800, 5); + evo_data(push, asyw->image.offset >> 8); + evo_data(push, 0x00000000); + evo_data(push, (asyw->image.h << 16) | asyw->image.w); + evo_data(push, (asyw->image.layout << 20) | + asyw->image.pitch | + asyw->image.block); + evo_data(push, (asyw->image.kind << 16) | + (asyw->image.format << 8)); + } else + if (oclass < GF110_DISP_BASE_CHANNEL_DMA) { + evo_mthd(push, 0x0800, 5); + evo_data(push, asyw->image.offset >> 8); + evo_data(push, 0x00000000); + evo_data(push, (asyw->image.h << 16) | asyw->image.w); + evo_data(push, (asyw->image.layout << 20) | + asyw->image.pitch | + asyw->image.block); + evo_data(push, asyw->image.format << 8); + } else { + evo_mthd(push, 0x0400, 5); + evo_data(push, asyw->image.offset >> 8); + evo_data(push, 0x00000000); + evo_data(push, (asyw->image.h << 16) | asyw->image.w); + evo_data(push, (asyw->image.layout << 24) | + asyw->image.pitch | + asyw->image.block); + evo_data(push, asyw->image.format << 8); + } + evo_kick(push, &wndw->wndw); + } +} + +static int +base507c_ntfy_wait_begun(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev); + struct nv50_disp *disp = nv50_disp(wndw->plane.dev); + if (nvif_msec(&drm->client.device, 2000ULL, + u32 data = nouveau_bo_rd32(disp->sync, asyw->ntfy.offset / 4); + if ((data & 0xc0000000) == 0x40000000) + break; + usleep_range(1, 2); + ) < 0) + return -ETIMEDOUT; + return 0; +} + +static void +base507c_ntfy_clr(struct nv50_wndw *wndw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 2))) { + evo_mthd(push, 0x00a4, 1); + evo_data(push, 0x00000000); + evo_kick(push, &wndw->wndw); + } +} + +static void +base507c_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 3))) { + evo_mthd(push, 0x00a0, 2); + evo_data(push, asyw->ntfy.awaken << 30 | asyw->ntfy.offset); + evo_data(push, asyw->ntfy.handle); + evo_kick(push, &wndw->wndw); + } +} + +static void +base507c_sema_clr(struct nv50_wndw *wndw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 2))) { + evo_mthd(push, 0x0094, 1); + evo_data(push, 0x00000000); + evo_kick(push, &wndw->wndw); + } +} + +static void +base507c_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 5))) { + evo_mthd(push, 0x0088, 4); + evo_data(push, asyw->sema.offset); + evo_data(push, asyw->sema.acquire); + evo_data(push, asyw->sema.release); + evo_data(push, asyw->sema.handle); + evo_kick(push, &wndw->wndw); + } +} + +static void +base507c_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, + struct nv50_head_atom *asyh) +{ + asyh->base.cpp = 0; +} + +static int +base507c_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, + struct nv50_head_atom *asyh) +{ + const struct drm_framebuffer *fb = asyw->state.fb; + int ret; + + if (!fb->format->depth) + return -EINVAL; + + ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state, + DRM_PLANE_HELPER_NO_SCALING, + DRM_PLANE_HELPER_NO_SCALING, + false, true); + if (ret) + return ret; + + asyh->base.depth = fb->format->depth; + asyh->base.cpp = fb->format->cpp[0]; + asyh->base.x = asyw->state.src.x1 >> 16; + asyh->base.y = asyw->state.src.y1 >> 16; + asyh->base.w = asyw->state.fb->width; + asyh->base.h = asyw->state.fb->height; + + switch (fb->format->format) { + case DRM_FORMAT_C8 : asyw->image.format = 0x1e; break; + case DRM_FORMAT_RGB565 : asyw->image.format = 0xe8; break; + case DRM_FORMAT_XRGB1555 : + case DRM_FORMAT_ARGB1555 : asyw->image.format = 0xe9; break; + case DRM_FORMAT_XRGB8888 : + case DRM_FORMAT_ARGB8888 : asyw->image.format = 0xcf; break; + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_ABGR2101010: asyw->image.format = 0xd1; break; + case DRM_FORMAT_XBGR8888 : + case DRM_FORMAT_ABGR8888 : asyw->image.format = 0xd5; break; + default: + WARN_ON(1); + return -EINVAL; + } + + asyw->lut.enable = 1; + asyw->set.image = true; + return 0; +} + +static const u32 +base507c_format[] = { + DRM_FORMAT_C8, + DRM_FORMAT_RGB565, + DRM_FORMAT_XRGB1555, + DRM_FORMAT_ARGB1555, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_XBGR2101010, + DRM_FORMAT_ABGR2101010, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_ABGR8888, + 0 +}; + +static const struct nv50_wndw_func +base507c = { + .acquire = base507c_acquire, + .release = base507c_release, + .sema_set = base507c_sema_set, + .sema_clr = base507c_sema_clr, + .ntfy_set = base507c_ntfy_set, + .ntfy_clr = base507c_ntfy_clr, + .ntfy_wait_begun = base507c_ntfy_wait_begun, + .image_set = base507c_image_set, + .image_clr = base507c_image_clr, + .lut = base507c_lut, + .update = base507c_update, +}; + +static int +base507c_new_(const struct nv50_wndw_func *func, const u32 *format, + struct nouveau_drm *drm, int head, s32 oclass, + struct nv50_wndw **pwndw) +{ + struct nv50_disp_base_channel_dma_v0 args = { + .head = head, + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + struct nv50_wndw *wndw; + int ret; + + ret = nv50_wndw_new_(func, drm->dev, DRM_PLANE_TYPE_PRIMARY, + "base", head, format, &wndw); + if (*pwndw = wndw, ret) + return ret; + + ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, + &oclass, head, &args, sizeof(args), + disp->sync->bo.offset, &wndw->wndw); + if (ret) { + NV_ERROR(drm, "base%04x allocation failed: %d\n", oclass, ret); + return ret; + } + + ret = nvif_notify_init(&wndw->wndw.base.user, wndw->notify.func, + false, NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT, + &(struct nvif_notify_uevent_req) {}, + sizeof(struct nvif_notify_uevent_req), + sizeof(struct nvif_notify_uevent_rep), + &wndw->notify); + if (ret) + return ret; + + wndw->ntfy = NV50_DISP_BASE_NTFY(wndw->id); + wndw->sema = NV50_DISP_BASE_SEM0(wndw->id); + wndw->data = 0x00000000; + return 0; +} + +int +base507c_new(struct nouveau_drm *drm, int head, s32 oclass, + struct nv50_wndw **pwndw) +{ + return base507c_new_(&base507c, base507c_format, drm, head, oclass, pwndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/core.c b/drivers/gpu/drm/nouveau/dispnv50/core.c new file mode 100644 index 0000000000000..b12899fe052a4 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/core.c @@ -0,0 +1,69 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "core.h" + +#include + +void +nv50_core_del(struct nv50_core **pcore) +{ + struct nv50_core *core = *pcore; + if (core) { + nv50_dmac_destroy(&core->chan); + kfree(*pcore); + *pcore = NULL; + } +} + +int +nv50_core_new(struct nouveau_drm *drm, struct nv50_core **pcore) +{ + struct { + s32 oclass; + int version; + int (*new)(struct nouveau_drm *, s32, struct nv50_core **); + } cores[] = { + { GP102_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GP100_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GM200_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GM107_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GK110_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GK104_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GF110_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GT214_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GT206_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GT200_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { G82_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { NV50_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + {} + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + int cid; + + cid = nvif_mclass(&disp->disp->object, cores); + if (cid < 0) { + NV_ERROR(drm, "No supported core channel class\n"); + return cid; + } + + return cores[cid].new(drm, cores[cid].oclass, pcore); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/core.h b/drivers/gpu/drm/nouveau/dispnv50/core.h new file mode 100644 index 0000000000000..3cd54469311aa --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/core.h @@ -0,0 +1,26 @@ +#ifndef __NV50_KMS_CORE_H__ +#define __NV50_KMS_CORE_H__ +#include "disp.h" +#include "atom.h" + +struct nv50_core { + const struct nv50_core_func *func; + struct nv50_dmac chan; +}; + +int nv50_core_new(struct nouveau_drm *, struct nv50_core **); +void nv50_core_del(struct nv50_core **); + +struct nv50_core_func { + const struct nv50_head_func *head; + const struct nv50_outp_func { + void (*ctrl)(struct nv50_core *, int or, u32 ctrl, + struct nv50_head_atom *); + } *dac, *pior, *sor; +}; + +int core507d_new(struct nouveau_drm *, s32, struct nv50_core **); +extern const struct nv50_outp_func dac507d; +extern const struct nv50_outp_func sor507d; +extern const struct nv50_outp_func pior507d; +#endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/core507d.c b/drivers/gpu/drm/nouveau/dispnv50/core507d.c new file mode 100644 index 0000000000000..b0325f69a26f6 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/core507d.c @@ -0,0 +1,65 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "core.h" +#include "head.h" + +#include + +#include "nouveau_bo.h" + +static const struct nv50_core_func +core507d = { + .head = &head507d, + .dac = &dac507d, + .sor = &sor507d, + .pior = &pior507d, +}; + +static int +core507d_new_(const struct nv50_core_func *func, struct nouveau_drm *drm, + s32 oclass, struct nv50_core **pcore) +{ + struct nv50_disp_core_channel_dma_v0 args = {}; + struct nv50_disp *disp = nv50_disp(drm->dev); + struct nv50_core *core; + int ret; + + if (!(core = *pcore = kzalloc(sizeof(*core), GFP_KERNEL))) + return -ENOMEM; + core->func = func; + + ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, + &oclass, 0, &args, sizeof(args), + disp->sync->bo.offset, &core->chan); + if (ret) { + NV_ERROR(drm, "core%04x allocation failed: %d\n", oclass, ret); + return ret; + } + + return 0; +} + +int +core507d_new(struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore) +{ + return core507d_new_(&core507d, drm, oclass, pcore); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs.c b/drivers/gpu/drm/nouveau/dispnv50/curs.c new file mode 100644 index 0000000000000..6d60e978db69d --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/curs.c @@ -0,0 +1,51 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "curs.h" + +#include + +int +nv50_curs_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) +{ + struct { + s32 oclass; + int version; + int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); + } curses[] = { + { GK104_DISP_CURSOR, 0, curs507a_new }, + { GF110_DISP_CURSOR, 0, curs507a_new }, + { GT214_DISP_CURSOR, 0, curs507a_new }, + { G82_DISP_CURSOR, 0, curs507a_new }, + { NV50_DISP_CURSOR, 0, curs507a_new }, + {} + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + int cid; + + cid = nvif_mclass(&disp->disp->object, curses); + if (cid < 0) { + NV_ERROR(drm, "No supported cursor immediate class\n"); + return cid; + } + + return curses[cid].new(drm, head, curses[cid].oclass, pwndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs.h b/drivers/gpu/drm/nouveau/dispnv50/curs.h new file mode 100644 index 0000000000000..b85ca9fa419c7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/curs.h @@ -0,0 +1,8 @@ +#ifndef __NV50_KMS_CURS_H__ +#define __NV50_KMS_CURS_H__ +#include "wndw.h" + +int curs507a_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); + +int nv50_curs_new(struct nouveau_drm *, int head, struct nv50_wndw **); +#endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c new file mode 100644 index 0000000000000..1a3e199b5b450 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c @@ -0,0 +1,151 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "curs.h" +#include "core.h" + +#include + +#include +#include + +static u32 +curs507a_update(struct nv50_wndw *wndw, u32 interlock) +{ + nvif_wr32(&wndw->wimm.base.user, 0x0080, 0x00000000); + return 0; +} + +static void +curs507a_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + nvif_wr32(&wndw->wimm.base.user, 0x0084, asyw->point.y << 16 | + asyw->point.x); +} + +static const struct nv50_wimm_func +curs507a = { + .point = curs507a_point, + .update = curs507a_update, +}; + +static void +curs507a_prepare(struct nv50_wndw *wndw, struct nv50_head_atom *asyh, + struct nv50_wndw_atom *asyw) +{ + u32 handle = nv50_disp(wndw->plane.dev)->core->chan.vram.handle; + u32 offset = asyw->image.offset; + if (asyh->curs.handle != handle || asyh->curs.offset != offset) { + asyh->curs.handle = handle; + asyh->curs.offset = offset; + asyh->set.curs = asyh->curs.visible; + } +} + +static void +curs507a_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, + struct nv50_head_atom *asyh) +{ + asyh->curs.visible = false; +} + +static int +curs507a_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, + struct nv50_head_atom *asyh) +{ + int ret; + + ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state, + DRM_PLANE_HELPER_NO_SCALING, + DRM_PLANE_HELPER_NO_SCALING, + true, true); + asyh->curs.visible = asyw->state.visible; + if (ret || !asyh->curs.visible) + return ret; + + switch (asyw->state.fb->width) { + case 32: asyh->curs.layout = 0; break; + case 64: asyh->curs.layout = 1; break; + default: + return -EINVAL; + } + + if (asyw->state.fb->width != asyw->state.fb->height) + return -EINVAL; + + switch (asyw->state.fb->format->format) { + case DRM_FORMAT_ARGB8888: asyh->curs.format = 1; break; + default: + WARN_ON(1); + return -EINVAL; + } + + return 0; +} + +static const u32 +curs507a_format[] = { + DRM_FORMAT_ARGB8888, + 0 +}; + +static const struct nv50_wndw_func +curs507a_wndw = { + .acquire = curs507a_acquire, + .release = curs507a_release, + .prepare = curs507a_prepare, +}; + +static int +curs507a_new_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, + int head, s32 oclass, struct nv50_wndw **pwndw) +{ + struct nv50_disp_cursor_v0 args = { + .head = head, + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + struct nv50_wndw *wndw; + int ret; + + ret = nv50_wndw_new_(&curs507a_wndw, drm->dev, DRM_PLANE_TYPE_CURSOR, + "curs", head, curs507a_format, &wndw); + if (*pwndw = wndw, ret) + return ret; + + ret = nvif_object_init(&disp->disp->object, 0, oclass, &args, + sizeof(args), &wndw->wimm.base.user); + if (ret) { + NV_ERROR(drm, "curs%04x allocation failed: %d\n", oclass, ret); + return ret; + } + + nvif_object_map(&wndw->wimm.base.user, NULL, 0); + wndw->immd = func; + wndw->ctxdma.parent = &disp->core->chan.base.user; + return 0; +} + +int +curs507a_new(struct nouveau_drm *drm, int head, s32 oclass, + struct nv50_wndw **pwndw) +{ + return curs507a_new_(&curs507a, drm, head, oclass, pwndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/dac507d.c b/drivers/gpu/drm/nouveau/dispnv50/dac507d.c new file mode 100644 index 0000000000000..28b6025a80f3d --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/dac507d.c @@ -0,0 +1,51 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "core.h" + +#include + +static void +dac507d_ctrl(struct nv50_core *core, int or, u32 ctrl, + struct nv50_head_atom *asyh) +{ + u32 *push, sync = 0; + if ((push = evo_wait(&core->chan, 3))) { + if (core->chan.base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { + if (asyh) { + sync |= asyh->or.nvsync << 1; + sync |= asyh->or.nhsync; + } + evo_mthd(push, 0x0400 + (or * 0x080), 2); + evo_data(push, ctrl); + evo_data(push, sync); + } else { + evo_mthd(push, 0x0180 + (or * 0x020), 1); + evo_data(push, ctrl); + } + evo_kick(push, &core->chan); + } +} + +const struct nv50_outp_func +dac507d = { + .ctrl = dac507d_ctrl, +}; diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 995109ee57624..a8367c5d4691b 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -21,12 +21,16 @@ * * Authors: Ben Skeggs */ +#include "disp.h" +#include "atom.h" +#include "core.h" +#include "head.h" +#include "wndw.h" #include #include #include -#include #include #include #include @@ -34,2586 +38,188 @@ #include #include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "nouveau_drv.h" -#include "nouveau_dma.h" -#include "nouveau_gem.h" -#include "nouveau_connector.h" -#include "nouveau_encoder.h" -#include "nouveau_crtc.h" -#include "nouveau_fence.h" -#include "nouveau_fbcon.h" -#include "nv50_display.h" - -#define EVO_DMA_NR 9 - -#define EVO_MASTER (0x00) -#define EVO_FLIP(c) (0x01 + (c)) -#define EVO_OVLY(c) (0x05 + (c)) -#define EVO_OIMM(c) (0x09 + (c)) -#define EVO_CURS(c) (0x0d + (c)) - -/* offsets in shared sync bo of various structures */ -#define EVO_SYNC(c, o) ((c) * 0x0100 + (o)) -#define EVO_MAST_NTFY EVO_SYNC( 0, 0x00) -#define EVO_FLIP_SEM0(c) EVO_SYNC((c) + 1, 0x00) -#define EVO_FLIP_SEM1(c) EVO_SYNC((c) + 1, 0x10) -#define EVO_FLIP_NTFY0(c) EVO_SYNC((c) + 1, 0x20) -#define EVO_FLIP_NTFY1(c) EVO_SYNC((c) + 1, 0x30) - -/****************************************************************************** - * Atomic state - *****************************************************************************/ -#define nv50_atom(p) container_of((p), struct nv50_atom, state) - -struct nv50_atom { - struct drm_atomic_state state; - - struct list_head outp; - bool lock_core; - bool flush_disable; -}; - -struct nv50_outp_atom { - struct list_head head; - - struct drm_encoder *encoder; - bool flush_disable; - - union { - struct { - bool ctrl:1; - }; - u8 mask; - } clr; - - union { - struct { - bool ctrl:1; - }; - u8 mask; - } set; -}; - -#define nv50_head_atom(p) container_of((p), struct nv50_head_atom, state) - -struct nv50_head_atom { - struct drm_crtc_state state; - - struct { - u16 iW; - u16 iH; - u16 oW; - u16 oH; - } view; - - struct nv50_head_mode { - bool interlace; - u32 clock; - struct { - u16 active; - u16 synce; - u16 blanke; - u16 blanks; - } h; - struct { - u32 active; - u16 synce; - u16 blanke; - u16 blanks; - u16 blank2s; - u16 blank2e; - u16 blankus; - } v; - } mode; - - struct { - bool visible; - u32 handle; - u64 offset:40; - u8 mode:4; - } lut; - - struct { - bool visible; - u32 handle; - u64 offset:40; - u8 format; - u8 kind:7; - u8 layout:1; - u8 block:4; - u32 pitch:20; - u16 x; - u16 y; - u16 w; - u16 h; - } core; - - struct { - bool visible; - u32 handle; - u64 offset:40; - u8 layout:1; - u8 format:1; - } curs; - - struct { - u8 depth; - u8 cpp; - u16 x; - u16 y; - u16 w; - u16 h; - } base; - - struct { - u8 cpp; - } ovly; - - struct { - bool enable:1; - u8 bits:2; - u8 mode:4; - } dither; - - struct { - struct { - u16 cos:12; - u16 sin:12; - } sat; - } procamp; - - struct { - u8 nhsync:1; - u8 nvsync:1; - u8 depth:4; - } or; - - union { - struct { - bool ilut:1; - bool core:1; - bool curs:1; - }; - u8 mask; - } clr; - - union { - struct { - bool ilut:1; - bool core:1; - bool curs:1; - bool view:1; - bool mode:1; - bool base:1; - bool ovly:1; - bool dither:1; - bool procamp:1; - bool or:1; - }; - u16 mask; - } set; -}; - -static inline struct nv50_head_atom * -nv50_head_atom_get(struct drm_atomic_state *state, struct drm_crtc *crtc) -{ - struct drm_crtc_state *statec = drm_atomic_get_crtc_state(state, crtc); - if (IS_ERR(statec)) - return (void *)statec; - return nv50_head_atom(statec); -} - -#define nv50_wndw_atom(p) container_of((p), struct nv50_wndw_atom, state) - -struct nv50_wndw_atom { - struct drm_plane_state state; - u8 interval; - - struct { - u32 handle; - u16 offset:12; - bool awaken:1; - } ntfy; - - struct { - u32 handle; - u16 offset:12; - u32 acquire; - u32 release; - } sema; - - struct { - u8 enable:2; - } lut; - - struct { - u8 mode:2; - u8 interval:4; - - u8 format; - u8 kind:7; - u8 layout:1; - u8 block:4; - u32 pitch:20; - u16 w; - u16 h; - - u32 handle; - u64 offset; - } image; - - struct { - u16 x; - u16 y; - } point; - - union { - struct { - bool ntfy:1; - bool sema:1; - bool image:1; - }; - u8 mask; - } clr; - - union { - struct { - bool ntfy:1; - bool sema:1; - bool image:1; - bool lut:1; - bool point:1; - }; - u8 mask; - } set; -}; - -/****************************************************************************** - * EVO channel - *****************************************************************************/ - -struct nv50_chan { - struct nvif_object user; - struct nvif_device *device; -}; - -static int -nv50_chan_create(struct nvif_device *device, struct nvif_object *disp, - const s32 *oclass, u8 head, void *data, u32 size, - struct nv50_chan *chan) -{ - struct nvif_sclass *sclass; - int ret, i, n; - - chan->device = device; - - ret = n = nvif_object_sclass_get(disp, &sclass); - if (ret < 0) - return ret; - - while (oclass[0]) { - for (i = 0; i < n; i++) { - if (sclass[i].oclass == oclass[0]) { - ret = nvif_object_init(disp, 0, oclass[0], - data, size, &chan->user); - if (ret == 0) - nvif_object_map(&chan->user, NULL, 0); - nvif_object_sclass_put(&sclass); - return ret; - } - } - oclass++; - } - - nvif_object_sclass_put(&sclass); - return -ENOSYS; -} - -static void -nv50_chan_destroy(struct nv50_chan *chan) -{ - nvif_object_fini(&chan->user); -} - -/****************************************************************************** - * DMA EVO channel - *****************************************************************************/ - -struct nv50_wndw_ctxdma { - struct list_head head; - struct nvif_object object; -}; - -struct nv50_dmac { - struct nv50_chan base; - - struct nvif_mem push; - u32 *ptr; - - struct nvif_object sync; - struct nvif_object vram; - - /* Protects against concurrent pushbuf access to this channel, lock is - * grabbed by evo_wait (if the pushbuf reservation is successful) and - * dropped again by evo_kick. */ - struct mutex lock; -}; - -static void -nv50_dmac_destroy(struct nv50_dmac *dmac) -{ - nvif_object_fini(&dmac->vram); - nvif_object_fini(&dmac->sync); - - nv50_chan_destroy(&dmac->base); - - nvif_mem_fini(&dmac->push); -} - -static int -nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, - const s32 *oclass, u8 head, void *data, u32 size, u64 syncbuf, - struct nv50_dmac *dmac) -{ - struct nouveau_cli *cli = (void *)device->object.client; - struct nv50_disp_core_channel_dma_v0 *args = data; - int ret; - - mutex_init(&dmac->lock); - - ret = nvif_mem_init_map(&cli->mmu, NVIF_MEM_COHERENT, 0x1000, - &dmac->push); - if (ret) - return ret; - - dmac->ptr = dmac->push.object.map.ptr; - - args->pushbuf = nvif_handle(&dmac->push.object); - - ret = nv50_chan_create(device, disp, oclass, head, data, size, - &dmac->base); - if (ret) - return ret; - - ret = nvif_object_init(&dmac->base.user, 0xf0000000, NV_DMA_IN_MEMORY, - &(struct nv_dma_v0) { - .target = NV_DMA_V0_TARGET_VRAM, - .access = NV_DMA_V0_ACCESS_RDWR, - .start = syncbuf + 0x0000, - .limit = syncbuf + 0x0fff, - }, sizeof(struct nv_dma_v0), - &dmac->sync); - if (ret) - return ret; - - ret = nvif_object_init(&dmac->base.user, 0xf0000001, NV_DMA_IN_MEMORY, - &(struct nv_dma_v0) { - .target = NV_DMA_V0_TARGET_VRAM, - .access = NV_DMA_V0_ACCESS_RDWR, - .start = 0, - .limit = device->info.ram_user - 1, - }, sizeof(struct nv_dma_v0), - &dmac->vram); - if (ret) - return ret; - - return ret; -} - -/****************************************************************************** - * Base - *****************************************************************************/ - -struct nv50_sync { - struct nv50_dmac base; - u32 addr; - u32 data; -}; - -struct nv50_head { - const struct nv50_head_func *func; - struct nouveau_crtc base; - struct { - struct nouveau_bo *nvbo[2]; - int next; - } lut; -}; - -struct nv50_head_func { - void (*view)(struct nv50_head *, struct nv50_head_atom *); - void (*mode)(struct nv50_head *, struct nv50_head_atom *); - void (*ilut_set)(struct nv50_head *, struct nv50_head_atom *); - void (*ilut_clr)(struct nv50_head *); - void (*core_set)(struct nv50_head *, struct nv50_head_atom *); - void (*core_clr)(struct nv50_head *); - void (*curs_set)(struct nv50_head *, struct nv50_head_atom *); - void (*curs_clr)(struct nv50_head *); - void (*base)(struct nv50_head *, struct nv50_head_atom *); - void (*ovly)(struct nv50_head *, struct nv50_head_atom *); - void (*dither)(struct nv50_head *, struct nv50_head_atom *); - void (*procamp)(struct nv50_head *, struct nv50_head_atom *); - void (*or)(struct nv50_head *, struct nv50_head_atom *); -}; - -#define nv50_head(c) container_of((c), struct nv50_head, base.base) - -struct nv50_disp { - struct nvif_disp *disp; - struct nv50_core *core; - - struct nouveau_bo *sync; - - struct mutex mutex; -}; - -static struct nv50_disp * -nv50_disp(struct drm_device *dev) -{ - return nouveau_display(dev)->priv; -} - -/****************************************************************************** - * Core - *****************************************************************************/ - -struct nv50_core { - const struct nv50_core_func *func; - struct nv50_dmac chan; -}; - -struct nv50_core_func { - const struct nv50_head_func *head; - const struct nv50_outp_func *dac; - const struct nv50_outp_func *sor; - const struct nv50_outp_func *pior; -}; - -struct nv50_outp_func { - void (*ctrl)(struct nv50_core *, int or, u32 ctrl, - struct nv50_head_atom *); -}; - -static int -core507d_new_(const struct nv50_core_func *func, struct nouveau_drm *drm, - s32 oclass, struct nv50_core **pcore) -{ - struct nv50_disp_core_channel_dma_v0 args = {}; - struct nv50_disp *disp = nv50_disp(drm->dev); - struct nv50_core *core; - int ret; - - if (!(core = *pcore = kzalloc(sizeof(*core), GFP_KERNEL))) - return -ENOMEM; - core->func = func; - - ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, - &oclass, 0, &args, sizeof(args), - disp->sync->bo.offset, &core->chan); - if (ret) { - NV_ERROR(drm, "core%04x allocation failed: %d\n", oclass, ret); - return ret; - } - - return 0; -} - -/****************************************************************************** - * EVO channel helpers - *****************************************************************************/ -static u32 * -evo_wait(void *evoc, int nr) -{ - struct nv50_dmac *dmac = evoc; - struct nvif_device *device = dmac->base.device; - u32 put = nvif_rd32(&dmac->base.user, 0x0000) / 4; - - mutex_lock(&dmac->lock); - if (put + nr >= (PAGE_SIZE / 4) - 8) { - dmac->ptr[put] = 0x20000000; - - nvif_wr32(&dmac->base.user, 0x0000, 0x00000000); - if (nvif_msec(device, 2000, - if (!nvif_rd32(&dmac->base.user, 0x0004)) - break; - ) < 0) { - mutex_unlock(&dmac->lock); - pr_err("nouveau: evo channel stalled\n"); - return NULL; - } - - put = 0; - } - - return dmac->ptr + put; -} - -static void -evo_kick(u32 *push, void *evoc) -{ - struct nv50_dmac *dmac = evoc; - nvif_wr32(&dmac->base.user, 0x0000, (push - dmac->ptr) << 2); - mutex_unlock(&dmac->lock); -} - -#define evo_mthd(p, m, s) do { \ - const u32 _m = (m), _s = (s); \ - if (drm_debug & DRM_UT_KMS) \ - pr_err("%04x %d %s\n", _m, _s, __func__); \ - *((p)++) = ((_s << 18) | _m); \ -} while(0) - -#define evo_data(p, d) do { \ - const u32 _d = (d); \ - if (drm_debug & DRM_UT_KMS) \ - pr_err("\t%08x\n", _d); \ - *((p)++) = _d; \ -} while(0) - -/****************************************************************************** - * Plane - *****************************************************************************/ -#define nv50_wndw(p) container_of((p), struct nv50_wndw, plane) - -struct nv50_wndw { - const struct nv50_wndw_func *func; - const struct nv50_wimm_func *immd; - int id; - - struct { - struct nvif_object *parent; - struct list_head list; - } ctxdma; - - struct drm_plane plane; - - struct nv50_dmac wndw; - struct nv50_dmac wimm; - - struct nvif_notify notify; - u16 ntfy; - u16 sema; - u32 data; -}; - -struct nv50_wndw_func { - int (*acquire)(struct nv50_wndw *, struct nv50_wndw_atom *asyw, - struct nv50_head_atom *asyh); - void (*release)(struct nv50_wndw *, struct nv50_wndw_atom *asyw, - struct nv50_head_atom *asyh); - void (*prepare)(struct nv50_wndw *, struct nv50_head_atom *asyh, - struct nv50_wndw_atom *asyw); - - void (*sema_set)(struct nv50_wndw *, struct nv50_wndw_atom *); - void (*sema_clr)(struct nv50_wndw *); - void (*ntfy_set)(struct nv50_wndw *, struct nv50_wndw_atom *); - void (*ntfy_clr)(struct nv50_wndw *); - int (*ntfy_wait_begun)(struct nv50_wndw *, struct nv50_wndw_atom *); - void (*image_set)(struct nv50_wndw *, struct nv50_wndw_atom *); - void (*image_clr)(struct nv50_wndw *); - void (*lut)(struct nv50_wndw *, struct nv50_wndw_atom *); - - u32 (*update)(struct nv50_wndw *, u32 interlock); -}; - -struct nv50_wimm_func { - void (*point)(struct nv50_wndw *, struct nv50_wndw_atom *); - - u32 (*update)(struct nv50_wndw *, u32 interlock); -}; - -static void -nv50_wndw_ctxdma_del(struct nv50_wndw_ctxdma *ctxdma) -{ - nvif_object_fini(&ctxdma->object); - list_del(&ctxdma->head); - kfree(ctxdma); -} - -static struct nv50_wndw_ctxdma * -nv50_wndw_ctxdma_new(struct nv50_wndw *wndw, struct nouveau_framebuffer *fb) -{ - struct nouveau_drm *drm = nouveau_drm(fb->base.dev); - struct nv50_wndw_ctxdma *ctxdma; - const u8 kind = fb->nvbo->kind; - const u32 handle = 0xfb000000 | kind; - struct { - struct nv_dma_v0 base; - union { - struct nv50_dma_v0 nv50; - struct gf100_dma_v0 gf100; - struct gf119_dma_v0 gf119; - }; - } args = {}; - u32 argc = sizeof(args.base); - int ret; - - list_for_each_entry(ctxdma, &wndw->ctxdma.list, head) { - if (ctxdma->object.handle == handle) - return ctxdma; - } - - if (!(ctxdma = kzalloc(sizeof(*ctxdma), GFP_KERNEL))) - return ERR_PTR(-ENOMEM); - list_add(&ctxdma->head, &wndw->ctxdma.list); - - args.base.target = NV_DMA_V0_TARGET_VRAM; - args.base.access = NV_DMA_V0_ACCESS_RDWR; - args.base.start = 0; - args.base.limit = drm->client.device.info.ram_user - 1; - - if (drm->client.device.info.chipset < 0x80) { - args.nv50.part = NV50_DMA_V0_PART_256; - argc += sizeof(args.nv50); - } else - if (drm->client.device.info.chipset < 0xc0) { - args.nv50.part = NV50_DMA_V0_PART_256; - args.nv50.kind = kind; - argc += sizeof(args.nv50); - } else - if (drm->client.device.info.chipset < 0xd0) { - args.gf100.kind = kind; - argc += sizeof(args.gf100); - } else { - args.gf119.page = GF119_DMA_V0_PAGE_LP; - args.gf119.kind = kind; - argc += sizeof(args.gf119); - } - - ret = nvif_object_init(wndw->ctxdma.parent, handle, NV_DMA_IN_MEMORY, - &args, argc, &ctxdma->object); - if (ret) { - nv50_wndw_ctxdma_del(ctxdma); - return ERR_PTR(ret); - } - - return ctxdma; -} - -static int -nv50_wndw_wait_armed(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) -{ - if (asyw->set.ntfy) - return wndw->func->ntfy_wait_begun(wndw, asyw); - return 0; -} - -static u32 -nv50_wndw_flush_clr(struct nv50_wndw *wndw, u32 interlock, bool flush, - struct nv50_wndw_atom *asyw) -{ - if (asyw->clr.sema && (!asyw->set.sema || flush)) - wndw->func->sema_clr(wndw); - if (asyw->clr.ntfy && (!asyw->set.ntfy || flush)) - wndw->func->ntfy_clr(wndw); - if (asyw->clr.image && (!asyw->set.image || flush)) - wndw->func->image_clr(wndw); - - return flush ? wndw->func->update(wndw, interlock) : 0; -} - -static u32 -nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 interlock, - struct nv50_wndw_atom *asyw) -{ - if (interlock) { - asyw->image.mode = 0; - asyw->image.interval = 1; - } - - if (asyw->set.sema ) wndw->func->sema_set (wndw, asyw); - if (asyw->set.ntfy ) wndw->func->ntfy_set (wndw, asyw); - if (asyw->set.image) wndw->func->image_set(wndw, asyw); - if (asyw->set.lut ) wndw->func->lut (wndw, asyw); - if (asyw->set.point) { - wndw->immd->point(wndw, asyw); - wndw->immd->update(wndw, interlock); - } - - return wndw->func->update ? wndw->func->update(wndw, interlock) : 0; -} - -static void -nv50_wndw_atomic_check_release(struct nv50_wndw *wndw, - struct nv50_wndw_atom *asyw, - struct nv50_head_atom *asyh) -{ - struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev); - NV_ATOMIC(drm, "%s release\n", wndw->plane.name); - wndw->func->release(wndw, asyw, asyh); - asyw->ntfy.handle = 0; - asyw->sema.handle = 0; -} - -static int -nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, - struct nv50_wndw_atom *asyw, - struct nv50_head_atom *asyh) -{ - struct nouveau_framebuffer *fb = nouveau_framebuffer(asyw->state.fb); - struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev); - int ret; - - NV_ATOMIC(drm, "%s acquire\n", wndw->plane.name); - - asyw->image.w = fb->base.width; - asyw->image.h = fb->base.height; - asyw->image.kind = fb->nvbo->kind; - - if (asyh->state.pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC) - asyw->interval = 0; - else - asyw->interval = 1; - - if (asyw->image.kind) { - asyw->image.layout = 0; - if (drm->client.device.info.chipset >= 0xc0) - asyw->image.block = fb->nvbo->mode >> 4; - else - asyw->image.block = fb->nvbo->mode; - asyw->image.pitch = (fb->base.pitches[0] / 4) << 4; - } else { - asyw->image.layout = 1; - asyw->image.block = 0; - asyw->image.pitch = fb->base.pitches[0]; - } - - ret = wndw->func->acquire(wndw, asyw, asyh); - if (ret) - return ret; - - if (asyw->set.image) { - if (!(asyw->image.mode = asyw->interval ? 0 : 1)) - asyw->image.interval = asyw->interval; - else - asyw->image.interval = 0; - } - - return 0; -} - -static int -nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) -{ - struct nouveau_drm *drm = nouveau_drm(plane->dev); - struct nv50_wndw *wndw = nv50_wndw(plane); - struct nv50_wndw_atom *armw = nv50_wndw_atom(wndw->plane.state); - struct nv50_wndw_atom *asyw = nv50_wndw_atom(state); - struct nv50_head_atom *harm = NULL, *asyh = NULL; - bool varm = false, asyv = false, asym = false; - int ret; - - NV_ATOMIC(drm, "%s atomic_check\n", plane->name); - if (asyw->state.crtc) { - asyh = nv50_head_atom_get(asyw->state.state, asyw->state.crtc); - if (IS_ERR(asyh)) - return PTR_ERR(asyh); - asym = drm_atomic_crtc_needs_modeset(&asyh->state); - asyv = asyh->state.active; - } - - if (armw->state.crtc) { - harm = nv50_head_atom_get(asyw->state.state, armw->state.crtc); - if (IS_ERR(harm)) - return PTR_ERR(harm); - varm = harm->state.crtc->state->active; - } - - if (asyv) { - asyw->point.x = asyw->state.crtc_x; - asyw->point.y = asyw->state.crtc_y; - if (memcmp(&armw->point, &asyw->point, sizeof(asyw->point))) - asyw->set.point = true; - - ret = nv50_wndw_atomic_check_acquire(wndw, asyw, asyh); - if (ret) - return ret; - } else - if (varm) { - nv50_wndw_atomic_check_release(wndw, asyw, harm); - } else { - return 0; - } - - if (!asyv || asym) { - asyw->clr.ntfy = armw->ntfy.handle != 0; - asyw->clr.sema = armw->sema.handle != 0; - if (wndw->func->image_clr) - asyw->clr.image = armw->image.handle != 0; - asyw->set.lut = wndw->func->lut && asyv; - } - - return 0; -} - -static void -nv50_wndw_cleanup_fb(struct drm_plane *plane, struct drm_plane_state *old_state) -{ - struct nouveau_framebuffer *fb = nouveau_framebuffer(old_state->fb); - struct nouveau_drm *drm = nouveau_drm(plane->dev); - - NV_ATOMIC(drm, "%s cleanup: %p\n", plane->name, old_state->fb); - if (!old_state->fb) - return; - - nouveau_bo_unpin(fb->nvbo); -} - -static int -nv50_wndw_prepare_fb(struct drm_plane *plane, struct drm_plane_state *state) -{ - struct nouveau_framebuffer *fb = nouveau_framebuffer(state->fb); - struct nouveau_drm *drm = nouveau_drm(plane->dev); - struct nv50_wndw *wndw = nv50_wndw(plane); - struct nv50_wndw_atom *asyw = nv50_wndw_atom(state); - struct nv50_head_atom *asyh; - struct nv50_wndw_ctxdma *ctxdma; - int ret; - - NV_ATOMIC(drm, "%s prepare: %p\n", plane->name, state->fb); - if (!asyw->state.fb) - return 0; - - ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM, true); - if (ret) - return ret; - - ctxdma = nv50_wndw_ctxdma_new(wndw, fb); - if (IS_ERR(ctxdma)) { - nouveau_bo_unpin(fb->nvbo); - return PTR_ERR(ctxdma); - } - - asyw->state.fence = reservation_object_get_excl_rcu(fb->nvbo->bo.resv); - asyw->image.handle = ctxdma->object.handle; - asyw->image.offset = fb->nvbo->bo.offset; - - if (wndw->func->prepare) { - asyh = nv50_head_atom_get(asyw->state.state, asyw->state.crtc); - if (IS_ERR(asyh)) - return PTR_ERR(asyh); - - wndw->func->prepare(wndw, asyh, asyw); - } - - return 0; -} - -static const struct drm_plane_helper_funcs -nv50_wndw_helper = { - .prepare_fb = nv50_wndw_prepare_fb, - .cleanup_fb = nv50_wndw_cleanup_fb, - .atomic_check = nv50_wndw_atomic_check, -}; - -static void -nv50_wndw_atomic_destroy_state(struct drm_plane *plane, - struct drm_plane_state *state) -{ - struct nv50_wndw_atom *asyw = nv50_wndw_atom(state); - __drm_atomic_helper_plane_destroy_state(&asyw->state); - kfree(asyw); -} - -static struct drm_plane_state * -nv50_wndw_atomic_duplicate_state(struct drm_plane *plane) -{ - struct nv50_wndw_atom *armw = nv50_wndw_atom(plane->state); - struct nv50_wndw_atom *asyw; - if (!(asyw = kmalloc(sizeof(*asyw), GFP_KERNEL))) - return NULL; - __drm_atomic_helper_plane_duplicate_state(plane, &asyw->state); - asyw->interval = 1; - asyw->sema = armw->sema; - asyw->ntfy = armw->ntfy; - asyw->image = armw->image; - asyw->point = armw->point; - asyw->lut = armw->lut; - asyw->clr.mask = 0; - asyw->set.mask = 0; - return &asyw->state; -} - -static void -nv50_wndw_reset(struct drm_plane *plane) -{ - struct nv50_wndw_atom *asyw; - - if (WARN_ON(!(asyw = kzalloc(sizeof(*asyw), GFP_KERNEL)))) - return; - - if (plane->state) - plane->funcs->atomic_destroy_state(plane, plane->state); - plane->state = &asyw->state; - plane->state->plane = plane; - plane->state->rotation = DRM_MODE_ROTATE_0; -} - -static void -nv50_wndw_destroy(struct drm_plane *plane) -{ - struct nv50_wndw *wndw = nv50_wndw(plane); - struct nv50_wndw_ctxdma *ctxdma, *ctxtmp; - - list_for_each_entry_safe(ctxdma, ctxtmp, &wndw->ctxdma.list, head) { - nv50_wndw_ctxdma_del(ctxdma); - } - - nvif_notify_fini(&wndw->notify); - nv50_dmac_destroy(&wndw->wimm); - nv50_dmac_destroy(&wndw->wndw); - drm_plane_cleanup(&wndw->plane); - kfree(wndw); -} - -static const struct drm_plane_funcs -nv50_wndw = { - .update_plane = drm_atomic_helper_update_plane, - .disable_plane = drm_atomic_helper_disable_plane, - .destroy = nv50_wndw_destroy, - .reset = nv50_wndw_reset, - .atomic_duplicate_state = nv50_wndw_atomic_duplicate_state, - .atomic_destroy_state = nv50_wndw_atomic_destroy_state, -}; - -static int -nv50_wndw_notify(struct nvif_notify *notify) -{ - return NVIF_NOTIFY_KEEP; -} - -static void -nv50_wndw_fini(struct nv50_wndw *wndw) -{ - nvif_notify_put(&wndw->notify); -} - -static void -nv50_wndw_init(struct nv50_wndw *wndw) -{ - nvif_notify_get(&wndw->notify); -} - -static int -nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, - enum drm_plane_type type, const char *name, int index, - const u32 *format, struct nv50_wndw **pwndw) -{ - struct nv50_wndw *wndw; - int nformat; - int ret; - - if (!(wndw = *pwndw = kzalloc(sizeof(*wndw), GFP_KERNEL))) - return -ENOMEM; - wndw->func = func; - wndw->id = index; - - wndw->ctxdma.parent = &wndw->wndw.base.user; - INIT_LIST_HEAD(&wndw->ctxdma.list); - - for (nformat = 0; format[nformat]; nformat++); - - ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw, - format, nformat, NULL, - type, "%s-%d", name, index); - if (ret) { - kfree(*pwndw); - *pwndw = NULL; - return ret; - } - - drm_plane_helper_add(&wndw->plane, &nv50_wndw_helper); - - wndw->notify.func = nv50_wndw_notify; - return 0; -} - -/****************************************************************************** - * Overlay - *****************************************************************************/ - -static const struct nv50_wimm_func -oimm507b = { -}; - -static int -oimm507b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, - s32 oclass, struct nv50_wndw *wndw) -{ - struct nv50_disp_overlay_v0 args = { - .head = wndw->id, - }; - struct nv50_disp *disp = nv50_disp(drm->dev); - int ret; - - ret = nvif_object_init(&disp->disp->object, 0, oclass, &args, - sizeof(args), &wndw->wimm.base.user); - if (ret) { - NV_ERROR(drm, "oimm%04x allocation failed: %d\n", oclass, ret); - return ret; - } - - nvif_object_map(&wndw->wimm.base.user, NULL, 0); - wndw->immd = func; - return 0; -} - -static int -oimm507b_init(struct nouveau_drm *drm, s32 oclass, struct nv50_wndw *wndw) -{ - return oimm507b_init_(&oimm507b, drm, oclass, wndw); -} - -static int -nv50_oimm_init(struct nouveau_drm *drm, struct nv50_wndw *wndw) -{ - static const struct { - s32 oclass; - int version; - int (*init)(struct nouveau_drm *, s32, struct nv50_wndw *); - } oimms[] = { - { GK104_DISP_OVERLAY, 0, oimm507b_init }, - { GF110_DISP_OVERLAY, 0, oimm507b_init }, - { GT214_DISP_OVERLAY, 0, oimm507b_init }, - { G82_DISP_OVERLAY, 0, oimm507b_init }, - { NV50_DISP_OVERLAY, 0, oimm507b_init }, - {} - }; - struct nv50_disp *disp = nv50_disp(drm->dev); - int cid; - - cid = nvif_mclass(&disp->disp->object, oimms); - if (cid < 0) { - NV_ERROR(drm, "No supported overlay immediate class\n"); - return cid; - } - - return oimms[cid].init(drm, oimms[cid].oclass, wndw); -} - -static const struct nv50_wndw_func -ovly507e = { -}; - -static const u32 -ovly507e_format[] = { - 0 -}; - -static int -ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format, - struct nouveau_drm *drm, int head, s32 oclass, - struct nv50_wndw **pwndw) -{ - struct nv50_disp_overlay_channel_dma_v0 args = { - .head = head, - }; - struct nv50_disp *disp = nv50_disp(drm->dev); - struct nv50_wndw *wndw; - int ret; - - ret = nv50_wndw_new_(func, drm->dev, DRM_PLANE_TYPE_OVERLAY, - "ovly", head, format, &wndw); - if (*pwndw = wndw, ret) - return ret; - - ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, - &oclass, 0, &args, sizeof(args), - disp->sync->bo.offset, &wndw->wndw); - if (ret) { - NV_ERROR(drm, "ovly%04x allocation failed: %d\n", oclass, ret); - return ret; - } - - return 0; -} - -static int -ovly507e_new(struct nouveau_drm *drm, int head, s32 oclass, - struct nv50_wndw **pwndw) -{ - return ovly507e_new_(&ovly507e, ovly507e_format, drm, head, oclass, pwndw); -} - -static int -nv50_ovly_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) -{ - static const struct { - s32 oclass; - int version; - int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); - } ovlys[] = { - { GK104_DISP_OVERLAY_CONTROL_DMA, 0, ovly507e_new }, - { GF110_DISP_OVERLAY_CONTROL_DMA, 0, ovly507e_new }, - { GT214_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new }, - { GT200_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new }, - { G82_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new }, - { NV50_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new }, - {} - }; - struct nv50_disp *disp = nv50_disp(drm->dev); - int cid, ret; - - cid = nvif_mclass(&disp->disp->object, ovlys); - if (cid < 0) { - NV_ERROR(drm, "No supported overlay class\n"); - return cid; - } - - ret = ovlys[cid].new(drm, head, ovlys[cid].oclass, pwndw); - if (ret) - return ret; - - return nv50_oimm_init(drm, *pwndw); -} - -/****************************************************************************** - * Cursor plane - *****************************************************************************/ -static u32 -nv50_curs_update(struct nv50_wndw *wndw, u32 interlock) -{ - nvif_wr32(&wndw->wimm.base.user, 0x0080, 0x00000000); - return 0; -} - -static void -nv50_curs_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) -{ - nvif_wr32(&wndw->wimm.base.user, 0x0084, (asyw->point.y << 16) | - asyw->point.x); -} - -static const struct nv50_wimm_func -curs507a = { - .point = nv50_curs_point, - .update = nv50_curs_update, -}; - -static void -nv50_curs_prepare(struct nv50_wndw *wndw, struct nv50_head_atom *asyh, - struct nv50_wndw_atom *asyw) -{ - u32 handle = nv50_disp(wndw->plane.dev)->core->chan.vram.handle; - u32 offset = asyw->image.offset; - if (asyh->curs.handle != handle || asyh->curs.offset != offset) { - asyh->curs.handle = handle; - asyh->curs.offset = offset; - asyh->set.curs = asyh->curs.visible; - } -} - -static void -nv50_curs_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, - struct nv50_head_atom *asyh) -{ - asyh->curs.visible = false; -} - -static int -nv50_curs_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, - struct nv50_head_atom *asyh) -{ - int ret; - - ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state, - DRM_PLANE_HELPER_NO_SCALING, - DRM_PLANE_HELPER_NO_SCALING, - true, true); - asyh->curs.visible = asyw->state.visible; - if (ret || !asyh->curs.visible) - return ret; - - switch (asyw->state.fb->width) { - case 32: asyh->curs.layout = 0; break; - case 64: asyh->curs.layout = 1; break; - default: - return -EINVAL; - } - - if (asyw->state.fb->width != asyw->state.fb->height) - return -EINVAL; - - switch (asyw->state.fb->format->format) { - case DRM_FORMAT_ARGB8888: asyh->curs.format = 1; break; - default: - WARN_ON(1); - return -EINVAL; - } - - return 0; -} - -static const u32 -nv50_curs_format[] = { - DRM_FORMAT_ARGB8888, - 0 -}; - -static const struct nv50_wndw_func -nv50_curs = { - .acquire = nv50_curs_acquire, - .release = nv50_curs_release, - .prepare = nv50_curs_prepare, -}; - -static int -curs507a_new_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, - int head, s32 oclass, struct nv50_wndw **pwndw) -{ - struct nv50_disp_cursor_v0 args = { - .head = head, - }; - struct nv50_disp *disp = nv50_disp(drm->dev); - struct nv50_wndw *wndw; - int ret; - - ret = nv50_wndw_new_(&nv50_curs, drm->dev, DRM_PLANE_TYPE_CURSOR, - "curs", head, nv50_curs_format, &wndw); - if (*pwndw = wndw, ret) - return ret; - - ret = nvif_object_init(&disp->disp->object, 0, oclass, &args, - sizeof(args), &wndw->wimm.base.user); - if (ret) { - NV_ERROR(drm, "curs%04x allocation failed: %d\n", oclass, ret); - return ret; - } - - nvif_object_map(&wndw->wimm.base.user, NULL, 0); - wndw->immd = func; - wndw->ctxdma.parent = &disp->core->chan.base.user; - return 0; -} - -static int -curs507a_new(struct nouveau_drm *drm, int head, s32 oclass, - struct nv50_wndw **pwndw) -{ - return curs507a_new_(&curs507a, drm, head, oclass, pwndw); -} - -static int -nv50_curs_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) -{ - struct { - s32 oclass; - int version; - int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); - } curses[] = { - { GK104_DISP_CURSOR, 0, curs507a_new }, - { GF110_DISP_CURSOR, 0, curs507a_new }, - { GT214_DISP_CURSOR, 0, curs507a_new }, - { G82_DISP_CURSOR, 0, curs507a_new }, - { NV50_DISP_CURSOR, 0, curs507a_new }, - {} - }; - struct nv50_disp *disp = nv50_disp(drm->dev); - int cid; - - cid = nvif_mclass(&disp->disp->object, curses); - if (cid < 0) { - NV_ERROR(drm, "No supported cursor immediate class\n"); - return cid; - } - - return curses[cid].new(drm, head, curses[cid].oclass, pwndw); -} - -/****************************************************************************** - * Primary plane - *****************************************************************************/ -static void -nv50_base_lut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) -{ - u32 *push; - if ((push = evo_wait(&wndw->wndw, 2))) { - evo_mthd(push, 0x00e0, 1); - evo_data(push, asyw->lut.enable << 30); - evo_kick(push, &wndw->wndw); - } -} - -static void -nv50_base_image_clr(struct nv50_wndw *wndw) -{ - u32 *push; - if ((push = evo_wait(&wndw->wndw, 4))) { - evo_mthd(push, 0x0084, 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x00c0, 1); - evo_data(push, 0x00000000); - evo_kick(push, &wndw->wndw); - } -} - -static void -nv50_base_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) -{ - const s32 oclass = wndw->wndw.base.user.oclass; - u32 *push; - if ((push = evo_wait(&wndw->wndw, 10))) { - evo_mthd(push, 0x0084, 1); - evo_data(push, (asyw->image.mode << 8) | - (asyw->image.interval << 4)); - evo_mthd(push, 0x00c0, 1); - evo_data(push, asyw->image.handle); - if (oclass < G82_DISP_BASE_CHANNEL_DMA) { - evo_mthd(push, 0x0800, 5); - evo_data(push, asyw->image.offset >> 8); - evo_data(push, 0x00000000); - evo_data(push, (asyw->image.h << 16) | asyw->image.w); - evo_data(push, (asyw->image.layout << 20) | - asyw->image.pitch | - asyw->image.block); - evo_data(push, (asyw->image.kind << 16) | - (asyw->image.format << 8)); - } else - if (oclass < GF110_DISP_BASE_CHANNEL_DMA) { - evo_mthd(push, 0x0800, 5); - evo_data(push, asyw->image.offset >> 8); - evo_data(push, 0x00000000); - evo_data(push, (asyw->image.h << 16) | asyw->image.w); - evo_data(push, (asyw->image.layout << 20) | - asyw->image.pitch | - asyw->image.block); - evo_data(push, asyw->image.format << 8); - } else { - evo_mthd(push, 0x0400, 5); - evo_data(push, asyw->image.offset >> 8); - evo_data(push, 0x00000000); - evo_data(push, (asyw->image.h << 16) | asyw->image.w); - evo_data(push, (asyw->image.layout << 24) | - asyw->image.pitch | - asyw->image.block); - evo_data(push, asyw->image.format << 8); - } - evo_kick(push, &wndw->wndw); - } -} - -static void -nv50_base_ntfy_clr(struct nv50_wndw *wndw) -{ - u32 *push; - if ((push = evo_wait(&wndw->wndw, 2))) { - evo_mthd(push, 0x00a4, 1); - evo_data(push, 0x00000000); - evo_kick(push, &wndw->wndw); - } -} - -static void -nv50_base_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) -{ - u32 *push; - if ((push = evo_wait(&wndw->wndw, 3))) { - evo_mthd(push, 0x00a0, 2); - evo_data(push, (asyw->ntfy.awaken << 30) | asyw->ntfy.offset); - evo_data(push, asyw->ntfy.handle); - evo_kick(push, &wndw->wndw); - } -} - -static void -nv50_base_sema_clr(struct nv50_wndw *wndw) -{ - u32 *push; - if ((push = evo_wait(&wndw->wndw, 2))) { - evo_mthd(push, 0x0094, 1); - evo_data(push, 0x00000000); - evo_kick(push, &wndw->wndw); - } -} - -static void -nv50_base_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) -{ - u32 *push; - if ((push = evo_wait(&wndw->wndw, 5))) { - evo_mthd(push, 0x0088, 4); - evo_data(push, asyw->sema.offset); - evo_data(push, asyw->sema.acquire); - evo_data(push, asyw->sema.release); - evo_data(push, asyw->sema.handle); - evo_kick(push, &wndw->wndw); - } -} - -static u32 -nv50_base_update(struct nv50_wndw *wndw, u32 interlock) -{ - u32 *push; - - if (!(push = evo_wait(&wndw->wndw, 2))) - return 0; - evo_mthd(push, 0x0080, 1); - evo_data(push, interlock); - evo_kick(push, &wndw->wndw); - - if (wndw->wndw.base.user.oclass < GF110_DISP_BASE_CHANNEL_DMA) - return interlock ? 2 << (wndw->id * 8) : 0; - return interlock ? 2 << (wndw->id * 4) : 0; -} - -static int -nv50_base_ntfy_wait_begun(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) -{ - struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev); - struct nv50_disp *disp = nv50_disp(wndw->plane.dev); - if (nvif_msec(&drm->client.device, 2000ULL, - u32 data = nouveau_bo_rd32(disp->sync, asyw->ntfy.offset / 4); - if ((data & 0xc0000000) == 0x40000000) - break; - usleep_range(1, 2); - ) < 0) - return -ETIMEDOUT; - return 0; -} - -static void -nv50_base_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, - struct nv50_head_atom *asyh) -{ - asyh->base.cpp = 0; -} - -static int -nv50_base_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, - struct nv50_head_atom *asyh) -{ - const struct drm_framebuffer *fb = asyw->state.fb; - int ret; - - if (!fb->format->depth) - return -EINVAL; - - ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state, - DRM_PLANE_HELPER_NO_SCALING, - DRM_PLANE_HELPER_NO_SCALING, - false, true); - if (ret) - return ret; - - asyh->base.depth = fb->format->depth; - asyh->base.cpp = fb->format->cpp[0]; - asyh->base.x = asyw->state.src.x1 >> 16; - asyh->base.y = asyw->state.src.y1 >> 16; - asyh->base.w = asyw->state.fb->width; - asyh->base.h = asyw->state.fb->height; - - switch (fb->format->format) { - case DRM_FORMAT_C8 : asyw->image.format = 0x1e; break; - case DRM_FORMAT_RGB565 : asyw->image.format = 0xe8; break; - case DRM_FORMAT_XRGB1555 : - case DRM_FORMAT_ARGB1555 : asyw->image.format = 0xe9; break; - case DRM_FORMAT_XRGB8888 : - case DRM_FORMAT_ARGB8888 : asyw->image.format = 0xcf; break; - case DRM_FORMAT_XBGR2101010: - case DRM_FORMAT_ABGR2101010: asyw->image.format = 0xd1; break; - case DRM_FORMAT_XBGR8888 : - case DRM_FORMAT_ABGR8888 : asyw->image.format = 0xd5; break; - default: - WARN_ON(1); - return -EINVAL; - } - - asyw->lut.enable = 1; - asyw->set.image = true; - return 0; -} - -static const u32 -nv50_base_format[] = { - DRM_FORMAT_C8, - DRM_FORMAT_RGB565, - DRM_FORMAT_XRGB1555, - DRM_FORMAT_ARGB1555, - DRM_FORMAT_XRGB8888, - DRM_FORMAT_ARGB8888, - DRM_FORMAT_XBGR2101010, - DRM_FORMAT_ABGR2101010, - DRM_FORMAT_XBGR8888, - DRM_FORMAT_ABGR8888, - 0 -}; - -static const struct nv50_wndw_func -nv50_base = { - .acquire = nv50_base_acquire, - .release = nv50_base_release, - .sema_set = nv50_base_sema_set, - .sema_clr = nv50_base_sema_clr, - .ntfy_set = nv50_base_ntfy_set, - .ntfy_clr = nv50_base_ntfy_clr, - .ntfy_wait_begun = nv50_base_ntfy_wait_begun, - .image_set = nv50_base_image_set, - .image_clr = nv50_base_image_clr, - .lut = nv50_base_lut, - .update = nv50_base_update, -}; - -static int -base507c_new_(const struct nv50_wndw_func *func, const u32 *format, - struct nouveau_drm *drm, int head, s32 oclass, - struct nv50_wndw **pwndw) -{ - struct nv50_disp_base_channel_dma_v0 args = { - .head = head, - }; - struct nv50_disp *disp = nv50_disp(drm->dev); - struct nv50_wndw *wndw; - int ret; - - ret = nv50_wndw_new_(func, drm->dev, DRM_PLANE_TYPE_PRIMARY, - "base", head, format, &wndw); - if (*pwndw = wndw, ret) - return ret; - - ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, - &oclass, head, &args, sizeof(args), - disp->sync->bo.offset, &wndw->wndw); - if (ret) { - NV_ERROR(drm, "base%04x allocation failed: %d\n", oclass, ret); - return ret; - } - - ret = nvif_notify_init(&wndw->wndw.base.user, wndw->notify.func, - false, NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT, - &(struct nvif_notify_uevent_req) {}, - sizeof(struct nvif_notify_uevent_req), - sizeof(struct nvif_notify_uevent_rep), - &wndw->notify); - if (ret) - return ret; - - wndw->ntfy = EVO_FLIP_NTFY0(wndw->id); - wndw->sema = EVO_FLIP_SEM0(wndw->id); - wndw->data = 0x00000000; - return 0; -} - -static int -base507c_new(struct nouveau_drm *drm, int head, s32 oclass, - struct nv50_wndw **pwndw) -{ - return base507c_new_(&nv50_base, nv50_base_format, drm, head, oclass, pwndw); -} - -static int -nv50_base_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) -{ - struct { - s32 oclass; - int version; - int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); - } bases[] = { - { GK110_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, - { GK104_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, - { GF110_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, - { GT214_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, - { GT200_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, - { G82_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, - { NV50_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, - {} - }; - struct nv50_disp *disp = nv50_disp(drm->dev); - int cid; - - cid = nvif_mclass(&disp->disp->object, bases); - if (cid < 0) { - NV_ERROR(drm, "No supported base class\n"); - return cid; - } - - return bases[cid].new(drm, head, bases[cid].oclass, pwndw); -} - -/****************************************************************************** - * Head - *****************************************************************************/ -static void -head907d_or(struct nv50_head *head, struct nv50_head_atom *asyh) -{ - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if (core->base.user.oclass >= GF110_DISP_CORE_CHANNEL_DMA && - (push = evo_wait(core, 3))) { - evo_mthd(push, 0x0404 + (head->base.index * 0x300), 2); - evo_data(push, 0x00000001 | (asyh->or.depth << 6) | - (asyh->or.nvsync << 4) | - (asyh->or.nhsync << 3)); - evo_data(push, 0x31ec6000 | (head->base.index << 25) | - asyh->mode.interlace); - evo_kick(push, core); - } -} - -static void -nv50_head_procamp(struct nv50_head *head, struct nv50_head_atom *asyh) -{ - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 2))) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) - evo_mthd(push, 0x08a8 + (head->base.index * 0x400), 1); - else - evo_mthd(push, 0x0498 + (head->base.index * 0x300), 1); - evo_data(push, (asyh->procamp.sat.sin << 20) | - (asyh->procamp.sat.cos << 8)); - evo_kick(push, core); - } -} - -static void -nv50_head_dither(struct nv50_head *head, struct nv50_head_atom *asyh) -{ - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 2))) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) - evo_mthd(push, 0x08a0 + (head->base.index * 0x0400), 1); - else - if (core->base.user.oclass < GK104_DISP_CORE_CHANNEL_DMA) - evo_mthd(push, 0x0490 + (head->base.index * 0x0300), 1); - else - evo_mthd(push, 0x04a0 + (head->base.index * 0x0300), 1); - evo_data(push, (asyh->dither.mode << 3) | - (asyh->dither.bits << 1) | - asyh->dither.enable); - evo_kick(push, core); - } -} - -static void -nv50_head_ovly(struct nv50_head *head, struct nv50_head_atom *asyh) -{ - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 bounds = 0; - u32 *push; - - if (asyh->base.cpp) { - switch (asyh->base.cpp) { - case 8: bounds |= 0x00000500; break; - case 4: bounds |= 0x00000300; break; - case 2: bounds |= 0x00000100; break; - default: - WARN_ON(1); - break; - } - bounds |= 0x00000001; - } - - if ((push = evo_wait(core, 2))) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) - evo_mthd(push, 0x0904 + head->base.index * 0x400, 1); - else - evo_mthd(push, 0x04d4 + head->base.index * 0x300, 1); - evo_data(push, bounds); - evo_kick(push, core); - } -} - -static void -nv50_head_base(struct nv50_head *head, struct nv50_head_atom *asyh) -{ - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 bounds = 0; - u32 *push; - - if (asyh->base.cpp) { - switch (asyh->base.cpp) { - case 8: bounds |= 0x00000500; break; - case 4: bounds |= 0x00000300; break; - case 2: bounds |= 0x00000100; break; - case 1: bounds |= 0x00000000; break; - default: - WARN_ON(1); - break; - } - bounds |= 0x00000001; - } - - if ((push = evo_wait(core, 2))) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) - evo_mthd(push, 0x0900 + head->base.index * 0x400, 1); - else - evo_mthd(push, 0x04d0 + head->base.index * 0x300, 1); - evo_data(push, bounds); - evo_kick(push, core); - } -} - -static void -nv50_head_curs_clr(struct nv50_head *head) -{ - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 4))) { - if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0880 + head->base.index * 0x400, 1); - evo_data(push, 0x05000000); - } else - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0880 + head->base.index * 0x400, 1); - evo_data(push, 0x05000000); - evo_mthd(push, 0x089c + head->base.index * 0x400, 1); - evo_data(push, 0x00000000); - } else { - evo_mthd(push, 0x0480 + head->base.index * 0x300, 1); - evo_data(push, 0x05000000); - evo_mthd(push, 0x048c + head->base.index * 0x300, 1); - evo_data(push, 0x00000000); - } - evo_kick(push, core); - } -} - -static void -nv50_head_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh) -{ - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 5))) { - if (core->base.user.oclass < G82_DISP_BASE_CHANNEL_DMA) { - evo_mthd(push, 0x0880 + head->base.index * 0x400, 2); - evo_data(push, 0x80000000 | (asyh->curs.layout << 26) | - (asyh->curs.format << 24)); - evo_data(push, asyh->curs.offset >> 8); - } else - if (core->base.user.oclass < GF110_DISP_BASE_CHANNEL_DMA) { - evo_mthd(push, 0x0880 + head->base.index * 0x400, 2); - evo_data(push, 0x80000000 | (asyh->curs.layout << 26) | - (asyh->curs.format << 24)); - evo_data(push, asyh->curs.offset >> 8); - evo_mthd(push, 0x089c + head->base.index * 0x400, 1); - evo_data(push, asyh->curs.handle); - } else { - evo_mthd(push, 0x0480 + head->base.index * 0x300, 2); - evo_data(push, 0x80000000 | (asyh->curs.layout << 26) | - (asyh->curs.format << 24)); - evo_data(push, asyh->curs.offset >> 8); - evo_mthd(push, 0x048c + head->base.index * 0x300, 1); - evo_data(push, asyh->curs.handle); - } - evo_kick(push, core); - } -} - -static void -nv50_head_core_clr(struct nv50_head *head) -{ - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 2))) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) - evo_mthd(push, 0x0874 + head->base.index * 0x400, 1); - else - evo_mthd(push, 0x0474 + head->base.index * 0x300, 1); - evo_data(push, 0x00000000); - evo_kick(push, core); - } -} - -static void -nv50_head_core_set(struct nv50_head *head, struct nv50_head_atom *asyh) -{ - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 9))) { - if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0860 + head->base.index * 0x400, 1); - evo_data(push, asyh->core.offset >> 8); - evo_mthd(push, 0x0868 + head->base.index * 0x400, 4); - evo_data(push, (asyh->core.h << 16) | asyh->core.w); - evo_data(push, asyh->core.layout << 20 | - (asyh->core.pitch >> 8) << 8 | - asyh->core.block); - evo_data(push, asyh->core.kind << 16 | - asyh->core.format << 8); - evo_data(push, asyh->core.handle); - evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1); - evo_data(push, (asyh->core.y << 16) | asyh->core.x); - /* EVO will complain with INVALID_STATE if we have an - * active cursor and (re)specify HeadSetContextDmaIso - * without also updating HeadSetOffsetCursor. - */ - asyh->set.curs = asyh->curs.visible; - } else - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0860 + head->base.index * 0x400, 1); - evo_data(push, asyh->core.offset >> 8); - evo_mthd(push, 0x0868 + head->base.index * 0x400, 4); - evo_data(push, (asyh->core.h << 16) | asyh->core.w); - evo_data(push, asyh->core.layout << 20 | - (asyh->core.pitch >> 8) << 8 | - asyh->core.block); - evo_data(push, asyh->core.format << 8); - evo_data(push, asyh->core.handle); - evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1); - evo_data(push, (asyh->core.y << 16) | asyh->core.x); - } else { - evo_mthd(push, 0x0460 + head->base.index * 0x300, 1); - evo_data(push, asyh->core.offset >> 8); - evo_mthd(push, 0x0468 + head->base.index * 0x300, 4); - evo_data(push, (asyh->core.h << 16) | asyh->core.w); - evo_data(push, asyh->core.layout << 24 | - (asyh->core.pitch >> 8) << 8 | - asyh->core.block); - evo_data(push, asyh->core.format << 8); - evo_data(push, asyh->core.handle); - evo_mthd(push, 0x04b0 + head->base.index * 0x300, 1); - evo_data(push, (asyh->core.y << 16) | asyh->core.x); - } - evo_kick(push, core); - } -} - -static void -nv50_head_lut_clr(struct nv50_head *head) -{ - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 4))) { - if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1); - evo_data(push, 0x40000000); - } else - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1); - evo_data(push, 0x40000000); - evo_mthd(push, 0x085c + (head->base.index * 0x400), 1); - evo_data(push, 0x00000000); - } else { - evo_mthd(push, 0x0440 + (head->base.index * 0x300), 1); - evo_data(push, 0x03000000); - evo_mthd(push, 0x045c + (head->base.index * 0x300), 1); - evo_data(push, 0x00000000); - } - evo_kick(push, core); - } -} - -static void -nv50_head_lut_load(struct drm_property_blob *blob, int mode, - struct nouveau_bo *nvbo) -{ - struct drm_color_lut *in = (struct drm_color_lut *)blob->data; - void __iomem *lut = (u8 *)nvbo_kmap_obj_iovirtual(nvbo); - const int size = blob->length / sizeof(*in); - int bits, shift, i; - u16 zero, r, g, b; - - /* This can't happen.. But it shuts the compiler up. */ - if (WARN_ON(size != 256)) - return; - - switch (mode) { - case 0: /* LORES. */ - case 1: /* HIRES. */ - bits = 11; - shift = 3; - zero = 0x0000; - break; - case 7: /* INTERPOLATE_257_UNITY_RANGE. */ - bits = 14; - shift = 0; - zero = 0x6000; - break; - default: - WARN_ON(1); - return; - } - - for (i = 0; i < size; i++) { - r = (drm_color_lut_extract(in[i]. red, bits) + zero) << shift; - g = (drm_color_lut_extract(in[i].green, bits) + zero) << shift; - b = (drm_color_lut_extract(in[i]. blue, bits) + zero) << shift; - writew(r, lut + (i * 0x08) + 0); - writew(g, lut + (i * 0x08) + 2); - writew(b, lut + (i * 0x08) + 4); - } - - /* INTERPOLATE modes require a "next" entry to interpolate with, - * so we replicate the last entry to deal with this for now. - */ - writew(r, lut + (i * 0x08) + 0); - writew(g, lut + (i * 0x08) + 2); - writew(b, lut + (i * 0x08) + 4); -} - -static void -nv50_head_lut_set(struct nv50_head *head, struct nv50_head_atom *asyh) -{ - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 7))) { - if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2); - evo_data(push, 0x80000000 | asyh->lut.mode << 30); - evo_data(push, asyh->lut.offset >> 8); - } else - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2); - evo_data(push, 0x80000000 | asyh->lut.mode << 30); - evo_data(push, asyh->lut.offset >> 8); - evo_mthd(push, 0x085c + (head->base.index * 0x400), 1); - evo_data(push, asyh->lut.handle); - } else { - evo_mthd(push, 0x0440 + (head->base.index * 0x300), 4); - evo_data(push, 0x80000000 | asyh->lut.mode << 24); - evo_data(push, asyh->lut.offset >> 8); - evo_data(push, 0x00000000); - evo_data(push, 0x00000000); - evo_mthd(push, 0x045c + (head->base.index * 0x300), 1); - evo_data(push, asyh->lut.handle); - } - evo_kick(push, core); - } -} - -static void -nv50_head_mode(struct nv50_head *head, struct nv50_head_atom *asyh) -{ - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - struct nv50_head_mode *m = &asyh->mode; - u32 *push; - if ((push = evo_wait(core, 14))) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0804 + (head->base.index * 0x400), 2); - evo_data(push, 0x00800000 | m->clock); - evo_data(push, m->interlace ? 0x00000002 : 0x00000000); - evo_mthd(push, 0x0810 + (head->base.index * 0x400), 7); - evo_data(push, 0x00000000); - evo_data(push, (m->v.active << 16) | m->h.active ); - evo_data(push, (m->v.synce << 16) | m->h.synce ); - evo_data(push, (m->v.blanke << 16) | m->h.blanke ); - evo_data(push, (m->v.blanks << 16) | m->h.blanks ); - evo_data(push, (m->v.blank2e << 16) | m->v.blank2s); - evo_data(push, asyh->mode.v.blankus); - evo_mthd(push, 0x082c + (head->base.index * 0x400), 1); - evo_data(push, 0x00000000); - } else { - evo_mthd(push, 0x0410 + (head->base.index * 0x300), 6); - evo_data(push, 0x00000000); - evo_data(push, (m->v.active << 16) | m->h.active ); - evo_data(push, (m->v.synce << 16) | m->h.synce ); - evo_data(push, (m->v.blanke << 16) | m->h.blanke ); - evo_data(push, (m->v.blanks << 16) | m->h.blanks ); - evo_data(push, (m->v.blank2e << 16) | m->v.blank2s); - evo_mthd(push, 0x042c + (head->base.index * 0x300), 2); - evo_data(push, 0x00000000); /* ??? */ - evo_data(push, 0xffffff00); - evo_mthd(push, 0x0450 + (head->base.index * 0x300), 3); - evo_data(push, m->clock * 1000); - evo_data(push, 0x00200000); /* ??? */ - evo_data(push, m->clock * 1000); - } - evo_kick(push, core); - } -} - -static void -nv50_head_view(struct nv50_head *head, struct nv50_head_atom *asyh) -{ - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if ((push = evo_wait(core, 10))) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x08a4 + (head->base.index * 0x400), 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x08c8 + (head->base.index * 0x400), 1); - evo_data(push, (asyh->view.iH << 16) | asyh->view.iW); - evo_mthd(push, 0x08d8 + (head->base.index * 0x400), 2); - evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); - evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); - } else { - evo_mthd(push, 0x0494 + (head->base.index * 0x300), 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x04b8 + (head->base.index * 0x300), 1); - evo_data(push, (asyh->view.iH << 16) | asyh->view.iW); - evo_mthd(push, 0x04c0 + (head->base.index * 0x300), 3); - evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); - evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); - evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); - } - evo_kick(push, core); - } -} - -static const struct nv50_head_func -head507d = { - .view = nv50_head_view, - .mode = nv50_head_mode, - .ilut_set = nv50_head_lut_set, - .ilut_clr = nv50_head_lut_clr, - .core_set = nv50_head_core_set, - .core_clr = nv50_head_core_clr, - .curs_set = nv50_head_curs_set, - .curs_clr = nv50_head_curs_clr, - .base = nv50_head_base, - .ovly = nv50_head_ovly, - .dither = nv50_head_dither, - .procamp = nv50_head_procamp, - .or = head907d_or, -}; - -static void -nv50_head_flush_clr(struct nv50_head *head, struct nv50_head_atom *asyh, bool y) -{ - if (asyh->clr.ilut && (!asyh->set.ilut || y)) - head->func->ilut_clr(head); - if (asyh->clr.core && (!asyh->set.core || y)) - head->func->core_clr(head); - if (asyh->clr.curs && (!asyh->set.curs || y)) - head->func->curs_clr(head); -} - -static void -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.ilut ) { - struct nouveau_bo *nvbo = head->lut.nvbo[head->lut.next]; - struct drm_property_blob *blob = asyh->state.gamma_lut; - if (blob) - nv50_head_lut_load(blob, asyh->lut.mode, nvbo); - asyh->lut.offset = nvbo->bo.offset; - head->lut.next ^= 1; - head->func->ilut_set(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); - if (asyh->set.procamp) head->func->procamp (head, asyh); - if (asyh->set.or ) head->func->or (head, asyh); -} - -static void -nv50_head_atomic_check_procamp(struct nv50_head_atom *armh, - struct nv50_head_atom *asyh, - struct nouveau_conn_atom *asyc) -{ - const int vib = asyc->procamp.color_vibrance - 100; - const int hue = asyc->procamp.vibrant_hue - 90; - const int adj = (vib > 0) ? 50 : 0; - asyh->procamp.sat.cos = ((vib * 2047 + adj) / 100) & 0xfff; - asyh->procamp.sat.sin = ((hue * 2047) / 100) & 0xfff; - asyh->set.procamp = true; -} - -static void -nv50_head_atomic_check_dither(struct nv50_head_atom *armh, - struct nv50_head_atom *asyh, - struct nouveau_conn_atom *asyc) -{ - struct drm_connector *connector = asyc->state.connector; - u32 mode = 0x00; - - if (asyc->dither.mode == DITHERING_MODE_AUTO) { - if (asyh->base.depth > connector->display_info.bpc * 3) - mode = DITHERING_MODE_DYNAMIC2X2; - } else { - mode = asyc->dither.mode; - } - - if (asyc->dither.depth == DITHERING_DEPTH_AUTO) { - if (connector->display_info.bpc >= 8) - mode |= DITHERING_DEPTH_8BPC; - } else { - mode |= asyc->dither.depth; - } - - asyh->dither.enable = mode; - asyh->dither.bits = mode >> 1; - asyh->dither.mode = mode >> 3; - asyh->set.dither = true; -} - -static void -nv50_head_atomic_check_view(struct nv50_head_atom *armh, - struct nv50_head_atom *asyh, - struct nouveau_conn_atom *asyc) -{ - struct drm_connector *connector = asyc->state.connector; - struct drm_display_mode *omode = &asyh->state.adjusted_mode; - struct drm_display_mode *umode = &asyh->state.mode; - int mode = asyc->scaler.mode; - struct edid *edid; - int umode_vdisplay, omode_hdisplay, omode_vdisplay; - - if (connector->edid_blob_ptr) - edid = (struct edid *)connector->edid_blob_ptr->data; - else - edid = NULL; - - if (!asyc->scaler.full) { - if (mode == DRM_MODE_SCALE_NONE) - omode = umode; - } else { - /* Non-EDID LVDS/eDP mode. */ - mode = DRM_MODE_SCALE_FULLSCREEN; - } - - /* For the user-specified mode, we must ignore doublescan and - * the like, but honor frame packing. - */ - umode_vdisplay = umode->vdisplay; - if ((umode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING) - umode_vdisplay += umode->vtotal; - asyh->view.iW = umode->hdisplay; - asyh->view.iH = umode_vdisplay; - /* For the output mode, we can just use the stock helper. */ - drm_mode_get_hv_timing(omode, &omode_hdisplay, &omode_vdisplay); - asyh->view.oW = omode_hdisplay; - asyh->view.oH = omode_vdisplay; - - /* Add overscan compensation if necessary, will keep the aspect - * ratio the same as the backend mode unless overridden by the - * user setting both hborder and vborder properties. - */ - if ((asyc->scaler.underscan.mode == UNDERSCAN_ON || - (asyc->scaler.underscan.mode == UNDERSCAN_AUTO && - drm_detect_hdmi_monitor(edid)))) { - u32 bX = asyc->scaler.underscan.hborder; - u32 bY = asyc->scaler.underscan.vborder; - u32 r = (asyh->view.oH << 19) / asyh->view.oW; - - if (bX) { - asyh->view.oW -= (bX * 2); - if (bY) asyh->view.oH -= (bY * 2); - else asyh->view.oH = ((asyh->view.oW * r) + (r / 2)) >> 19; - } else { - asyh->view.oW -= (asyh->view.oW >> 4) + 32; - if (bY) asyh->view.oH -= (bY * 2); - else asyh->view.oH = ((asyh->view.oW * r) + (r / 2)) >> 19; - } - } - - /* Handle CENTER/ASPECT scaling, taking into account the areas - * removed already for overscan compensation. - */ - switch (mode) { - case DRM_MODE_SCALE_CENTER: - asyh->view.oW = min((u16)umode->hdisplay, asyh->view.oW); - asyh->view.oH = min((u16)umode_vdisplay, asyh->view.oH); - /* fall-through */ - case DRM_MODE_SCALE_ASPECT: - if (asyh->view.oH < asyh->view.oW) { - u32 r = (asyh->view.iW << 19) / asyh->view.iH; - asyh->view.oW = ((asyh->view.oH * r) + (r / 2)) >> 19; - } else { - u32 r = (asyh->view.iH << 19) / asyh->view.iW; - asyh->view.oH = ((asyh->view.oW * r) + (r / 2)) >> 19; - } - break; - default: - break; - } - - asyh->set.view = true; -} - -static void -nv50_head_atomic_check_lut(struct nv50_head *head, - struct nv50_head_atom *armh, - struct nv50_head_atom *asyh) -{ - struct nv50_disp *disp = nv50_disp(head->base.base.dev); +#include +#include +#include +#include +#include - /* An I8 surface without an input LUT makes no sense, and - * EVO will throw an error if you try. - * - * Legacy clients actually cause this due to the order in - * which they call ioctls, so we will enable the LUT with - * whatever contents the buffer already contains to avoid - * triggering the error check. - */ - if (!asyh->state.gamma_lut && asyh->base.cpp != 1) { - asyh->lut.handle = 0; - asyh->clr.ilut = armh->lut.visible; - return; - } +#include "nouveau_drv.h" +#include "nouveau_dma.h" +#include "nouveau_gem.h" +#include "nouveau_connector.h" +#include "nouveau_encoder.h" +#include "nouveau_fence.h" +#include "nouveau_fbcon.h" - if (disp->disp->object.oclass < GF110_DISP) { - asyh->lut.mode = (asyh->base.cpp == 1) ? 0 : 1; - asyh->set.ilut = true; - } else { - asyh->lut.mode = 7; - asyh->set.ilut = asyh->state.color_mgmt_changed; - } - asyh->lut.handle = disp->core->chan.vram.handle; -} +/****************************************************************************** + * Atomic state + *****************************************************************************/ -static void -nv50_head_atomic_check_mode(struct nv50_head *head, struct nv50_head_atom *asyh) -{ - struct drm_display_mode *mode = &asyh->state.adjusted_mode; - struct nv50_head_mode *m = &asyh->mode; - u32 blankus; +struct nv50_outp_atom { + struct list_head head; - drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V | CRTC_STEREO_DOUBLE); + struct drm_encoder *encoder; + bool flush_disable; - /* - * DRM modes are defined in terms of a repeating interval - * starting with the active display area. The hardware modes - * are defined in terms of a repeating interval starting one - * unit (pixel or line) into the sync pulse. So, add bias. - */ + union { + struct { + bool ctrl:1; + }; + u8 mask; + } clr; - m->h.active = mode->crtc_htotal; - m->h.synce = mode->crtc_hsync_end - mode->crtc_hsync_start - 1; - m->h.blanke = mode->crtc_hblank_end - mode->crtc_hsync_start - 1; - m->h.blanks = m->h.blanke + mode->crtc_hdisplay; - - m->v.active = mode->crtc_vtotal; - m->v.synce = mode->crtc_vsync_end - mode->crtc_vsync_start - 1; - m->v.blanke = mode->crtc_vblank_end - mode->crtc_vsync_start - 1; - m->v.blanks = m->v.blanke + mode->crtc_vdisplay; - - /*XXX: Safe underestimate, even "0" works */ - blankus = (m->v.active - mode->crtc_vdisplay - 2) * m->h.active; - blankus *= 1000; - blankus /= mode->crtc_clock; - m->v.blankus = blankus; - - if (mode->flags & DRM_MODE_FLAG_INTERLACE) { - m->v.blank2e = m->v.active + m->v.blanke; - m->v.blank2s = m->v.blank2e + mode->crtc_vdisplay; - m->v.active = (m->v.active * 2) + 1; - m->interlace = true; - } else { - m->v.blank2e = 0; - m->v.blank2s = 1; - m->interlace = false; - } - m->clock = mode->crtc_clock; + union { + struct { + bool ctrl:1; + }; + u8 mask; + } set; +}; - asyh->or.nhsync = !!(mode->flags & DRM_MODE_FLAG_NHSYNC); - asyh->or.nvsync = !!(mode->flags & DRM_MODE_FLAG_NVSYNC); - asyh->set.or = head->func->or != NULL; - asyh->set.mode = true; -} +/****************************************************************************** + * EVO channel + *****************************************************************************/ static int -nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) +nv50_chan_create(struct nvif_device *device, struct nvif_object *disp, + const s32 *oclass, u8 head, void *data, u32 size, + struct nv50_chan *chan) { - struct nouveau_drm *drm = nouveau_drm(crtc->dev); - struct nv50_disp *disp = nv50_disp(crtc->dev); - struct nv50_head *head = nv50_head(crtc); - struct nv50_head_atom *armh = nv50_head_atom(crtc->state); - struct nv50_head_atom *asyh = nv50_head_atom(state); - struct nouveau_conn_atom *asyc = NULL; - struct drm_connector_state *conns; - struct drm_connector *conn; - int i; - - NV_ATOMIC(drm, "%s atomic_check %d\n", crtc->name, asyh->state.active); - if (asyh->state.active) { - for_each_new_connector_in_state(asyh->state.state, conn, conns, i) { - if (conns->crtc == crtc) { - asyc = nouveau_conn_atom(conns); - break; - } - } - - if (armh->state.active) { - if (asyc) { - if (asyh->state.mode_changed) - asyc->set.scaler = true; - if (armh->base.depth != asyh->base.depth) - asyc->set.dither = true; - } - } else { - if (asyc) - asyc->set.mask = ~0; - asyh->set.mask = ~0; - asyh->set.or = head->func->or != NULL; - } - - if (asyh->state.mode_changed) - nv50_head_atomic_check_mode(head, asyh); - - if (asyh->state.color_mgmt_changed || - asyh->base.cpp != armh->base.cpp) - nv50_head_atomic_check_lut(head, armh, asyh); - asyh->lut.visible = asyh->lut.handle != 0; - - if (asyc) { - if (asyc->set.scaler) - nv50_head_atomic_check_view(armh, asyh, asyc); - if (asyc->set.dither) - nv50_head_atomic_check_dither(armh, asyh, asyc); - if (asyc->set.procamp) - nv50_head_atomic_check_procamp(armh, asyh, asyc); - } + struct nvif_sclass *sclass; + int ret, i, n; - if ((asyh->core.visible = (asyh->base.cpp != 0))) { - asyh->core.x = asyh->base.x; - asyh->core.y = asyh->base.y; - asyh->core.w = asyh->base.w; - asyh->core.h = asyh->base.h; - } else - if ((asyh->core.visible = asyh->curs.visible) || - (asyh->core.visible = asyh->lut.visible)) { - /*XXX: We need to either find some way of having the - * primary base layer appear black, while still - * being able to display the other layers, or we - * need to allocate a dummy black surface here. - */ - asyh->core.x = 0; - asyh->core.y = 0; - asyh->core.w = asyh->state.mode.hdisplay; - asyh->core.h = asyh->state.mode.vdisplay; - } - asyh->core.handle = disp->core->chan.vram.handle; - asyh->core.offset = 0; - asyh->core.format = 0xcf; - asyh->core.kind = 0; - asyh->core.layout = 1; - asyh->core.block = 0; - asyh->core.pitch = ALIGN(asyh->core.w, 64) * 4; - asyh->set.base = armh->base.cpp != asyh->base.cpp; - asyh->set.ovly = armh->ovly.cpp != asyh->ovly.cpp; - } else { - asyh->lut.visible = false; - asyh->core.visible = false; - asyh->curs.visible = false; - asyh->base.cpp = 0; - asyh->ovly.cpp = 0; - } + chan->device = device; - if (!drm_atomic_crtc_needs_modeset(&asyh->state)) { - if (asyh->core.visible) { - if (memcmp(&armh->core, &asyh->core, sizeof(asyh->core))) - asyh->set.core = true; - } else - if (armh->core.visible) { - asyh->clr.core = true; - } + ret = n = nvif_object_sclass_get(disp, &sclass); + if (ret < 0) + return ret; - if (asyh->curs.visible) { - if (memcmp(&armh->curs, &asyh->curs, sizeof(asyh->curs))) - asyh->set.curs = true; - } else - if (armh->curs.visible) { - asyh->clr.curs = true; + while (oclass[0]) { + for (i = 0; i < n; i++) { + if (sclass[i].oclass == oclass[0]) { + ret = nvif_object_init(disp, 0, oclass[0], + data, size, &chan->user); + if (ret == 0) + nvif_object_map(&chan->user, NULL, 0); + nvif_object_sclass_put(&sclass); + return ret; + } } - } else { - asyh->clr.ilut = armh->lut.visible; - asyh->clr.core = armh->core.visible; - asyh->clr.curs = armh->curs.visible; - asyh->set.ilut = asyh->lut.visible; - asyh->set.core = asyh->core.visible; - asyh->set.curs = asyh->curs.visible; + oclass++; } - if (asyh->clr.mask || asyh->set.mask) - nv50_atom(asyh->state.state)->lock_core = true; - return 0; + nvif_object_sclass_put(&sclass); + return -ENOSYS; } -static const struct drm_crtc_helper_funcs -nv50_head_help = { - .atomic_check = nv50_head_atomic_check, -}; - static void -nv50_head_atomic_destroy_state(struct drm_crtc *crtc, - struct drm_crtc_state *state) -{ - struct nv50_head_atom *asyh = nv50_head_atom(state); - __drm_atomic_helper_crtc_destroy_state(&asyh->state); - kfree(asyh); -} - -static struct drm_crtc_state * -nv50_head_atomic_duplicate_state(struct drm_crtc *crtc) +nv50_chan_destroy(struct nv50_chan *chan) { - struct nv50_head_atom *armh = nv50_head_atom(crtc->state); - struct nv50_head_atom *asyh; - if (!(asyh = kmalloc(sizeof(*asyh), GFP_KERNEL))) - return NULL; - __drm_atomic_helper_crtc_duplicate_state(crtc, &asyh->state); - asyh->view = armh->view; - asyh->mode = armh->mode; - asyh->lut = armh->lut; - asyh->core = armh->core; - asyh->curs = armh->curs; - asyh->base = armh->base; - asyh->ovly = armh->ovly; - asyh->dither = armh->dither; - asyh->procamp = armh->procamp; - asyh->clr.mask = 0; - asyh->set.mask = 0; - return &asyh->state; + nvif_object_fini(&chan->user); } -static void -__drm_atomic_helper_crtc_reset(struct drm_crtc *crtc, - struct drm_crtc_state *state) -{ - if (crtc->state) - crtc->funcs->atomic_destroy_state(crtc, crtc->state); - crtc->state = state; - crtc->state->crtc = crtc; -} +/****************************************************************************** + * DMA EVO channel + *****************************************************************************/ -static void -nv50_head_reset(struct drm_crtc *crtc) +void +nv50_dmac_destroy(struct nv50_dmac *dmac) { - struct nv50_head_atom *asyh; + nvif_object_fini(&dmac->vram); + nvif_object_fini(&dmac->sync); - if (WARN_ON(!(asyh = kzalloc(sizeof(*asyh), GFP_KERNEL)))) - return; + nv50_chan_destroy(&dmac->base); - __drm_atomic_helper_crtc_reset(crtc, &asyh->state); + nvif_mem_fini(&dmac->push); } -static void -nv50_head_destroy(struct drm_crtc *crtc) +int +nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, + const s32 *oclass, u8 head, void *data, u32 size, u64 syncbuf, + struct nv50_dmac *dmac) { - struct nv50_head *head = nv50_head(crtc); - int i; - - for (i = 0; i < ARRAY_SIZE(head->lut.nvbo); i++) - nouveau_bo_unmap_unpin_unref(&head->lut.nvbo[i]); + struct nouveau_cli *cli = (void *)device->object.client; + struct nv50_disp_core_channel_dma_v0 *args = data; + int ret; - drm_crtc_cleanup(crtc); - kfree(head); -} + mutex_init(&dmac->lock); -static const struct drm_crtc_funcs -nv50_head_func = { - .reset = nv50_head_reset, - .gamma_set = drm_atomic_helper_legacy_gamma_set, - .destroy = nv50_head_destroy, - .set_config = drm_atomic_helper_set_config, - .page_flip = drm_atomic_helper_page_flip, - .atomic_duplicate_state = nv50_head_atomic_duplicate_state, - .atomic_destroy_state = nv50_head_atomic_destroy_state, -}; + ret = nvif_mem_init_map(&cli->mmu, NVIF_MEM_COHERENT, 0x1000, + &dmac->push); + if (ret) + return ret; -static int -nv50_head_create(struct drm_device *dev, int index) -{ - struct nouveau_drm *drm = nouveau_drm(dev); - struct nv50_disp *disp = nv50_disp(dev); - struct nv50_head *head; - struct nv50_wndw *curs, *wndw; - struct drm_crtc *crtc; - int ret, i; + dmac->ptr = dmac->push.object.map.ptr; - head = kzalloc(sizeof(*head), GFP_KERNEL); - if (!head) - return -ENOMEM; + args->pushbuf = nvif_handle(&dmac->push.object); - head->func = disp->core->func->head; - head->base.index = index; - ret = nv50_base_new(drm, head->base.index, &wndw); - if (ret == 0) - ret = nv50_curs_new(drm, head->base.index, &curs); - if (ret) { - kfree(head); + ret = nv50_chan_create(device, disp, oclass, head, data, size, + &dmac->base); + if (ret) return ret; - } - crtc = &head->base.base; - drm_crtc_init_with_planes(dev, crtc, &wndw->plane, &curs->plane, - &nv50_head_func, "head-%d", head->base.index); - drm_crtc_helper_add(crtc, &nv50_head_help); - drm_mode_crtc_set_gamma_size(crtc, 256); - - for (i = 0; i < ARRAY_SIZE(head->lut.nvbo); i++) { - ret = nouveau_bo_new_pin_map(&drm->client, 1025 * 8, 0x100, - TTM_PL_FLAG_VRAM, - &head->lut.nvbo[i]); - if (ret) - goto out; - } + ret = nvif_object_init(&dmac->base.user, 0xf0000000, NV_DMA_IN_MEMORY, + &(struct nv_dma_v0) { + .target = NV_DMA_V0_TARGET_VRAM, + .access = NV_DMA_V0_ACCESS_RDWR, + .start = syncbuf + 0x0000, + .limit = syncbuf + 0x0fff, + }, sizeof(struct nv_dma_v0), + &dmac->sync); + if (ret) + return ret; - /* allocate overlay resources */ - ret = nv50_ovly_new(drm, head->base.index, &wndw); -out: + ret = nvif_object_init(&dmac->base.user, 0xf0000001, NV_DMA_IN_MEMORY, + &(struct nv_dma_v0) { + .target = NV_DMA_V0_TARGET_VRAM, + .access = NV_DMA_V0_ACCESS_RDWR, + .start = 0, + .limit = device->info.ram_user - 1, + }, sizeof(struct nv_dma_v0), + &dmac->vram); if (ret) - nv50_head_destroy(crtc); + return ret; + return ret; } -static const struct nv50_outp_func dac507d; -static const struct nv50_outp_func sor507d; -static const struct nv50_outp_func pior507d; -static const struct nv50_core_func -core507d = { - .head = &head507d, - .dac = &dac507d, - .sor = &sor507d, - .pior = &pior507d, -}; - -static int -core507d_new(struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore) +/****************************************************************************** + * EVO channel helpers + *****************************************************************************/ +u32 * +evo_wait(struct nv50_dmac *evoc, int nr) { - return core507d_new_(&core507d, drm, oclass, pcore); -} + struct nv50_dmac *dmac = evoc; + struct nvif_device *device = dmac->base.device; + u32 put = nvif_rd32(&dmac->base.user, 0x0000) / 4; -static void -nv50_core_del(struct nv50_core **pcore) -{ - struct nv50_core *core = *pcore; - if (core) { - nv50_dmac_destroy(&core->chan); - kfree(*pcore); - *pcore = NULL; - } -} + mutex_lock(&dmac->lock); + if (put + nr >= (PAGE_SIZE / 4) - 8) { + dmac->ptr[put] = 0x20000000; -static int -nv50_core_new(struct nouveau_drm *drm, struct nv50_core **pcore) -{ - struct { - s32 oclass; - int version; - int (*new)(struct nouveau_drm *, s32, struct nv50_core **); - } cores[] = { - { GP102_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { GP100_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { GM200_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { GM107_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { GK110_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { GK104_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { GF110_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { GT214_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { GT206_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { GT200_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { G82_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { NV50_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - {} - }; - struct nv50_disp *disp = nv50_disp(drm->dev); - int cid; + nvif_wr32(&dmac->base.user, 0x0000, 0x00000000); + if (nvif_msec(device, 2000, + if (!nvif_rd32(&dmac->base.user, 0x0004)) + break; + ) < 0) { + mutex_unlock(&dmac->lock); + pr_err("nouveau: evo channel stalled\n"); + return NULL; + } - cid = nvif_mclass(&disp->disp->object, cores); - if (cid < 0) { - NV_ERROR(drm, "No supported core channel class\n"); - return cid; + put = 0; } - return cores[cid].new(drm, cores[cid].oclass, pcore); + return dmac->ptr + put; +} + +void +evo_kick(u32 *push, struct nv50_dmac *evoc) +{ + struct nv50_dmac *dmac = evoc; + nvif_wr32(&dmac->base.user, 0x0000, (push - dmac->ptr) << 2); + mutex_unlock(&dmac->lock); } /****************************************************************************** @@ -2720,33 +326,6 @@ nv50_outp_atomic_check(struct drm_encoder *encoder, /****************************************************************************** * DAC *****************************************************************************/ -static void -dac507d_ctrl(struct nv50_core *core, int or, u32 ctrl, - struct nv50_head_atom *asyh) -{ - u32 *push, sync = 0; - if ((push = evo_wait(&core->chan, 3))) { - if (core->chan.base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - if (asyh) { - sync |= asyh->or.nvsync << 1; - sync |= asyh->or.nhsync; - } - evo_mthd(push, 0x0400 + (or * 0x080), 2); - evo_data(push, ctrl); - evo_data(push, sync); - } else { - evo_mthd(push, 0x0180 + (or * 0x020), 1); - evo_data(push, ctrl); - } - evo_kick(push, &core->chan); - } -} - -static const struct nv50_outp_func -dac507d = { - .ctrl = dac507d_ctrl, -}; - static void nv50_dac_disable(struct drm_encoder *encoder) { @@ -3634,32 +1213,6 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max, /****************************************************************************** * SOR *****************************************************************************/ -static void -sor507d_ctrl(struct nv50_core *core, int or, u32 ctrl, - struct nv50_head_atom *asyh) -{ - u32 *push; - if ((push = evo_wait(&core->chan, 6))) { - if (core->chan.base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - if (asyh) { - ctrl |= asyh->or.depth << 16; - ctrl |= asyh->or.nvsync << 13; - ctrl |= asyh->or.nhsync << 12; - } - evo_mthd(push, 0x0600 + (or * 0x40), 1); - } else { - evo_mthd(push, 0x0200 + (or * 0x20), 1); - } - evo_data(push, ctrl); - evo_kick(push, &core->chan); - } -} - -static const struct nv50_outp_func -sor507d = { - .ctrl = sor507d_ctrl, -}; - static void nv50_sor_update(struct nouveau_encoder *nv_encoder, u8 head, struct nv50_head_atom *asyh, u8 proto, u8 depth) @@ -3904,30 +1457,6 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe) /****************************************************************************** * PIOR *****************************************************************************/ -static void -pior507d_ctrl(struct nv50_core *core, int or, u32 ctrl, - struct nv50_head_atom *asyh) -{ - u32 *push; - if ((push = evo_wait(&core->chan, 8))) { - if (core->chan.base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - if (asyh) { - ctrl |= asyh->or.depth << 16; - ctrl |= asyh->or.nvsync << 13; - ctrl |= asyh->or.nhsync << 12; - } - evo_mthd(push, 0x0700 + (or * 0x040), 1); - evo_data(push, ctrl); - } - evo_kick(push, &core->chan); - } -} - -static const struct nv50_outp_func -pior507d = { - .ctrl = pior507d_ctrl, -}; - static int nv50_pior_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.h b/drivers/gpu/drm/nouveau/dispnv50/disp.h new file mode 100644 index 0000000000000..7cbd668497436 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.h @@ -0,0 +1,71 @@ +#ifndef __NV50_KMS_H__ +#define __NV50_KMS_H__ +#include + +#include "nouveau_display.h" + +struct nv50_disp { + struct nvif_disp *disp; + struct nv50_core *core; + +#define NV50_DISP_SYNC(c, o) ((c) * 0x040 + (o)) +#define NV50_DISP_CORE_NTFY NV50_DISP_SYNC(0 , 0x00) +#define NV50_DISP_WNDW_SEM0(c) NV50_DISP_SYNC(1 + (c), 0x00) +#define NV50_DISP_WNDW_SEM1(c) NV50_DISP_SYNC(1 + (c), 0x10) +#define NV50_DISP_WNDW_NTFY(c) NV50_DISP_SYNC(1 + (c), 0x20) +#define NV50_DISP_BASE_SEM0(c) NV50_DISP_WNDW_SEM0(0 + (c)) +#define NV50_DISP_BASE_SEM1(c) NV50_DISP_WNDW_SEM1(0 + (c)) +#define NV50_DISP_BASE_NTFY(c) NV50_DISP_WNDW_NTFY(0 + (c)) + struct nouveau_bo *sync; + + struct mutex mutex; +}; + +static inline struct nv50_disp * +nv50_disp(struct drm_device *dev) +{ + return nouveau_display(dev)->priv; +} + +struct nv50_chan { + struct nvif_object user; + struct nvif_device *device; +}; + +struct nv50_dmac { + struct nv50_chan base; + + struct nvif_mem push; + u32 *ptr; + + struct nvif_object sync; + struct nvif_object vram; + + /* Protects against concurrent pushbuf access to this channel, lock is + * grabbed by evo_wait (if the pushbuf reservation is successful) and + * dropped again by evo_kick. */ + struct mutex lock; +}; + +int nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, + const s32 *oclass, u8 head, void *data, u32 size, + u64 syncbuf, struct nv50_dmac *dmac); +void nv50_dmac_destroy(struct nv50_dmac *); + +u32 *evo_wait(struct nv50_dmac *, int nr); +void evo_kick(u32 *, struct nv50_dmac *); + +#define evo_mthd(p, m, s) do { \ + const u32 _m = (m), _s = (s); \ + if (drm_debug & DRM_UT_KMS) \ + pr_err("%04x %d %s\n", _m, _s, __func__); \ + *((p)++) = ((_s << 18) | _m); \ +} while(0) + +#define evo_data(p, d) do { \ + const u32 _d = (d); \ + if (drm_debug & DRM_UT_KMS) \ + pr_err("\t%08x\n", _d); \ + *((p)++) = _d; \ +} while(0) +#endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c new file mode 100644 index 0000000000000..6a809ff24e145 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/head.c @@ -0,0 +1,566 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "head.h" +#include "base.h" +#include "core.h" +#include "curs.h" +#include "ovly.h" + +#include + +#include +#include +#include "nouveau_connector.h" +#include "nouveau_bo.h" + +static void +nv50_head_lut_load(struct drm_property_blob *blob, int mode, + struct nouveau_bo *nvbo) +{ + struct drm_color_lut *in = (struct drm_color_lut *)blob->data; + void __iomem *lut = (u8 *)nvbo_kmap_obj_iovirtual(nvbo); + const int size = blob->length / sizeof(*in); + int bits, shift, i; + u16 zero, r, g, b; + + /* This can't happen.. But it shuts the compiler up. */ + if (WARN_ON(size != 256)) + return; + + switch (mode) { + case 0: /* LORES. */ + case 1: /* HIRES. */ + bits = 11; + shift = 3; + zero = 0x0000; + break; + case 7: /* INTERPOLATE_257_UNITY_RANGE. */ + bits = 14; + shift = 0; + zero = 0x6000; + break; + default: + WARN_ON(1); + return; + } + + for (i = 0; i < size; i++) { + r = (drm_color_lut_extract(in[i]. red, bits) + zero) << shift; + g = (drm_color_lut_extract(in[i].green, bits) + zero) << shift; + b = (drm_color_lut_extract(in[i]. blue, bits) + zero) << shift; + writew(r, lut + (i * 0x08) + 0); + writew(g, lut + (i * 0x08) + 2); + writew(b, lut + (i * 0x08) + 4); + } + + /* INTERPOLATE modes require a "next" entry to interpolate with, + * so we replicate the last entry to deal with this for now. + */ + writew(r, lut + (i * 0x08) + 0); + writew(g, lut + (i * 0x08) + 2); + writew(b, lut + (i * 0x08) + 4); +} + +void +nv50_head_flush_clr(struct nv50_head *head, struct nv50_head_atom *asyh, bool y) +{ + if (asyh->clr.ilut && (!asyh->set.ilut || y)) + head->func->ilut_clr(head); + if (asyh->clr.core && (!asyh->set.core || y)) + head->func->core_clr(head); + if (asyh->clr.curs && (!asyh->set.curs || y)) + head->func->curs_clr(head); +} + +void +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.ilut ) { + struct nouveau_bo *nvbo = head->ilut.nvbo[head->ilut.next]; + struct drm_property_blob *blob = asyh->state.gamma_lut; + if (blob) + nv50_head_lut_load(blob, asyh->ilut.mode, nvbo); + asyh->ilut.offset = nvbo->bo.offset; + head->ilut.next ^= 1; + head->func->ilut_set(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); + if (asyh->set.procamp) head->func->procamp (head, asyh); + if (asyh->set.or ) head->func->or (head, asyh); +} + +static void +nv50_head_atomic_check_procamp(struct nv50_head_atom *armh, + struct nv50_head_atom *asyh, + struct nouveau_conn_atom *asyc) +{ + const int vib = asyc->procamp.color_vibrance - 100; + const int hue = asyc->procamp.vibrant_hue - 90; + const int adj = (vib > 0) ? 50 : 0; + asyh->procamp.sat.cos = ((vib * 2047 + adj) / 100) & 0xfff; + asyh->procamp.sat.sin = ((hue * 2047) / 100) & 0xfff; + asyh->set.procamp = true; +} + +static void +nv50_head_atomic_check_dither(struct nv50_head_atom *armh, + struct nv50_head_atom *asyh, + struct nouveau_conn_atom *asyc) +{ + struct drm_connector *connector = asyc->state.connector; + u32 mode = 0x00; + + if (asyc->dither.mode == DITHERING_MODE_AUTO) { + if (asyh->base.depth > connector->display_info.bpc * 3) + mode = DITHERING_MODE_DYNAMIC2X2; + } else { + mode = asyc->dither.mode; + } + + if (asyc->dither.depth == DITHERING_DEPTH_AUTO) { + if (connector->display_info.bpc >= 8) + mode |= DITHERING_DEPTH_8BPC; + } else { + mode |= asyc->dither.depth; + } + + asyh->dither.enable = mode; + asyh->dither.bits = mode >> 1; + asyh->dither.mode = mode >> 3; + asyh->set.dither = true; +} + +static void +nv50_head_atomic_check_view(struct nv50_head_atom *armh, + struct nv50_head_atom *asyh, + struct nouveau_conn_atom *asyc) +{ + struct drm_connector *connector = asyc->state.connector; + struct drm_display_mode *omode = &asyh->state.adjusted_mode; + struct drm_display_mode *umode = &asyh->state.mode; + int mode = asyc->scaler.mode; + struct edid *edid; + int umode_vdisplay, omode_hdisplay, omode_vdisplay; + + if (connector->edid_blob_ptr) + edid = (struct edid *)connector->edid_blob_ptr->data; + else + edid = NULL; + + if (!asyc->scaler.full) { + if (mode == DRM_MODE_SCALE_NONE) + omode = umode; + } else { + /* Non-EDID LVDS/eDP mode. */ + mode = DRM_MODE_SCALE_FULLSCREEN; + } + + /* For the user-specified mode, we must ignore doublescan and + * the like, but honor frame packing. + */ + umode_vdisplay = umode->vdisplay; + if ((umode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING) + umode_vdisplay += umode->vtotal; + asyh->view.iW = umode->hdisplay; + asyh->view.iH = umode_vdisplay; + /* For the output mode, we can just use the stock helper. */ + drm_mode_get_hv_timing(omode, &omode_hdisplay, &omode_vdisplay); + asyh->view.oW = omode_hdisplay; + asyh->view.oH = omode_vdisplay; + + /* Add overscan compensation if necessary, will keep the aspect + * ratio the same as the backend mode unless overridden by the + * user setting both hborder and vborder properties. + */ + if ((asyc->scaler.underscan.mode == UNDERSCAN_ON || + (asyc->scaler.underscan.mode == UNDERSCAN_AUTO && + drm_detect_hdmi_monitor(edid)))) { + u32 bX = asyc->scaler.underscan.hborder; + u32 bY = asyc->scaler.underscan.vborder; + u32 r = (asyh->view.oH << 19) / asyh->view.oW; + + if (bX) { + asyh->view.oW -= (bX * 2); + if (bY) asyh->view.oH -= (bY * 2); + else asyh->view.oH = ((asyh->view.oW * r) + (r / 2)) >> 19; + } else { + asyh->view.oW -= (asyh->view.oW >> 4) + 32; + if (bY) asyh->view.oH -= (bY * 2); + else asyh->view.oH = ((asyh->view.oW * r) + (r / 2)) >> 19; + } + } + + /* Handle CENTER/ASPECT scaling, taking into account the areas + * removed already for overscan compensation. + */ + switch (mode) { + case DRM_MODE_SCALE_CENTER: + asyh->view.oW = min((u16)umode->hdisplay, asyh->view.oW); + asyh->view.oH = min((u16)umode_vdisplay, asyh->view.oH); + /* fall-through */ + case DRM_MODE_SCALE_ASPECT: + if (asyh->view.oH < asyh->view.oW) { + u32 r = (asyh->view.iW << 19) / asyh->view.iH; + asyh->view.oW = ((asyh->view.oH * r) + (r / 2)) >> 19; + } else { + u32 r = (asyh->view.iH << 19) / asyh->view.iW; + asyh->view.oH = ((asyh->view.oW * r) + (r / 2)) >> 19; + } + break; + default: + break; + } + + asyh->set.view = true; +} + +static void +nv50_head_atomic_check_lut(struct nv50_head *head, + struct nv50_head_atom *armh, + struct nv50_head_atom *asyh) +{ + struct nv50_disp *disp = nv50_disp(head->base.base.dev); + + /* An I8 surface without an input LUT makes no sense, and + * EVO will throw an error if you try. + * + * Legacy clients actually cause this due to the order in + * which they call ioctls, so we will enable the LUT with + * whatever contents the buffer already contains to avoid + * triggering the error check. + */ + if (!asyh->state.gamma_lut && asyh->base.cpp != 1) { + asyh->ilut.handle = 0; + asyh->clr.ilut = armh->ilut.visible; + return; + } + + if (disp->disp->object.oclass < GF110_DISP) { + asyh->ilut.mode = (asyh->base.cpp == 1) ? 0 : 1; + asyh->set.ilut = true; + } else { + asyh->ilut.mode = 7; + asyh->set.ilut = asyh->state.color_mgmt_changed; + } + asyh->ilut.handle = disp->core->chan.vram.handle; +} + +static void +nv50_head_atomic_check_mode(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct drm_display_mode *mode = &asyh->state.adjusted_mode; + struct nv50_head_mode *m = &asyh->mode; + u32 blankus; + + drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V | CRTC_STEREO_DOUBLE); + + /* + * DRM modes are defined in terms of a repeating interval + * starting with the active display area. The hardware modes + * are defined in terms of a repeating interval starting one + * unit (pixel or line) into the sync pulse. So, add bias. + */ + + m->h.active = mode->crtc_htotal; + m->h.synce = mode->crtc_hsync_end - mode->crtc_hsync_start - 1; + m->h.blanke = mode->crtc_hblank_end - mode->crtc_hsync_start - 1; + m->h.blanks = m->h.blanke + mode->crtc_hdisplay; + + m->v.active = mode->crtc_vtotal; + m->v.synce = mode->crtc_vsync_end - mode->crtc_vsync_start - 1; + m->v.blanke = mode->crtc_vblank_end - mode->crtc_vsync_start - 1; + m->v.blanks = m->v.blanke + mode->crtc_vdisplay; + + /*XXX: Safe underestimate, even "0" works */ + blankus = (m->v.active - mode->crtc_vdisplay - 2) * m->h.active; + blankus *= 1000; + blankus /= mode->crtc_clock; + m->v.blankus = blankus; + + if (mode->flags & DRM_MODE_FLAG_INTERLACE) { + m->v.blank2e = m->v.active + m->v.blanke; + m->v.blank2s = m->v.blank2e + mode->crtc_vdisplay; + m->v.active = (m->v.active * 2) + 1; + m->interlace = true; + } else { + m->v.blank2e = 0; + m->v.blank2s = 1; + m->interlace = false; + } + m->clock = mode->crtc_clock; + + asyh->or.nhsync = !!(mode->flags & DRM_MODE_FLAG_NHSYNC); + asyh->or.nvsync = !!(mode->flags & DRM_MODE_FLAG_NVSYNC); + asyh->set.or = head->func->or != NULL; + asyh->set.mode = true; +} + +static int +nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) +{ + struct nouveau_drm *drm = nouveau_drm(crtc->dev); + struct nv50_disp *disp = nv50_disp(crtc->dev); + struct nv50_head *head = nv50_head(crtc); + struct nv50_head_atom *armh = nv50_head_atom(crtc->state); + struct nv50_head_atom *asyh = nv50_head_atom(state); + struct nouveau_conn_atom *asyc = NULL; + struct drm_connector_state *conns; + struct drm_connector *conn; + int i; + + NV_ATOMIC(drm, "%s atomic_check %d\n", crtc->name, asyh->state.active); + if (asyh->state.active) { + for_each_new_connector_in_state(asyh->state.state, conn, conns, i) { + if (conns->crtc == crtc) { + asyc = nouveau_conn_atom(conns); + break; + } + } + + if (armh->state.active) { + if (asyc) { + if (asyh->state.mode_changed) + asyc->set.scaler = true; + if (armh->base.depth != asyh->base.depth) + asyc->set.dither = true; + } + } else { + if (asyc) + asyc->set.mask = ~0; + asyh->set.mask = ~0; + asyh->set.or = head->func->or != NULL; + } + + if (asyh->state.mode_changed) + nv50_head_atomic_check_mode(head, asyh); + + if (asyh->state.color_mgmt_changed || + asyh->base.cpp != armh->base.cpp) + nv50_head_atomic_check_lut(head, armh, asyh); + asyh->ilut.visible = asyh->ilut.handle != 0; + + if (asyc) { + if (asyc->set.scaler) + nv50_head_atomic_check_view(armh, asyh, asyc); + if (asyc->set.dither) + nv50_head_atomic_check_dither(armh, asyh, asyc); + if (asyc->set.procamp) + nv50_head_atomic_check_procamp(armh, asyh, asyc); + } + + if ((asyh->core.visible = (asyh->base.cpp != 0))) { + asyh->core.x = asyh->base.x; + asyh->core.y = asyh->base.y; + asyh->core.w = asyh->base.w; + asyh->core.h = asyh->base.h; + } else + if ((asyh->core.visible = asyh->curs.visible) || + (asyh->core.visible = asyh->ilut.visible)) { + /*XXX: We need to either find some way of having the + * primary base layer appear black, while still + * being able to display the other layers, or we + * need to allocate a dummy black surface here. + */ + asyh->core.x = 0; + asyh->core.y = 0; + asyh->core.w = asyh->state.mode.hdisplay; + asyh->core.h = asyh->state.mode.vdisplay; + } + asyh->core.handle = disp->core->chan.vram.handle; + asyh->core.offset = 0; + asyh->core.format = 0xcf; + asyh->core.kind = 0; + asyh->core.layout = 1; + asyh->core.block = 0; + asyh->core.pitch = ALIGN(asyh->core.w, 64) * 4; + asyh->set.base = armh->base.cpp != asyh->base.cpp; + asyh->set.ovly = armh->ovly.cpp != asyh->ovly.cpp; + } else { + asyh->ilut.visible = false; + asyh->core.visible = false; + asyh->curs.visible = false; + asyh->base.cpp = 0; + asyh->ovly.cpp = 0; + } + + if (!drm_atomic_crtc_needs_modeset(&asyh->state)) { + if (asyh->core.visible) { + if (memcmp(&armh->core, &asyh->core, sizeof(asyh->core))) + asyh->set.core = true; + } else + if (armh->core.visible) { + asyh->clr.core = true; + } + + if (asyh->curs.visible) { + if (memcmp(&armh->curs, &asyh->curs, sizeof(asyh->curs))) + asyh->set.curs = true; + } else + if (armh->curs.visible) { + asyh->clr.curs = true; + } + } else { + asyh->clr.ilut = armh->ilut.visible; + asyh->clr.core = armh->core.visible; + asyh->clr.curs = armh->curs.visible; + asyh->set.ilut = asyh->ilut.visible; + asyh->set.core = asyh->core.visible; + asyh->set.curs = asyh->curs.visible; + } + + if (asyh->clr.mask || asyh->set.mask) + nv50_atom(asyh->state.state)->lock_core = true; + return 0; +} + +static const struct drm_crtc_helper_funcs +nv50_head_help = { + .atomic_check = nv50_head_atomic_check, +}; + +static void +nv50_head_atomic_destroy_state(struct drm_crtc *crtc, + struct drm_crtc_state *state) +{ + struct nv50_head_atom *asyh = nv50_head_atom(state); + __drm_atomic_helper_crtc_destroy_state(&asyh->state); + kfree(asyh); +} + +static struct drm_crtc_state * +nv50_head_atomic_duplicate_state(struct drm_crtc *crtc) +{ + struct nv50_head_atom *armh = nv50_head_atom(crtc->state); + struct nv50_head_atom *asyh; + if (!(asyh = kmalloc(sizeof(*asyh), GFP_KERNEL))) + return NULL; + __drm_atomic_helper_crtc_duplicate_state(crtc, &asyh->state); + asyh->view = armh->view; + asyh->mode = armh->mode; + asyh->ilut = armh->ilut; + asyh->core = armh->core; + asyh->curs = armh->curs; + asyh->base = armh->base; + asyh->ovly = armh->ovly; + asyh->dither = armh->dither; + asyh->procamp = armh->procamp; + asyh->clr.mask = 0; + asyh->set.mask = 0; + return &asyh->state; +} + +static void +__drm_atomic_helper_crtc_reset(struct drm_crtc *crtc, + struct drm_crtc_state *state) +{ + if (crtc->state) + crtc->funcs->atomic_destroy_state(crtc, crtc->state); + crtc->state = state; + crtc->state->crtc = crtc; +} + +static void +nv50_head_reset(struct drm_crtc *crtc) +{ + struct nv50_head_atom *asyh; + + if (WARN_ON(!(asyh = kzalloc(sizeof(*asyh), GFP_KERNEL)))) + return; + + __drm_atomic_helper_crtc_reset(crtc, &asyh->state); +} + +static void +nv50_head_destroy(struct drm_crtc *crtc) +{ + struct nv50_head *head = nv50_head(crtc); + int i; + + for (i = 0; i < ARRAY_SIZE(head->ilut.nvbo); i++) + nouveau_bo_unmap_unpin_unref(&head->ilut.nvbo[i]); + + drm_crtc_cleanup(crtc); + kfree(head); +} + +static const struct drm_crtc_funcs +nv50_head_func = { + .reset = nv50_head_reset, + .gamma_set = drm_atomic_helper_legacy_gamma_set, + .destroy = nv50_head_destroy, + .set_config = drm_atomic_helper_set_config, + .page_flip = drm_atomic_helper_page_flip, + .atomic_duplicate_state = nv50_head_atomic_duplicate_state, + .atomic_destroy_state = nv50_head_atomic_destroy_state, +}; + +int +nv50_head_create(struct drm_device *dev, int index) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct nv50_disp *disp = nv50_disp(dev); + struct nv50_head *head; + struct nv50_wndw *curs, *wndw; + struct drm_crtc *crtc; + int ret, i; + + head = kzalloc(sizeof(*head), GFP_KERNEL); + if (!head) + return -ENOMEM; + + head->func = disp->core->func->head; + head->base.index = index; + ret = nv50_base_new(drm, head->base.index, &wndw); + if (ret == 0) + ret = nv50_curs_new(drm, head->base.index, &curs); + if (ret) { + kfree(head); + return ret; + } + + crtc = &head->base.base; + drm_crtc_init_with_planes(dev, crtc, &wndw->plane, &curs->plane, + &nv50_head_func, "head-%d", head->base.index); + drm_crtc_helper_add(crtc, &nv50_head_help); + drm_mode_crtc_set_gamma_size(crtc, 256); + + for (i = 0; i < ARRAY_SIZE(head->ilut.nvbo); i++) { + ret = nouveau_bo_new_pin_map(&drm->client, 1025 * 8, 0x100, + TTM_PL_FLAG_VRAM, + &head->ilut.nvbo[i]); + if (ret) + goto out; + } + + /* allocate overlay resources */ + ret = nv50_ovly_new(drm, head->base.index, &wndw); +out: + if (ret) + nv50_head_destroy(crtc); + return ret; +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.h b/drivers/gpu/drm/nouveau/dispnv50/head.h new file mode 100644 index 0000000000000..23099a82883b1 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/head.h @@ -0,0 +1,39 @@ +#ifndef __NV50_KMS_HEAD_H__ +#define __NV50_KMS_HEAD_H__ +#define nv50_head(c) container_of((c), struct nv50_head, base.base) +#include "disp.h" +#include "atom.h" + +#include "nouveau_crtc.h" + +struct nv50_head { + const struct nv50_head_func *func; + struct nouveau_crtc base; + struct { + struct nouveau_bo *nvbo[2]; + int next; + } ilut; +}; + +int nv50_head_create(struct drm_device *, int index); +void nv50_head_flush_set(struct nv50_head *, struct nv50_head_atom *); +void nv50_head_flush_clr(struct nv50_head *, struct nv50_head_atom *, bool y); + +struct nv50_head_func { + void (*view)(struct nv50_head *, struct nv50_head_atom *); + void (*mode)(struct nv50_head *, struct nv50_head_atom *); + void (*ilut_set)(struct nv50_head *, struct nv50_head_atom *); + void (*ilut_clr)(struct nv50_head *); + void (*core_set)(struct nv50_head *, struct nv50_head_atom *); + void (*core_clr)(struct nv50_head *); + void (*curs_set)(struct nv50_head *, struct nv50_head_atom *); + void (*curs_clr)(struct nv50_head *); + void (*base)(struct nv50_head *, struct nv50_head_atom *); + void (*ovly)(struct nv50_head *, struct nv50_head_atom *); + void (*dither)(struct nv50_head *, struct nv50_head_atom *); + void (*procamp)(struct nv50_head *, struct nv50_head_atom *); + void (*or)(struct nv50_head *, struct nv50_head_atom *); +}; + +extern const struct nv50_head_func head507d; +#endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/head507d.c b/drivers/gpu/drm/nouveau/dispnv50/head507d.c new file mode 100644 index 0000000000000..92fa249ba72fc --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/head507d.c @@ -0,0 +1,403 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "head.h" +#include "core.h" + +#include + +static void +head907d_or(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if (core->base.user.oclass >= GF110_DISP_CORE_CHANNEL_DMA && + (push = evo_wait(core, 3))) { + evo_mthd(push, 0x0404 + (head->base.index * 0x300), 2); + evo_data(push, 0x00000001 | (asyh->or.depth << 6) | + (asyh->or.nvsync << 4) | + (asyh->or.nhsync << 3)); + evo_data(push, 0x31ec6000 | (head->base.index << 25) | + asyh->mode.interlace); + evo_kick(push, core); + } +} + +static void +head507d_procamp(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 2))) { + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) + evo_mthd(push, 0x08a8 + (head->base.index * 0x400), 1); + else + evo_mthd(push, 0x0498 + (head->base.index * 0x300), 1); + evo_data(push, (asyh->procamp.sat.sin << 20) | + (asyh->procamp.sat.cos << 8)); + evo_kick(push, core); + } +} + +static void +head507d_dither(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 2))) { + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) + evo_mthd(push, 0x08a0 + (head->base.index * 0x0400), 1); + else + if (core->base.user.oclass < GK104_DISP_CORE_CHANNEL_DMA) + evo_mthd(push, 0x0490 + (head->base.index * 0x0300), 1); + else + evo_mthd(push, 0x04a0 + (head->base.index * 0x0300), 1); + evo_data(push, (asyh->dither.mode << 3) | + (asyh->dither.bits << 1) | + asyh->dither.enable); + evo_kick(push, core); + } +} + +static void +head507d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 bounds = 0; + u32 *push; + + if (asyh->ovly.cpp) { + switch (asyh->ovly.cpp) { + case 8: bounds |= 0x00000500; break; + case 4: bounds |= 0x00000300; break; + case 2: bounds |= 0x00000100; break; + default: + WARN_ON(1); + break; + } + bounds |= 0x00000001; + } + + if ((push = evo_wait(core, 2))) { + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) + evo_mthd(push, 0x0904 + head->base.index * 0x400, 1); + else + evo_mthd(push, 0x04d4 + head->base.index * 0x300, 1); + evo_data(push, bounds); + evo_kick(push, core); + } +} + +static void +head507d_base(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 bounds = 0; + u32 *push; + + if (asyh->base.cpp) { + switch (asyh->base.cpp) { + case 8: bounds |= 0x00000500; break; + case 4: bounds |= 0x00000300; break; + case 2: bounds |= 0x00000100; break; + case 1: bounds |= 0x00000000; break; + default: + WARN_ON(1); + break; + } + bounds |= 0x00000001; + } + + if ((push = evo_wait(core, 2))) { + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) + evo_mthd(push, 0x0900 + head->base.index * 0x400, 1); + else + evo_mthd(push, 0x04d0 + head->base.index * 0x300, 1); + evo_data(push, bounds); + evo_kick(push, core); + } +} + +static void +head507d_curs_clr(struct nv50_head *head) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 4))) { + if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { + evo_mthd(push, 0x0880 + head->base.index * 0x400, 1); + evo_data(push, 0x05000000); + } else + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { + evo_mthd(push, 0x0880 + head->base.index * 0x400, 1); + evo_data(push, 0x05000000); + evo_mthd(push, 0x089c + head->base.index * 0x400, 1); + evo_data(push, 0x00000000); + } else { + evo_mthd(push, 0x0480 + head->base.index * 0x300, 1); + evo_data(push, 0x05000000); + evo_mthd(push, 0x048c + head->base.index * 0x300, 1); + evo_data(push, 0x00000000); + } + evo_kick(push, core); + } +} + +static void +head507d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 5))) { + if (core->base.user.oclass < G82_DISP_BASE_CHANNEL_DMA) { + evo_mthd(push, 0x0880 + head->base.index * 0x400, 2); + evo_data(push, 0x80000000 | (asyh->curs.layout << 26) | + (asyh->curs.format << 24)); + evo_data(push, asyh->curs.offset >> 8); + } else + if (core->base.user.oclass < GF110_DISP_BASE_CHANNEL_DMA) { + evo_mthd(push, 0x0880 + head->base.index * 0x400, 2); + evo_data(push, 0x80000000 | (asyh->curs.layout << 26) | + (asyh->curs.format << 24)); + evo_data(push, asyh->curs.offset >> 8); + evo_mthd(push, 0x089c + head->base.index * 0x400, 1); + evo_data(push, asyh->curs.handle); + } else { + evo_mthd(push, 0x0480 + head->base.index * 0x300, 2); + evo_data(push, 0x80000000 | (asyh->curs.layout << 26) | + (asyh->curs.format << 24)); + evo_data(push, asyh->curs.offset >> 8); + evo_mthd(push, 0x048c + head->base.index * 0x300, 1); + evo_data(push, asyh->curs.handle); + } + evo_kick(push, core); + } +} + +static void +head507d_core_clr(struct nv50_head *head) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 2))) { + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) + evo_mthd(push, 0x0874 + head->base.index * 0x400, 1); + else + evo_mthd(push, 0x0474 + head->base.index * 0x300, 1); + evo_data(push, 0x00000000); + evo_kick(push, core); + } +} + +static void +head507d_core_set(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 9))) { + if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { + evo_mthd(push, 0x0860 + head->base.index * 0x400, 1); + evo_data(push, asyh->core.offset >> 8); + evo_mthd(push, 0x0868 + head->base.index * 0x400, 4); + evo_data(push, (asyh->core.h << 16) | asyh->core.w); + evo_data(push, asyh->core.layout << 20 | + (asyh->core.pitch >> 8) << 8 | + asyh->core.block); + evo_data(push, asyh->core.kind << 16 | + asyh->core.format << 8); + evo_data(push, asyh->core.handle); + evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1); + evo_data(push, (asyh->core.y << 16) | asyh->core.x); + /* EVO will complain with INVALID_STATE if we have an + * active cursor and (re)specify HeadSetContextDmaIso + * without also updating HeadSetOffsetCursor. + */ + asyh->set.curs = asyh->curs.visible; + } else + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { + evo_mthd(push, 0x0860 + head->base.index * 0x400, 1); + evo_data(push, asyh->core.offset >> 8); + evo_mthd(push, 0x0868 + head->base.index * 0x400, 4); + evo_data(push, (asyh->core.h << 16) | asyh->core.w); + evo_data(push, asyh->core.layout << 20 | + (asyh->core.pitch >> 8) << 8 | + asyh->core.block); + evo_data(push, asyh->core.format << 8); + evo_data(push, asyh->core.handle); + evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1); + evo_data(push, (asyh->core.y << 16) | asyh->core.x); + } else { + evo_mthd(push, 0x0460 + head->base.index * 0x300, 1); + evo_data(push, asyh->core.offset >> 8); + evo_mthd(push, 0x0468 + head->base.index * 0x300, 4); + evo_data(push, (asyh->core.h << 16) | asyh->core.w); + evo_data(push, asyh->core.layout << 24 | + (asyh->core.pitch >> 8) << 8 | + asyh->core.block); + evo_data(push, asyh->core.format << 8); + evo_data(push, asyh->core.handle); + evo_mthd(push, 0x04b0 + head->base.index * 0x300, 1); + evo_data(push, (asyh->core.y << 16) | asyh->core.x); + } + evo_kick(push, core); + } +} + +static void +head507d_ilut_clr(struct nv50_head *head) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 4))) { + if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { + evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1); + evo_data(push, 0x40000000); + } else + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { + evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1); + evo_data(push, 0x40000000); + evo_mthd(push, 0x085c + (head->base.index * 0x400), 1); + evo_data(push, 0x00000000); + } else { + evo_mthd(push, 0x0440 + (head->base.index * 0x300), 1); + evo_data(push, 0x03000000); + evo_mthd(push, 0x045c + (head->base.index * 0x300), 1); + evo_data(push, 0x00000000); + } + evo_kick(push, core); + } +} + +static void +head507d_ilut_set(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 7))) { + if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { + evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2); + evo_data(push, 0x80000000 | asyh->ilut.mode << 30); + evo_data(push, asyh->ilut.offset >> 8); + } else + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { + evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2); + evo_data(push, 0x80000000 | asyh->ilut.mode << 30); + evo_data(push, asyh->ilut.offset >> 8); + evo_mthd(push, 0x085c + (head->base.index * 0x400), 1); + evo_data(push, asyh->ilut.handle); + } else { + evo_mthd(push, 0x0440 + (head->base.index * 0x300), 4); + evo_data(push, 0x80000000 | asyh->ilut.mode << 24); + evo_data(push, asyh->ilut.offset >> 8); + evo_data(push, 0x00000000); + evo_data(push, 0x00000000); + evo_mthd(push, 0x045c + (head->base.index * 0x300), 1); + evo_data(push, asyh->ilut.handle); + } + evo_kick(push, core); + } +} + +static void +head507d_mode(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + struct nv50_head_mode *m = &asyh->mode; + u32 *push; + if ((push = evo_wait(core, 14))) { + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { + evo_mthd(push, 0x0804 + (head->base.index * 0x400), 2); + evo_data(push, 0x00800000 | m->clock); + evo_data(push, m->interlace ? 0x00000002 : 0x00000000); + evo_mthd(push, 0x0810 + (head->base.index * 0x400), 7); + evo_data(push, 0x00000000); + evo_data(push, (m->v.active << 16) | m->h.active ); + evo_data(push, (m->v.synce << 16) | m->h.synce ); + evo_data(push, (m->v.blanke << 16) | m->h.blanke ); + evo_data(push, (m->v.blanks << 16) | m->h.blanks ); + evo_data(push, (m->v.blank2e << 16) | m->v.blank2s); + evo_data(push, asyh->mode.v.blankus); + evo_mthd(push, 0x082c + (head->base.index * 0x400), 1); + evo_data(push, 0x00000000); + } else { + evo_mthd(push, 0x0410 + (head->base.index * 0x300), 6); + evo_data(push, 0x00000000); + evo_data(push, (m->v.active << 16) | m->h.active ); + evo_data(push, (m->v.synce << 16) | m->h.synce ); + evo_data(push, (m->v.blanke << 16) | m->h.blanke ); + evo_data(push, (m->v.blanks << 16) | m->h.blanks ); + evo_data(push, (m->v.blank2e << 16) | m->v.blank2s); + evo_mthd(push, 0x042c + (head->base.index * 0x300), 2); + evo_data(push, 0x00000000); /* ??? */ + evo_data(push, 0xffffff00); + evo_mthd(push, 0x0450 + (head->base.index * 0x300), 3); + evo_data(push, m->clock * 1000); + evo_data(push, 0x00200000); /* ??? */ + evo_data(push, m->clock * 1000); + } + evo_kick(push, core); + } +} + +static void +head507d_view(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 10))) { + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { + evo_mthd(push, 0x08a4 + (head->base.index * 0x400), 1); + evo_data(push, 0x00000000); + evo_mthd(push, 0x08c8 + (head->base.index * 0x400), 1); + evo_data(push, (asyh->view.iH << 16) | asyh->view.iW); + evo_mthd(push, 0x08d8 + (head->base.index * 0x400), 2); + evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); + evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); + } else { + evo_mthd(push, 0x0494 + (head->base.index * 0x300), 1); + evo_data(push, 0x00000000); + evo_mthd(push, 0x04b8 + (head->base.index * 0x300), 1); + evo_data(push, (asyh->view.iH << 16) | asyh->view.iW); + evo_mthd(push, 0x04c0 + (head->base.index * 0x300), 3); + evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); + evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); + evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); + } + evo_kick(push, core); + } +} + +const struct nv50_head_func +head507d = { + .view = head507d_view, + .mode = head507d_mode, + .ilut_set = head507d_ilut_set, + .ilut_clr = head507d_ilut_clr, + .core_set = head507d_core_set, + .core_clr = head507d_core_clr, + .curs_set = head507d_curs_set, + .curs_clr = head507d_curs_clr, + .base = head507d_base, + .ovly = head507d_ovly, + .dither = head507d_dither, + .procamp = head507d_procamp, + .or = head907d_or, +}; diff --git a/drivers/gpu/drm/nouveau/dispnv50/oimm.c b/drivers/gpu/drm/nouveau/dispnv50/oimm.c new file mode 100644 index 0000000000000..2a2841d344c89 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/oimm.c @@ -0,0 +1,51 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "oimm.h" + +#include + +int +nv50_oimm_init(struct nouveau_drm *drm, struct nv50_wndw *wndw) +{ + static const struct { + s32 oclass; + int version; + int (*init)(struct nouveau_drm *, s32, struct nv50_wndw *); + } oimms[] = { + { GK104_DISP_OVERLAY, 0, oimm507b_init }, + { GF110_DISP_OVERLAY, 0, oimm507b_init }, + { GT214_DISP_OVERLAY, 0, oimm507b_init }, + { G82_DISP_OVERLAY, 0, oimm507b_init }, + { NV50_DISP_OVERLAY, 0, oimm507b_init }, + {} + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + int cid; + + cid = nvif_mclass(&disp->disp->object, oimms); + if (cid < 0) { + NV_ERROR(drm, "No supported overlay immediate class\n"); + return cid; + } + + return oimms[cid].init(drm, oimms[cid].oclass, wndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/oimm.h b/drivers/gpu/drm/nouveau/dispnv50/oimm.h new file mode 100644 index 0000000000000..6fa51f101e94d --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/oimm.h @@ -0,0 +1,8 @@ +#ifndef __NV50_KMS_OIMM_H__ +#define __NV50_KMS_OIMM_H__ +#include "wndw.h" + +int oimm507b_init(struct nouveau_drm *, s32, struct nv50_wndw *); + +int nv50_oimm_init(struct nouveau_drm *, struct nv50_wndw *); +#endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/oimm507b.c b/drivers/gpu/drm/nouveau/dispnv50/oimm507b.c new file mode 100644 index 0000000000000..c4baca82de14b --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/oimm507b.c @@ -0,0 +1,56 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "oimm.h" + +#include + +static const struct nv50_wimm_func +oimm507b = { +}; + +static int +oimm507b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, + s32 oclass, struct nv50_wndw *wndw) +{ + struct nv50_disp_overlay_v0 args = { + .head = wndw->id, + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + int ret; + + ret = nvif_object_init(&disp->disp->object, 0, oclass, &args, + sizeof(args), &wndw->wimm.base.user); + if (ret) { + NV_ERROR(drm, "oimm%04x allocation failed: %d\n", oclass, ret); + return ret; + } + + nvif_object_map(&wndw->wimm.base.user, NULL, 0); + wndw->immd = func; + return 0; +} + +int +oimm507b_init(struct nouveau_drm *drm, s32 oclass, struct nv50_wndw *wndw) +{ + return oimm507b_init_(&oimm507b, drm, oclass, wndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly.c b/drivers/gpu/drm/nouveau/dispnv50/ovly.c new file mode 100644 index 0000000000000..ac2d3b64f1863 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly.c @@ -0,0 +1,57 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "ovly.h" +#include "oimm.h" + +#include + +int +nv50_ovly_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) +{ + static const struct { + s32 oclass; + int version; + int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); + } ovlys[] = { + { GK104_DISP_OVERLAY_CONTROL_DMA, 0, ovly507e_new }, + { GF110_DISP_OVERLAY_CONTROL_DMA, 0, ovly507e_new }, + { GT214_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new }, + { GT200_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new }, + { G82_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new }, + { NV50_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new }, + {} + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + int cid, ret; + + cid = nvif_mclass(&disp->disp->object, ovlys); + if (cid < 0) { + NV_ERROR(drm, "No supported overlay class\n"); + return cid; + } + + ret = ovlys[cid].new(drm, head, ovlys[cid].oclass, pwndw); + if (ret) + return ret; + + return nv50_oimm_init(drm, *pwndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly.h b/drivers/gpu/drm/nouveau/dispnv50/ovly.h new file mode 100644 index 0000000000000..90af1f2f0aa01 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly.h @@ -0,0 +1,8 @@ +#ifndef __NV50_KMS_OVLY_H__ +#define __NV50_KMS_OVLY_H__ +#include "wndw.h" + +int ovly507e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); + +int nv50_ovly_new(struct nouveau_drm *, int head, struct nv50_wndw **); +#endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c b/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c new file mode 100644 index 0000000000000..ceec5127a17dc --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c @@ -0,0 +1,70 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "ovly.h" + +#include + +#include "nouveau_bo.h" + +static const struct nv50_wndw_func +ovly507e = { +}; + +static const u32 +ovly507e_format[] = { + 0 +}; + +static int +ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format, + struct nouveau_drm *drm, int head, s32 oclass, + struct nv50_wndw **pwndw) +{ + struct nv50_disp_overlay_channel_dma_v0 args = { + .head = head, + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + struct nv50_wndw *wndw; + int ret; + + ret = nv50_wndw_new_(func, drm->dev, DRM_PLANE_TYPE_OVERLAY, + "ovly", head, format, &wndw); + if (*pwndw = wndw, ret) + return ret; + + ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, + &oclass, 0, &args, sizeof(args), + disp->sync->bo.offset, &wndw->wndw); + if (ret) { + NV_ERROR(drm, "ovly%04x allocation failed: %d\n", oclass, ret); + return ret; + } + + return 0; +} + +int +ovly507e_new(struct nouveau_drm *drm, int head, s32 oclass, + struct nv50_wndw **pwndw) +{ + return ovly507e_new_(&ovly507e, ovly507e_format, drm, head, oclass, pwndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/pior507d.c b/drivers/gpu/drm/nouveau/dispnv50/pior507d.c new file mode 100644 index 0000000000000..a99ba6a7216f5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/pior507d.c @@ -0,0 +1,48 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "core.h" + +#include + +static void +pior507d_ctrl(struct nv50_core *core, int or, u32 ctrl, + struct nv50_head_atom *asyh) +{ + u32 *push; + if ((push = evo_wait(&core->chan, 8))) { + if (core->chan.base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { + if (asyh) { + ctrl |= asyh->or.depth << 16; + ctrl |= asyh->or.nvsync << 13; + ctrl |= asyh->or.nhsync << 12; + } + evo_mthd(push, 0x0700 + (or * 0x040), 1); + evo_data(push, ctrl); + } + evo_kick(push, &core->chan); + } +} + +const struct nv50_outp_func +pior507d = { + .ctrl = pior507d_ctrl, +}; diff --git a/drivers/gpu/drm/nouveau/dispnv50/sor507d.c b/drivers/gpu/drm/nouveau/dispnv50/sor507d.c new file mode 100644 index 0000000000000..2d540de27f592 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/sor507d.c @@ -0,0 +1,50 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "core.h" + +#include + +static void +sor507d_ctrl(struct nv50_core *core, int or, u32 ctrl, + struct nv50_head_atom *asyh) +{ + u32 *push; + if ((push = evo_wait(&core->chan, 6))) { + if (core->chan.base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { + if (asyh) { + ctrl |= asyh->or.depth << 16; + ctrl |= asyh->or.nvsync << 13; + ctrl |= asyh->or.nhsync << 12; + } + evo_mthd(push, 0x0600 + (or * 0x40), 1); + } else { + evo_mthd(push, 0x0200 + (or * 0x20), 1); + } + evo_data(push, ctrl); + evo_kick(push, &core->chan); + } +} + +const struct nv50_outp_func +sor507d = { + .ctrl = sor507d_ctrl, +}; diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c new file mode 100644 index 0000000000000..71a4c50af8ecb --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -0,0 +1,434 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "wndw.h" + +#include +#include + +#include +#include "nouveau_bo.h" + +static void +nv50_wndw_ctxdma_del(struct nv50_wndw_ctxdma *ctxdma) +{ + nvif_object_fini(&ctxdma->object); + list_del(&ctxdma->head); + kfree(ctxdma); +} + +static struct nv50_wndw_ctxdma * +nv50_wndw_ctxdma_new(struct nv50_wndw *wndw, struct nouveau_framebuffer *fb) +{ + struct nouveau_drm *drm = nouveau_drm(fb->base.dev); + struct nv50_wndw_ctxdma *ctxdma; + const u8 kind = fb->nvbo->kind; + const u32 handle = 0xfb000000 | kind; + struct { + struct nv_dma_v0 base; + union { + struct nv50_dma_v0 nv50; + struct gf100_dma_v0 gf100; + struct gf119_dma_v0 gf119; + }; + } args = {}; + u32 argc = sizeof(args.base); + int ret; + + list_for_each_entry(ctxdma, &wndw->ctxdma.list, head) { + if (ctxdma->object.handle == handle) + return ctxdma; + } + + if (!(ctxdma = kzalloc(sizeof(*ctxdma), GFP_KERNEL))) + return ERR_PTR(-ENOMEM); + list_add(&ctxdma->head, &wndw->ctxdma.list); + + args.base.target = NV_DMA_V0_TARGET_VRAM; + args.base.access = NV_DMA_V0_ACCESS_RDWR; + args.base.start = 0; + args.base.limit = drm->client.device.info.ram_user - 1; + + if (drm->client.device.info.chipset < 0x80) { + args.nv50.part = NV50_DMA_V0_PART_256; + argc += sizeof(args.nv50); + } else + if (drm->client.device.info.chipset < 0xc0) { + args.nv50.part = NV50_DMA_V0_PART_256; + args.nv50.kind = kind; + argc += sizeof(args.nv50); + } else + if (drm->client.device.info.chipset < 0xd0) { + args.gf100.kind = kind; + argc += sizeof(args.gf100); + } else { + args.gf119.page = GF119_DMA_V0_PAGE_LP; + args.gf119.kind = kind; + argc += sizeof(args.gf119); + } + + ret = nvif_object_init(wndw->ctxdma.parent, handle, NV_DMA_IN_MEMORY, + &args, argc, &ctxdma->object); + if (ret) { + nv50_wndw_ctxdma_del(ctxdma); + return ERR_PTR(ret); + } + + return ctxdma; +} + +int +nv50_wndw_wait_armed(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + if (asyw->set.ntfy) + return wndw->func->ntfy_wait_begun(wndw, asyw); + return 0; +} + +u32 +nv50_wndw_flush_clr(struct nv50_wndw *wndw, u32 interlock, bool flush, + struct nv50_wndw_atom *asyw) +{ + if (asyw->clr.sema && (!asyw->set.sema || flush)) + wndw->func->sema_clr(wndw); + if (asyw->clr.ntfy && (!asyw->set.ntfy || flush)) + wndw->func->ntfy_clr(wndw); + if (asyw->clr.image && (!asyw->set.image || flush)) + wndw->func->image_clr(wndw); + + return flush ? wndw->func->update(wndw, interlock) : 0; +} + +u32 +nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 interlock, + struct nv50_wndw_atom *asyw) +{ + if (interlock) { + asyw->image.mode = 0; + asyw->image.interval = 1; + } + + if (asyw->set.sema ) wndw->func->sema_set (wndw, asyw); + if (asyw->set.ntfy ) wndw->func->ntfy_set (wndw, asyw); + if (asyw->set.image) wndw->func->image_set(wndw, asyw); + if (asyw->set.lut ) wndw->func->lut (wndw, asyw); + if (asyw->set.point) { + wndw->immd->point(wndw, asyw); + wndw->immd->update(wndw, interlock); + } + + return wndw->func->update ? wndw->func->update(wndw, interlock) : 0; +} + +static void +nv50_wndw_atomic_check_release(struct nv50_wndw *wndw, + struct nv50_wndw_atom *asyw, + struct nv50_head_atom *asyh) +{ + struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev); + NV_ATOMIC(drm, "%s release\n", wndw->plane.name); + wndw->func->release(wndw, asyw, asyh); + asyw->ntfy.handle = 0; + asyw->sema.handle = 0; +} + +static int +nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, + struct nv50_wndw_atom *asyw, + struct nv50_head_atom *asyh) +{ + struct nouveau_framebuffer *fb = nouveau_framebuffer(asyw->state.fb); + struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev); + int ret; + + NV_ATOMIC(drm, "%s acquire\n", wndw->plane.name); + + asyw->image.w = fb->base.width; + asyw->image.h = fb->base.height; + asyw->image.kind = fb->nvbo->kind; + + if (asyh->state.pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC) + asyw->interval = 0; + else + asyw->interval = 1; + + if (asyw->image.kind) { + asyw->image.layout = 0; + if (drm->client.device.info.chipset >= 0xc0) + asyw->image.block = fb->nvbo->mode >> 4; + else + asyw->image.block = fb->nvbo->mode; + asyw->image.pitch = (fb->base.pitches[0] / 4) << 4; + } else { + asyw->image.layout = 1; + asyw->image.block = 0; + asyw->image.pitch = fb->base.pitches[0]; + } + + ret = wndw->func->acquire(wndw, asyw, asyh); + if (ret) + return ret; + + if (asyw->set.image) { + if (!(asyw->image.mode = asyw->interval ? 0 : 1)) + asyw->image.interval = asyw->interval; + else + asyw->image.interval = 0; + } + + return 0; +} + +int +nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) +{ + struct nouveau_drm *drm = nouveau_drm(plane->dev); + struct nv50_wndw *wndw = nv50_wndw(plane); + struct nv50_wndw_atom *armw = nv50_wndw_atom(wndw->plane.state); + struct nv50_wndw_atom *asyw = nv50_wndw_atom(state); + struct nv50_head_atom *harm = NULL, *asyh = NULL; + bool varm = false, asyv = false, asym = false; + int ret; + + NV_ATOMIC(drm, "%s atomic_check\n", plane->name); + if (asyw->state.crtc) { + asyh = nv50_head_atom_get(asyw->state.state, asyw->state.crtc); + if (IS_ERR(asyh)) + return PTR_ERR(asyh); + asym = drm_atomic_crtc_needs_modeset(&asyh->state); + asyv = asyh->state.active; + } + + if (armw->state.crtc) { + harm = nv50_head_atom_get(asyw->state.state, armw->state.crtc); + if (IS_ERR(harm)) + return PTR_ERR(harm); + varm = harm->state.crtc->state->active; + } + + if (asyv) { + asyw->point.x = asyw->state.crtc_x; + asyw->point.y = asyw->state.crtc_y; + if (memcmp(&armw->point, &asyw->point, sizeof(asyw->point))) + asyw->set.point = true; + + ret = nv50_wndw_atomic_check_acquire(wndw, asyw, asyh); + if (ret) + return ret; + } else + if (varm) { + nv50_wndw_atomic_check_release(wndw, asyw, harm); + } else { + return 0; + } + + if (!asyv || asym) { + asyw->clr.ntfy = armw->ntfy.handle != 0; + asyw->clr.sema = armw->sema.handle != 0; + if (wndw->func->image_clr) + asyw->clr.image = armw->image.handle != 0; + asyw->set.lut = wndw->func->lut && asyv; + } + + return 0; +} + +static void +nv50_wndw_cleanup_fb(struct drm_plane *plane, struct drm_plane_state *old_state) +{ + struct nouveau_framebuffer *fb = nouveau_framebuffer(old_state->fb); + struct nouveau_drm *drm = nouveau_drm(plane->dev); + + NV_ATOMIC(drm, "%s cleanup: %p\n", plane->name, old_state->fb); + if (!old_state->fb) + return; + + nouveau_bo_unpin(fb->nvbo); +} + +static int +nv50_wndw_prepare_fb(struct drm_plane *plane, struct drm_plane_state *state) +{ + struct nouveau_framebuffer *fb = nouveau_framebuffer(state->fb); + struct nouveau_drm *drm = nouveau_drm(plane->dev); + struct nv50_wndw *wndw = nv50_wndw(plane); + struct nv50_wndw_atom *asyw = nv50_wndw_atom(state); + struct nv50_head_atom *asyh; + struct nv50_wndw_ctxdma *ctxdma; + int ret; + + NV_ATOMIC(drm, "%s prepare: %p\n", plane->name, state->fb); + if (!asyw->state.fb) + return 0; + + ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM, true); + if (ret) + return ret; + + ctxdma = nv50_wndw_ctxdma_new(wndw, fb); + if (IS_ERR(ctxdma)) { + nouveau_bo_unpin(fb->nvbo); + return PTR_ERR(ctxdma); + } + + asyw->state.fence = reservation_object_get_excl_rcu(fb->nvbo->bo.resv); + asyw->image.handle = ctxdma->object.handle; + asyw->image.offset = fb->nvbo->bo.offset; + + if (wndw->func->prepare) { + asyh = nv50_head_atom_get(asyw->state.state, asyw->state.crtc); + if (IS_ERR(asyh)) + return PTR_ERR(asyh); + + wndw->func->prepare(wndw, asyh, asyw); + } + + return 0; +} + +static const struct drm_plane_helper_funcs +nv50_wndw_helper = { + .prepare_fb = nv50_wndw_prepare_fb, + .cleanup_fb = nv50_wndw_cleanup_fb, + .atomic_check = nv50_wndw_atomic_check, +}; + +static void +nv50_wndw_atomic_destroy_state(struct drm_plane *plane, + struct drm_plane_state *state) +{ + struct nv50_wndw_atom *asyw = nv50_wndw_atom(state); + __drm_atomic_helper_plane_destroy_state(&asyw->state); + kfree(asyw); +} + +static struct drm_plane_state * +nv50_wndw_atomic_duplicate_state(struct drm_plane *plane) +{ + struct nv50_wndw_atom *armw = nv50_wndw_atom(plane->state); + struct nv50_wndw_atom *asyw; + if (!(asyw = kmalloc(sizeof(*asyw), GFP_KERNEL))) + return NULL; + __drm_atomic_helper_plane_duplicate_state(plane, &asyw->state); + asyw->interval = 1; + asyw->sema = armw->sema; + asyw->ntfy = armw->ntfy; + asyw->image = armw->image; + asyw->point = armw->point; + asyw->lut = armw->lut; + asyw->clr.mask = 0; + asyw->set.mask = 0; + return &asyw->state; +} + +static void +nv50_wndw_reset(struct drm_plane *plane) +{ + struct nv50_wndw_atom *asyw; + + if (WARN_ON(!(asyw = kzalloc(sizeof(*asyw), GFP_KERNEL)))) + return; + + if (plane->state) + plane->funcs->atomic_destroy_state(plane, plane->state); + plane->state = &asyw->state; + plane->state->plane = plane; + plane->state->rotation = DRM_MODE_ROTATE_0; +} + +static void +nv50_wndw_destroy(struct drm_plane *plane) +{ + struct nv50_wndw *wndw = nv50_wndw(plane); + struct nv50_wndw_ctxdma *ctxdma, *ctxtmp; + + list_for_each_entry_safe(ctxdma, ctxtmp, &wndw->ctxdma.list, head) { + nv50_wndw_ctxdma_del(ctxdma); + } + + nvif_notify_fini(&wndw->notify); + nv50_dmac_destroy(&wndw->wimm); + nv50_dmac_destroy(&wndw->wndw); + drm_plane_cleanup(&wndw->plane); + kfree(wndw); +} + +const struct drm_plane_funcs +nv50_wndw = { + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, + .destroy = nv50_wndw_destroy, + .reset = nv50_wndw_reset, + .atomic_duplicate_state = nv50_wndw_atomic_duplicate_state, + .atomic_destroy_state = nv50_wndw_atomic_destroy_state, +}; + +static int +nv50_wndw_notify(struct nvif_notify *notify) +{ + return NVIF_NOTIFY_KEEP; +} + +void +nv50_wndw_fini(struct nv50_wndw *wndw) +{ + nvif_notify_put(&wndw->notify); +} + +void +nv50_wndw_init(struct nv50_wndw *wndw) +{ + nvif_notify_get(&wndw->notify); +} + +int +nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, + enum drm_plane_type type, const char *name, int index, + const u32 *format, struct nv50_wndw **pwndw) +{ + struct nv50_wndw *wndw; + int nformat; + int ret; + + if (!(wndw = *pwndw = kzalloc(sizeof(*wndw), GFP_KERNEL))) + return -ENOMEM; + wndw->func = func; + wndw->id = index; + + wndw->ctxdma.parent = &wndw->wndw.base.user; + INIT_LIST_HEAD(&wndw->ctxdma.list); + + for (nformat = 0; format[nformat]; nformat++); + + ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw, + format, nformat, NULL, + type, "%s-%d", name, index); + if (ret) { + kfree(*pwndw); + *pwndw = NULL; + return ret; + } + + drm_plane_helper_add(&wndw->plane, &nv50_wndw_helper); + + wndw->notify.func = nv50_wndw_notify; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.h b/drivers/gpu/drm/nouveau/dispnv50/wndw.h new file mode 100644 index 0000000000000..1931e30681152 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.h @@ -0,0 +1,73 @@ +#ifndef __NV50_KMS_WNDW_H__ +#define __NV50_KMS_WNDW_H__ +#define nv50_wndw(p) container_of((p), struct nv50_wndw, plane) +#include "disp.h" +#include "atom.h" + +#include + +struct nv50_wndw_ctxdma { + struct list_head head; + struct nvif_object object; +}; + +struct nv50_wndw { + const struct nv50_wndw_func *func; + const struct nv50_wimm_func *immd; + int id; + + struct { + struct nvif_object *parent; + struct list_head list; + } ctxdma; + + struct drm_plane plane; + + struct nv50_dmac wndw; + struct nv50_dmac wimm; + + struct nvif_notify notify; + u16 ntfy; + u16 sema; + u32 data; +}; + +int nv50_wndw_new_(const struct nv50_wndw_func *, struct drm_device *, + enum drm_plane_type, const char *name, int index, + const u32 *format, struct nv50_wndw **); +void nv50_wndw_init(struct nv50_wndw *); +void nv50_wndw_fini(struct nv50_wndw *); +u32 nv50_wndw_flush_set(struct nv50_wndw *, u32 interlock, + struct nv50_wndw_atom *); +u32 nv50_wndw_flush_clr(struct nv50_wndw *, u32 interlock, bool flush, + struct nv50_wndw_atom *); +int nv50_wndw_wait_armed(struct nv50_wndw *, struct nv50_wndw_atom *); + +struct nv50_wndw_func { + int (*acquire)(struct nv50_wndw *, struct nv50_wndw_atom *asyw, + struct nv50_head_atom *asyh); + void (*release)(struct nv50_wndw *, struct nv50_wndw_atom *asyw, + struct nv50_head_atom *asyh); + void (*prepare)(struct nv50_wndw *, struct nv50_head_atom *asyh, + struct nv50_wndw_atom *asyw); + + void (*sema_set)(struct nv50_wndw *, struct nv50_wndw_atom *); + void (*sema_clr)(struct nv50_wndw *); + void (*ntfy_set)(struct nv50_wndw *, struct nv50_wndw_atom *); + void (*ntfy_clr)(struct nv50_wndw *); + int (*ntfy_wait_begun)(struct nv50_wndw *, struct nv50_wndw_atom *); + void (*image_set)(struct nv50_wndw *, struct nv50_wndw_atom *); + void (*image_clr)(struct nv50_wndw *); + void (*lut)(struct nv50_wndw *, struct nv50_wndw_atom *); + + u32 (*update)(struct nv50_wndw *, u32 interlock); +}; + +extern const struct drm_plane_funcs nv50_wndw; + +struct nv50_wimm_func { + void (*point)(struct nv50_wndw *, struct nv50_wndw_atom *); + + u32 (*update)(struct nv50_wndw *, u32 interlock); +}; +#endif diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h index 918187cee84bf..fbd3b15583bc8 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.h +++ b/drivers/gpu/drm/nouveau/nv50_display.h @@ -28,7 +28,6 @@ #define __NV50_DISPLAY_H__ #include "nouveau_display.h" -#include "nouveau_crtc.h" #include "nouveau_reg.h" int nv50_display_create(struct drm_device *); From 09e1b78aab5715eacab02e4047c7a47d72f6a1e9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 116/165] drm/nouveau/kms/nv50-: split core implementation by hardware class Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/Kbuild | 8 + drivers/gpu/drm/nouveau/dispnv50/core.c | 22 +- drivers/gpu/drm/nouveau/dispnv50/core.h | 20 ++ drivers/gpu/drm/nouveau/dispnv50/core507d.c | 51 ++- drivers/gpu/drm/nouveau/dispnv50/core827d.c | 41 +++ drivers/gpu/drm/nouveau/dispnv50/core907d.c | 40 +++ drivers/gpu/drm/nouveau/dispnv50/core917d.c | 40 +++ drivers/gpu/drm/nouveau/dispnv50/dac507d.c | 19 +- drivers/gpu/drm/nouveau/dispnv50/dac907d.c | 39 +++ drivers/gpu/drm/nouveau/dispnv50/disp.c | 46 +-- drivers/gpu/drm/nouveau/dispnv50/head.c | 29 +- drivers/gpu/drm/nouveau/dispnv50/head.h | 27 ++ drivers/gpu/drm/nouveau/dispnv50/head507d.c | 328 +++++++------------- drivers/gpu/drm/nouveau/dispnv50/head827d.c | 120 +++++++ drivers/gpu/drm/nouveau/dispnv50/head907d.c | 274 ++++++++++++++++ drivers/gpu/drm/nouveau/dispnv50/head917d.c | 55 ++++ drivers/gpu/drm/nouveau/dispnv50/pior507d.c | 18 +- drivers/gpu/drm/nouveau/dispnv50/sor507d.c | 18 +- drivers/gpu/drm/nouveau/dispnv50/sor907d.c | 41 +++ 19 files changed, 903 insertions(+), 333 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/dispnv50/core827d.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/core907d.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/core917d.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/dac907d.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/head827d.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/head907d.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/head917d.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/sor907d.c diff --git a/drivers/gpu/drm/nouveau/dispnv50/Kbuild b/drivers/gpu/drm/nouveau/dispnv50/Kbuild index f3877d2d88407..cde3ae98191a0 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/Kbuild +++ b/drivers/gpu/drm/nouveau/dispnv50/Kbuild @@ -2,15 +2,23 @@ nouveau-y += dispnv50/disp.o nouveau-y += dispnv50/core.o nouveau-y += dispnv50/core507d.o +nouveau-y += dispnv50/core827d.o +nouveau-y += dispnv50/core907d.o +nouveau-y += dispnv50/core917d.o nouveau-y += dispnv50/dac507d.o +nouveau-y += dispnv50/dac907d.o nouveau-y += dispnv50/pior507d.o nouveau-y += dispnv50/sor507d.o +nouveau-y += dispnv50/sor907d.o nouveau-y += dispnv50/head.o nouveau-y += dispnv50/head507d.o +nouveau-y += dispnv50/head827d.o +nouveau-y += dispnv50/head907d.o +nouveau-y += dispnv50/head917d.o nouveau-y += dispnv50/wndw.o diff --git a/drivers/gpu/drm/nouveau/dispnv50/core.c b/drivers/gpu/drm/nouveau/dispnv50/core.c index b12899fe052a4..f87cbaa4f8eca 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core.c +++ b/drivers/gpu/drm/nouveau/dispnv50/core.c @@ -42,17 +42,17 @@ nv50_core_new(struct nouveau_drm *drm, struct nv50_core **pcore) int version; int (*new)(struct nouveau_drm *, s32, struct nv50_core **); } cores[] = { - { GP102_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { GP100_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { GM200_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { GM107_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { GK110_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { GK104_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { GF110_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { GT214_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { GT206_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { GT200_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, - { G82_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, + { GP102_DISP_CORE_CHANNEL_DMA, 0, core917d_new }, + { GP100_DISP_CORE_CHANNEL_DMA, 0, core917d_new }, + { GM200_DISP_CORE_CHANNEL_DMA, 0, core917d_new }, + { GM107_DISP_CORE_CHANNEL_DMA, 0, core917d_new }, + { GK110_DISP_CORE_CHANNEL_DMA, 0, core917d_new }, + { GK104_DISP_CORE_CHANNEL_DMA, 0, core917d_new }, + { GF110_DISP_CORE_CHANNEL_DMA, 0, core907d_new }, + { GT214_DISP_CORE_CHANNEL_DMA, 0, core827d_new }, + { GT206_DISP_CORE_CHANNEL_DMA, 0, core827d_new }, + { GT200_DISP_CORE_CHANNEL_DMA, 0, core827d_new }, + { G82_DISP_CORE_CHANNEL_DMA, 0, core827d_new }, { NV50_DISP_CORE_CHANNEL_DMA, 0, core507d_new }, {} }; diff --git a/drivers/gpu/drm/nouveau/dispnv50/core.h b/drivers/gpu/drm/nouveau/dispnv50/core.h index 3cd54469311aa..5fd7ddd31e5e4 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core.h +++ b/drivers/gpu/drm/nouveau/dispnv50/core.h @@ -12,6 +12,12 @@ int nv50_core_new(struct nouveau_drm *, struct nv50_core **); void nv50_core_del(struct nv50_core **); struct nv50_core_func { + void (*init)(struct nv50_core *); + void (*ntfy_init)(struct nouveau_bo *, u32 offset); + int (*ntfy_wait_done)(struct nouveau_bo *, u32 offset, + struct nvif_device *); + void (*update)(struct nv50_core *, u32 interlock, bool ntfy); + const struct nv50_head_func *head; const struct nv50_outp_func { void (*ctrl)(struct nv50_core *, int or, u32 ctrl, @@ -20,7 +26,21 @@ struct nv50_core_func { }; int core507d_new(struct nouveau_drm *, s32, struct nv50_core **); +int core507d_new_(const struct nv50_core_func *, struct nouveau_drm *, s32, + struct nv50_core **); +void core507d_init(struct nv50_core *); +void core507d_ntfy_init(struct nouveau_bo *, u32); +int core507d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *); +void core507d_update(struct nv50_core *, u32, bool); extern const struct nv50_outp_func dac507d; extern const struct nv50_outp_func sor507d; 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 **); +extern const struct nv50_outp_func dac907d; +extern const struct nv50_outp_func sor907d; + +int core917d_new(struct nouveau_drm *, s32, struct nv50_core **); #endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/core507d.c b/drivers/gpu/drm/nouveau/dispnv50/core507d.c index b0325f69a26f6..96d7d8fde669c 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/core507d.c @@ -26,15 +26,64 @@ #include "nouveau_bo.h" +void +core507d_update(struct nv50_core *core, u32 interlock, bool ntfy) +{ + u32 *push; + if ((push = evo_wait(&core->chan, 5))) { + if (ntfy) { + evo_mthd(push, 0x0084, 1); + evo_data(push, 0x80000000 | NV50_DISP_CORE_NTFY); + } + evo_mthd(push, 0x0080, 2); + evo_data(push, interlock); + evo_data(push, 0x00000000); + evo_kick(push, &core->chan); + } +} + +int +core507d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset, + struct nvif_device *device) +{ + s64 time = nvif_msec(device, 2000ULL, + if (nouveau_bo_rd32(bo, offset / 4)) + break; + usleep_range(1, 2); + ); + return time < 0 ? time : 0; +} + +void +core507d_ntfy_init(struct nouveau_bo *bo, u32 offset) +{ + nouveau_bo_wr32(bo, offset / 4, 0x00000000); +} + +void +core507d_init(struct nv50_core *core) +{ + u32 *push; + if ((push = evo_wait(&core->chan, 2))) { + evo_mthd(push, 0x0088, 1); + evo_data(push, core->chan.sync.handle); + evo_kick(push, &core->chan); + } +} + static const struct nv50_core_func core507d = { + .init = core507d_init, + .ntfy_init = core507d_ntfy_init, + .ntfy_wait_done = core507d_ntfy_wait_done, + .update = core507d_update, .head = &head507d, .dac = &dac507d, .sor = &sor507d, .pior = &pior507d, }; -static int +int core507d_new_(const struct nv50_core_func *func, struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore) { diff --git a/drivers/gpu/drm/nouveau/dispnv50/core827d.c b/drivers/gpu/drm/nouveau/dispnv50/core827d.c new file mode 100644 index 0000000000000..6123a068f8364 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/core827d.c @@ -0,0 +1,41 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "core.h" +#include "head.h" + +static const struct nv50_core_func +core827d = { + .init = core507d_init, + .ntfy_init = core507d_ntfy_init, + .ntfy_wait_done = core507d_ntfy_wait_done, + .update = core507d_update, + .head = &head827d, + .dac = &dac507d, + .sor = &sor507d, + .pior = &pior507d, +}; + +int +core827d_new(struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore) +{ + return core507d_new_(&core827d, drm, oclass, pcore); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/core907d.c b/drivers/gpu/drm/nouveau/dispnv50/core907d.c new file mode 100644 index 0000000000000..ef822f8134355 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/core907d.c @@ -0,0 +1,40 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "core.h" +#include "head.h" + +static const struct nv50_core_func +core907d = { + .init = core507d_init, + .ntfy_init = core507d_ntfy_init, + .ntfy_wait_done = core507d_ntfy_wait_done, + .update = core507d_update, + .head = &head907d, + .dac = &dac907d, + .sor = &sor907d, +}; + +int +core907d_new(struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore) +{ + return core507d_new_(&core907d, drm, oclass, pcore); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/core917d.c b/drivers/gpu/drm/nouveau/dispnv50/core917d.c new file mode 100644 index 0000000000000..392338df5bfdc --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/core917d.c @@ -0,0 +1,40 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "core.h" +#include "head.h" + +static const struct nv50_core_func +core917d = { + .init = core507d_init, + .ntfy_init = core507d_ntfy_init, + .ntfy_wait_done = core507d_ntfy_wait_done, + .update = core507d_update, + .head = &head917d, + .dac = &dac907d, + .sor = &sor907d, +}; + +int +core917d_new(struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore) +{ + return core507d_new_(&core917d, drm, oclass, pcore); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/dac507d.c b/drivers/gpu/drm/nouveau/dispnv50/dac507d.c index 28b6025a80f3d..2a10ef7d30a80 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/dac507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/dac507d.c @@ -21,26 +21,19 @@ */ #include "core.h" -#include - static void dac507d_ctrl(struct nv50_core *core, int or, u32 ctrl, struct nv50_head_atom *asyh) { u32 *push, sync = 0; if ((push = evo_wait(&core->chan, 3))) { - if (core->chan.base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - if (asyh) { - sync |= asyh->or.nvsync << 1; - sync |= asyh->or.nhsync; - } - evo_mthd(push, 0x0400 + (or * 0x080), 2); - evo_data(push, ctrl); - evo_data(push, sync); - } else { - evo_mthd(push, 0x0180 + (or * 0x020), 1); - evo_data(push, ctrl); + if (asyh) { + sync |= asyh->or.nvsync << 1; + sync |= asyh->or.nhsync; } + evo_mthd(push, 0x0400 + (or * 0x080), 2); + evo_data(push, ctrl); + evo_data(push, sync); evo_kick(push, &core->chan); } } diff --git a/drivers/gpu/drm/nouveau/dispnv50/dac907d.c b/drivers/gpu/drm/nouveau/dispnv50/dac907d.c new file mode 100644 index 0000000000000..11e87fa53fac8 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/dac907d.c @@ -0,0 +1,39 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "core.h" + +static void +dac907d_ctrl(struct nv50_core *core, int or, u32 ctrl, + struct nv50_head_atom *asyh) +{ + u32 *push; + if ((push = evo_wait(&core->chan, 2))) { + evo_mthd(push, 0x0180 + (or * 0x020), 1); + evo_data(push, ctrl); + evo_kick(push, &core->chan); + } +} + +const struct nv50_outp_func +dac907d = { + .ctrl = dac907d_ctrl, +}; diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index a8367c5d4691b..6136beeba3fcf 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1587,10 +1587,9 @@ static void nv50_disp_atomic_commit_core(struct nouveau_drm *drm, u32 interlock) { struct nv50_disp *disp = nv50_disp(drm->dev); - struct nv50_dmac *core = &disp->core->chan; + struct nv50_core *core = disp->core; struct nv50_mstm *mstm; struct drm_encoder *encoder; - u32 *push; NV_ATOMIC(drm, "commit core %08x\n", interlock); @@ -1602,21 +1601,11 @@ nv50_disp_atomic_commit_core(struct nouveau_drm *drm, u32 interlock) } } - if ((push = evo_wait(core, 5))) { - evo_mthd(push, 0x0084, 1); - evo_data(push, 0x80000000); - evo_mthd(push, 0x0080, 2); - evo_data(push, interlock); - evo_data(push, 0x00000000); - nouveau_bo_wr32(disp->sync, 0, 0x00000000); - evo_kick(push, core); - if (nvif_msec(&drm->client.device, 2000ULL, - if (nouveau_bo_rd32(disp->sync, 0)) - break; - usleep_range(1, 2); - ) < 0) - NV_ERROR(drm, "EVO timeout\n"); - } + core->func->ntfy_init(disp->sync, NV50_DISP_CORE_NTFY); + core->func->update(core, interlock, true); + if (core->func->ntfy_wait_done(disp->sync, NV50_DISP_CORE_NTFY, + disp->core->chan.base.device)) + NV_ERROR(drm, "core notifier timeout\n"); drm_for_each_encoder(encoder, drm->dev) { if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) { @@ -1770,16 +1759,10 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) /* Flush update. */ if (interlock_core) { - if (!interlock_chan && atom->state.legacy_cursor_update) { - u32 *push = evo_wait(&disp->core->chan, 2); - if (push) { - evo_mthd(push, 0x0080, 1); - evo_data(push, 0x00000000); - evo_kick(push, &disp->core->chan); - } - } else { + if (interlock_chan || !atom->state.legacy_cursor_update) nv50_disp_atomic_commit_core(drm, interlock_chan); - } + else + disp->core->func->update(disp->core, 0, false); } if (atom->lock_core) @@ -2079,18 +2062,11 @@ nv50_display_fini(struct drm_device *dev) int nv50_display_init(struct drm_device *dev) { - struct nv50_dmac *core = &nv50_disp(dev)->core->chan; + struct nv50_core *core = nv50_disp(dev)->core; struct drm_encoder *encoder; struct drm_plane *plane; - u32 *push; - - push = evo_wait(core, 32); - if (!push) - return -EBUSY; - evo_mthd(push, 0x0088, 1); - evo_data(push, core->sync.handle); - evo_kick(push, core); + core->func->init(core); list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) { diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c index 6a809ff24e145..1335c00500d16 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head.c @@ -324,7 +324,6 @@ static int nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { struct nouveau_drm *drm = nouveau_drm(crtc->dev); - struct nv50_disp *disp = nv50_disp(crtc->dev); struct nv50_head *head = nv50_head(crtc); struct nv50_head_atom *armh = nv50_head_atom(crtc->state); struct nv50_head_atom *asyh = nv50_head_atom(state); @@ -373,31 +372,9 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) nv50_head_atomic_check_procamp(armh, asyh, asyc); } - if ((asyh->core.visible = (asyh->base.cpp != 0))) { - asyh->core.x = asyh->base.x; - asyh->core.y = asyh->base.y; - asyh->core.w = asyh->base.w; - asyh->core.h = asyh->base.h; - } else - if ((asyh->core.visible = asyh->curs.visible) || - (asyh->core.visible = asyh->ilut.visible)) { - /*XXX: We need to either find some way of having the - * primary base layer appear black, while still - * being able to display the other layers, or we - * need to allocate a dummy black surface here. - */ - asyh->core.x = 0; - asyh->core.y = 0; - asyh->core.w = asyh->state.mode.hdisplay; - asyh->core.h = asyh->state.mode.vdisplay; - } - asyh->core.handle = disp->core->chan.vram.handle; - asyh->core.offset = 0; - asyh->core.format = 0xcf; - asyh->core.kind = 0; - asyh->core.layout = 1; - asyh->core.block = 0; - asyh->core.pitch = ALIGN(asyh->core.w, 64) * 4; + if (head->func->core_calc) + head->func->core_calc(head, asyh); + asyh->set.base = armh->base.cpp != asyh->base.cpp; asyh->set.ovly = armh->ovly.cpp != asyh->ovly.cpp; } else { diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.h b/drivers/gpu/drm/nouveau/dispnv50/head.h index 23099a82883b1..d00cebdbd2600 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.h +++ b/drivers/gpu/drm/nouveau/dispnv50/head.h @@ -24,6 +24,7 @@ struct nv50_head_func { void (*mode)(struct nv50_head *, struct nv50_head_atom *); void (*ilut_set)(struct nv50_head *, struct nv50_head_atom *); void (*ilut_clr)(struct nv50_head *); + void (*core_calc)(struct nv50_head *, struct nv50_head_atom *); void (*core_set)(struct nv50_head *, struct nv50_head_atom *); void (*core_clr)(struct nv50_head *); void (*curs_set)(struct nv50_head *, struct nv50_head_atom *); @@ -36,4 +37,30 @@ struct nv50_head_func { }; extern const struct nv50_head_func head507d; +void head507d_view(struct nv50_head *, struct nv50_head_atom *); +void head507d_mode(struct nv50_head *, struct nv50_head_atom *); +void head507d_core_calc(struct nv50_head *, struct nv50_head_atom *); +void head507d_core_clr(struct nv50_head *); +void head507d_base(struct nv50_head *, struct nv50_head_atom *); +void head507d_ovly(struct nv50_head *, struct nv50_head_atom *); +void head507d_dither(struct nv50_head *, struct nv50_head_atom *); +void head507d_procamp(struct nv50_head *, struct nv50_head_atom *); + +extern const struct nv50_head_func head827d; + +extern const struct nv50_head_func head907d; +void head907d_view(struct nv50_head *, struct nv50_head_atom *); +void head907d_mode(struct nv50_head *, struct nv50_head_atom *); +void head907d_ilut_set(struct nv50_head *, struct nv50_head_atom *); +void head907d_ilut_clr(struct nv50_head *); +void head907d_core_set(struct nv50_head *, struct nv50_head_atom *); +void head907d_core_clr(struct nv50_head *); +void head907d_curs_set(struct nv50_head *, struct nv50_head_atom *); +void head907d_curs_clr(struct nv50_head *); +void head907d_base(struct nv50_head *, struct nv50_head_atom *); +void head907d_ovly(struct nv50_head *, struct nv50_head_atom *); +void head907d_procamp(struct nv50_head *, struct nv50_head_atom *); +void head907d_or(struct nv50_head *, struct nv50_head_atom *); + +extern const struct nv50_head_func head917d; #endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/head507d.c b/drivers/gpu/drm/nouveau/dispnv50/head507d.c index 92fa249ba72fc..5f06fa174832f 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head507d.c @@ -22,62 +22,34 @@ #include "head.h" #include "core.h" -#include - -static void -head907d_or(struct nv50_head *head, struct nv50_head_atom *asyh) -{ - struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; - u32 *push; - if (core->base.user.oclass >= GF110_DISP_CORE_CHANNEL_DMA && - (push = evo_wait(core, 3))) { - evo_mthd(push, 0x0404 + (head->base.index * 0x300), 2); - evo_data(push, 0x00000001 | (asyh->or.depth << 6) | - (asyh->or.nvsync << 4) | - (asyh->or.nhsync << 3)); - evo_data(push, 0x31ec6000 | (head->base.index << 25) | - asyh->mode.interlace); - evo_kick(push, core); - } -} - -static void +void head507d_procamp(struct nv50_head *head, struct nv50_head_atom *asyh) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if ((push = evo_wait(core, 2))) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) - evo_mthd(push, 0x08a8 + (head->base.index * 0x400), 1); - else - evo_mthd(push, 0x0498 + (head->base.index * 0x300), 1); - evo_data(push, (asyh->procamp.sat.sin << 20) | - (asyh->procamp.sat.cos << 8)); + evo_mthd(push, 0x08a8 + (head->base.index * 0x400), 1); + evo_data(push, asyh->procamp.sat.sin << 20 | + asyh->procamp.sat.cos << 8); evo_kick(push, core); } } -static void +void head507d_dither(struct nv50_head *head, struct nv50_head_atom *asyh) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if ((push = evo_wait(core, 2))) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) - evo_mthd(push, 0x08a0 + (head->base.index * 0x0400), 1); - else - if (core->base.user.oclass < GK104_DISP_CORE_CHANNEL_DMA) - evo_mthd(push, 0x0490 + (head->base.index * 0x0300), 1); - else - evo_mthd(push, 0x04a0 + (head->base.index * 0x0300), 1); - evo_data(push, (asyh->dither.mode << 3) | - (asyh->dither.bits << 1) | - asyh->dither.enable); + evo_mthd(push, 0x08a0 + (head->base.index * 0x0400), 1); + evo_data(push, asyh->dither.mode << 3 | + asyh->dither.bits << 1 | + asyh->dither.enable); evo_kick(push, core); } } -static void +void head507d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; @@ -97,16 +69,13 @@ head507d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh) } if ((push = evo_wait(core, 2))) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) - evo_mthd(push, 0x0904 + head->base.index * 0x400, 1); - else - evo_mthd(push, 0x04d4 + head->base.index * 0x300, 1); + evo_mthd(push, 0x0904 + head->base.index * 0x400, 1); evo_data(push, bounds); evo_kick(push, core); } } -static void +void head507d_base(struct nv50_head *head, struct nv50_head_atom *asyh) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; @@ -127,10 +96,7 @@ head507d_base(struct nv50_head *head, struct nv50_head_atom *asyh) } if ((push = evo_wait(core, 2))) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) - evo_mthd(push, 0x0900 + head->base.index * 0x400, 1); - else - evo_mthd(push, 0x04d0 + head->base.index * 0x300, 1); + evo_mthd(push, 0x0900 + head->base.index * 0x400, 1); evo_data(push, bounds); evo_kick(push, core); } @@ -141,22 +107,9 @@ head507d_curs_clr(struct nv50_head *head) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; - if ((push = evo_wait(core, 4))) { - if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0880 + head->base.index * 0x400, 1); - evo_data(push, 0x05000000); - } else - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0880 + head->base.index * 0x400, 1); - evo_data(push, 0x05000000); - evo_mthd(push, 0x089c + head->base.index * 0x400, 1); - evo_data(push, 0x00000000); - } else { - evo_mthd(push, 0x0480 + head->base.index * 0x300, 1); - evo_data(push, 0x05000000); - evo_mthd(push, 0x048c + head->base.index * 0x300, 1); - evo_data(push, 0x00000000); - } + if ((push = evo_wait(core, 2))) { + evo_mthd(push, 0x0880 + head->base.index * 0x400, 1); + evo_data(push, 0x05000000); evo_kick(push, core); } } @@ -166,42 +119,22 @@ head507d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; - if ((push = evo_wait(core, 5))) { - if (core->base.user.oclass < G82_DISP_BASE_CHANNEL_DMA) { - evo_mthd(push, 0x0880 + head->base.index * 0x400, 2); - evo_data(push, 0x80000000 | (asyh->curs.layout << 26) | - (asyh->curs.format << 24)); - evo_data(push, asyh->curs.offset >> 8); - } else - if (core->base.user.oclass < GF110_DISP_BASE_CHANNEL_DMA) { - evo_mthd(push, 0x0880 + head->base.index * 0x400, 2); - evo_data(push, 0x80000000 | (asyh->curs.layout << 26) | - (asyh->curs.format << 24)); - evo_data(push, asyh->curs.offset >> 8); - evo_mthd(push, 0x089c + head->base.index * 0x400, 1); - evo_data(push, asyh->curs.handle); - } else { - evo_mthd(push, 0x0480 + head->base.index * 0x300, 2); - evo_data(push, 0x80000000 | (asyh->curs.layout << 26) | - (asyh->curs.format << 24)); - evo_data(push, asyh->curs.offset >> 8); - evo_mthd(push, 0x048c + head->base.index * 0x300, 1); - evo_data(push, asyh->curs.handle); - } + if ((push = evo_wait(core, 3))) { + evo_mthd(push, 0x0880 + head->base.index * 0x400, 2); + evo_data(push, 0x80000000 | asyh->curs.layout << 26 | + asyh->curs.format << 24); + evo_data(push, asyh->curs.offset >> 8); evo_kick(push, core); } } -static void +void head507d_core_clr(struct nv50_head *head) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if ((push = evo_wait(core, 2))) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) - evo_mthd(push, 0x0874 + head->base.index * 0x400, 1); - else - evo_mthd(push, 0x0474 + head->base.index * 0x300, 1); + evo_mthd(push, 0x0874 + head->base.index * 0x400, 1); evo_data(push, 0x00000000); evo_kick(push, core); } @@ -213,52 +146,57 @@ head507d_core_set(struct nv50_head *head, struct nv50_head_atom *asyh) struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if ((push = evo_wait(core, 9))) { - if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0860 + head->base.index * 0x400, 1); - evo_data(push, asyh->core.offset >> 8); - evo_mthd(push, 0x0868 + head->base.index * 0x400, 4); - evo_data(push, (asyh->core.h << 16) | asyh->core.w); - evo_data(push, asyh->core.layout << 20 | - (asyh->core.pitch >> 8) << 8 | - asyh->core.block); - evo_data(push, asyh->core.kind << 16 | - asyh->core.format << 8); - evo_data(push, asyh->core.handle); - evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1); - evo_data(push, (asyh->core.y << 16) | asyh->core.x); - /* EVO will complain with INVALID_STATE if we have an - * active cursor and (re)specify HeadSetContextDmaIso - * without also updating HeadSetOffsetCursor. - */ - asyh->set.curs = asyh->curs.visible; - } else - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0860 + head->base.index * 0x400, 1); - evo_data(push, asyh->core.offset >> 8); - evo_mthd(push, 0x0868 + head->base.index * 0x400, 4); - evo_data(push, (asyh->core.h << 16) | asyh->core.w); - evo_data(push, asyh->core.layout << 20 | - (asyh->core.pitch >> 8) << 8 | - asyh->core.block); - evo_data(push, asyh->core.format << 8); - evo_data(push, asyh->core.handle); - evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1); - evo_data(push, (asyh->core.y << 16) | asyh->core.x); - } else { - evo_mthd(push, 0x0460 + head->base.index * 0x300, 1); - evo_data(push, asyh->core.offset >> 8); - evo_mthd(push, 0x0468 + head->base.index * 0x300, 4); - evo_data(push, (asyh->core.h << 16) | asyh->core.w); - evo_data(push, asyh->core.layout << 24 | - (asyh->core.pitch >> 8) << 8 | - asyh->core.block); - evo_data(push, asyh->core.format << 8); - evo_data(push, asyh->core.handle); - evo_mthd(push, 0x04b0 + head->base.index * 0x300, 1); - evo_data(push, (asyh->core.y << 16) | asyh->core.x); - } + evo_mthd(push, 0x0860 + head->base.index * 0x400, 1); + evo_data(push, asyh->core.offset >> 8); + evo_mthd(push, 0x0868 + head->base.index * 0x400, 4); + evo_data(push, asyh->core.h << 16 | asyh->core.w); + evo_data(push, asyh->core.layout << 20 | + asyh->core.pitch >> 8 << 8 | + asyh->core.block); + evo_data(push, asyh->core.kind << 16 | + asyh->core.format << 8); + evo_data(push, asyh->core.handle); + evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1); + evo_data(push, asyh->core.y << 16 | asyh->core.x); evo_kick(push, core); + + /* EVO will complain with INVALID_STATE if we have an + * active cursor and (re)specify HeadSetContextDmaIso + * without also updating HeadSetOffsetCursor. + */ + asyh->set.curs = asyh->curs.visible; + } +} + +void +head507d_core_calc(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_disp *disp = nv50_disp(head->base.base.dev); + if ((asyh->core.visible = (asyh->base.cpp != 0))) { + asyh->core.x = asyh->base.x; + asyh->core.y = asyh->base.y; + asyh->core.w = asyh->base.w; + asyh->core.h = asyh->base.h; + } else + if ((asyh->core.visible = asyh->curs.visible) || + (asyh->core.visible = asyh->ilut.visible)) { + /*XXX: We need to either find some way of having the + * primary base layer appear black, while still + * being able to display the other layers, or we + * need to allocate a dummy black surface here. + */ + asyh->core.x = 0; + asyh->core.y = 0; + asyh->core.w = asyh->state.mode.hdisplay; + asyh->core.h = asyh->state.mode.vdisplay; } + asyh->core.handle = disp->core->chan.vram.handle; + asyh->core.offset = 0; + asyh->core.format = 0xcf; + asyh->core.kind = 0; + asyh->core.layout = 1; + asyh->core.block = 0; + asyh->core.pitch = ALIGN(asyh->core.w, 64) * 4; } static void @@ -266,22 +204,9 @@ head507d_ilut_clr(struct nv50_head *head) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; - if ((push = evo_wait(core, 4))) { - if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1); - evo_data(push, 0x40000000); - } else - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1); - evo_data(push, 0x40000000); - evo_mthd(push, 0x085c + (head->base.index * 0x400), 1); - evo_data(push, 0x00000000); - } else { - evo_mthd(push, 0x0440 + (head->base.index * 0x300), 1); - evo_data(push, 0x03000000); - evo_mthd(push, 0x045c + (head->base.index * 0x300), 1); - evo_data(push, 0x00000000); - } + if ((push = evo_wait(core, 2))) { + evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1); + evo_data(push, 0x40000000); evo_kick(push, core); } } @@ -291,96 +216,51 @@ head507d_ilut_set(struct nv50_head *head, struct nv50_head_atom *asyh) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; - if ((push = evo_wait(core, 7))) { - if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2); - evo_data(push, 0x80000000 | asyh->ilut.mode << 30); - evo_data(push, asyh->ilut.offset >> 8); - } else - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2); - evo_data(push, 0x80000000 | asyh->ilut.mode << 30); - evo_data(push, asyh->ilut.offset >> 8); - evo_mthd(push, 0x085c + (head->base.index * 0x400), 1); - evo_data(push, asyh->ilut.handle); - } else { - evo_mthd(push, 0x0440 + (head->base.index * 0x300), 4); - evo_data(push, 0x80000000 | asyh->ilut.mode << 24); - evo_data(push, asyh->ilut.offset >> 8); - evo_data(push, 0x00000000); - evo_data(push, 0x00000000); - evo_mthd(push, 0x045c + (head->base.index * 0x300), 1); - evo_data(push, asyh->ilut.handle); - } + if ((push = evo_wait(core, 3))) { + evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2); + evo_data(push, 0x80000000 | asyh->ilut.mode << 30); + evo_data(push, asyh->ilut.offset >> 8); evo_kick(push, core); } } -static void +void head507d_mode(struct nv50_head *head, struct nv50_head_atom *asyh) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; struct nv50_head_mode *m = &asyh->mode; u32 *push; - if ((push = evo_wait(core, 14))) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x0804 + (head->base.index * 0x400), 2); - evo_data(push, 0x00800000 | m->clock); - evo_data(push, m->interlace ? 0x00000002 : 0x00000000); - evo_mthd(push, 0x0810 + (head->base.index * 0x400), 7); - evo_data(push, 0x00000000); - evo_data(push, (m->v.active << 16) | m->h.active ); - evo_data(push, (m->v.synce << 16) | m->h.synce ); - evo_data(push, (m->v.blanke << 16) | m->h.blanke ); - evo_data(push, (m->v.blanks << 16) | m->h.blanks ); - evo_data(push, (m->v.blank2e << 16) | m->v.blank2s); - evo_data(push, asyh->mode.v.blankus); - evo_mthd(push, 0x082c + (head->base.index * 0x400), 1); - evo_data(push, 0x00000000); - } else { - evo_mthd(push, 0x0410 + (head->base.index * 0x300), 6); - evo_data(push, 0x00000000); - evo_data(push, (m->v.active << 16) | m->h.active ); - evo_data(push, (m->v.synce << 16) | m->h.synce ); - evo_data(push, (m->v.blanke << 16) | m->h.blanke ); - evo_data(push, (m->v.blanks << 16) | m->h.blanks ); - evo_data(push, (m->v.blank2e << 16) | m->v.blank2s); - evo_mthd(push, 0x042c + (head->base.index * 0x300), 2); - evo_data(push, 0x00000000); /* ??? */ - evo_data(push, 0xffffff00); - evo_mthd(push, 0x0450 + (head->base.index * 0x300), 3); - evo_data(push, m->clock * 1000); - evo_data(push, 0x00200000); /* ??? */ - evo_data(push, m->clock * 1000); - } + if ((push = evo_wait(core, 13))) { + evo_mthd(push, 0x0804 + (head->base.index * 0x400), 2); + evo_data(push, 0x00800000 | m->clock); + evo_data(push, m->interlace ? 0x00000002 : 0x00000000); + evo_mthd(push, 0x0810 + (head->base.index * 0x400), 7); + evo_data(push, 0x00000000); + evo_data(push, m->v.active << 16 | m->h.active ); + evo_data(push, m->v.synce << 16 | m->h.synce ); + evo_data(push, m->v.blanke << 16 | m->h.blanke ); + evo_data(push, m->v.blanks << 16 | m->h.blanks ); + evo_data(push, m->v.blank2e << 16 | m->v.blank2s); + evo_data(push, asyh->mode.v.blankus); + evo_mthd(push, 0x082c + (head->base.index * 0x400), 1); + evo_data(push, 0x00000000); evo_kick(push, core); } } -static void +void head507d_view(struct nv50_head *head, struct nv50_head_atom *asyh) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; - if ((push = evo_wait(core, 10))) { - if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - evo_mthd(push, 0x08a4 + (head->base.index * 0x400), 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x08c8 + (head->base.index * 0x400), 1); - evo_data(push, (asyh->view.iH << 16) | asyh->view.iW); - evo_mthd(push, 0x08d8 + (head->base.index * 0x400), 2); - evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); - evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); - } else { - evo_mthd(push, 0x0494 + (head->base.index * 0x300), 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x04b8 + (head->base.index * 0x300), 1); - evo_data(push, (asyh->view.iH << 16) | asyh->view.iW); - evo_mthd(push, 0x04c0 + (head->base.index * 0x300), 3); - evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); - evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); - evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); - } + if ((push = evo_wait(core, 7))) { + evo_mthd(push, 0x08a4 + (head->base.index * 0x400), 1); + evo_data(push, 0x00000000); + evo_mthd(push, 0x08c8 + (head->base.index * 0x400), 1); + evo_data(push, asyh->view.iH << 16 | asyh->view.iW); + evo_mthd(push, 0x08d8 + (head->base.index * 0x400), 2); + evo_data(push, asyh->view.oH << 16 | asyh->view.oW); + evo_data(push, asyh->view.oH << 16 | asyh->view.oW); evo_kick(push, core); } } @@ -391,6 +271,7 @@ head507d = { .mode = head507d_mode, .ilut_set = head507d_ilut_set, .ilut_clr = head507d_ilut_clr, + .core_calc = head507d_core_calc, .core_set = head507d_core_set, .core_clr = head507d_core_clr, .curs_set = head507d_curs_set, @@ -399,5 +280,4 @@ head507d = { .ovly = head507d_ovly, .dither = head507d_dither, .procamp = head507d_procamp, - .or = head907d_or, }; diff --git a/drivers/gpu/drm/nouveau/dispnv50/head827d.c b/drivers/gpu/drm/nouveau/dispnv50/head827d.c new file mode 100644 index 0000000000000..84ce595fbe793 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/head827d.c @@ -0,0 +1,120 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "head.h" +#include "core.h" + +static void +head827d_curs_clr(struct nv50_head *head) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 4))) { + evo_mthd(push, 0x0880 + head->base.index * 0x400, 1); + evo_data(push, 0x05000000); + evo_mthd(push, 0x089c + head->base.index * 0x400, 1); + evo_data(push, 0x00000000); + evo_kick(push, core); + } +} + +static void +head827d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 5))) { + evo_mthd(push, 0x0880 + head->base.index * 0x400, 2); + evo_data(push, 0x80000000 | asyh->curs.layout << 26 | + asyh->curs.format << 24); + evo_data(push, asyh->curs.offset >> 8); + evo_mthd(push, 0x089c + head->base.index * 0x400, 1); + evo_data(push, asyh->curs.handle); + evo_kick(push, core); + } +} + +static void +head827d_core_set(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 9))) { + evo_mthd(push, 0x0860 + head->base.index * 0x400, 1); + evo_data(push, asyh->core.offset >> 8); + evo_mthd(push, 0x0868 + head->base.index * 0x400, 4); + evo_data(push, asyh->core.h << 16 | asyh->core.w); + evo_data(push, asyh->core.layout << 20 | + (asyh->core.pitch >> 8) << 8 | + asyh->core.block); + evo_data(push, asyh->core.format << 8); + evo_data(push, asyh->core.handle); + evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1); + evo_data(push, asyh->core.y << 16 | asyh->core.x); + evo_kick(push, core); + } +} + +static void +head827d_ilut_clr(struct nv50_head *head) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 4))) { + evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1); + evo_data(push, 0x40000000); + evo_mthd(push, 0x085c + (head->base.index * 0x400), 1); + evo_data(push, 0x00000000); + evo_kick(push, core); + } +} + +static void +head827d_ilut_set(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 5))) { + evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2); + evo_data(push, 0x80000000 | asyh->ilut.mode << 30); + evo_data(push, asyh->ilut.offset >> 8); + evo_mthd(push, 0x085c + (head->base.index * 0x400), 1); + evo_data(push, asyh->ilut.handle); + evo_kick(push, core); + } +} + +const struct nv50_head_func +head827d = { + .view = head507d_view, + .mode = head507d_mode, + .ilut_set = head827d_ilut_set, + .ilut_clr = head827d_ilut_clr, + .core_calc = head507d_core_calc, + .core_set = head827d_core_set, + .core_clr = head507d_core_clr, + .curs_set = head827d_curs_set, + .curs_clr = head827d_curs_clr, + .base = head507d_base, + .ovly = head507d_ovly, + .dither = head507d_dither, + .procamp = head507d_procamp, +}; diff --git a/drivers/gpu/drm/nouveau/dispnv50/head907d.c b/drivers/gpu/drm/nouveau/dispnv50/head907d.c new file mode 100644 index 0000000000000..0035eccd62d61 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/head907d.c @@ -0,0 +1,274 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "head.h" +#include "core.h" + +void +head907d_or(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 3))) { + evo_mthd(push, 0x0404 + (head->base.index * 0x300), 2); + evo_data(push, 0x00000001 | asyh->or.depth << 6 | + asyh->or.nvsync << 4 | + asyh->or.nhsync << 3); + evo_data(push, 0x31ec6000 | head->base.index << 25 | + asyh->mode.interlace); + evo_kick(push, core); + } +} + +void +head907d_procamp(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 2))) { + evo_mthd(push, 0x0498 + (head->base.index * 0x300), 1); + evo_data(push, asyh->procamp.sat.sin << 20 | + asyh->procamp.sat.cos << 8); + evo_kick(push, core); + } +} + +static void +head907d_dither(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 2))) { + evo_mthd(push, 0x0490 + (head->base.index * 0x0300), 1); + evo_data(push, asyh->dither.mode << 3 | + asyh->dither.bits << 1 | + asyh->dither.enable); + evo_kick(push, core); + } +} + +void +head907d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 bounds = 0; + u32 *push; + + if (asyh->ovly.cpp) { + switch (asyh->ovly.cpp) { + case 8: bounds |= 0x00000500; break; + case 4: bounds |= 0x00000300; break; + case 2: bounds |= 0x00000100; break; + default: + WARN_ON(1); + break; + } + bounds |= 0x00000001; + } + + if ((push = evo_wait(core, 2))) { + evo_mthd(push, 0x04d4 + head->base.index * 0x300, 1); + evo_data(push, bounds); + evo_kick(push, core); + } +} + +void +head907d_base(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 bounds = 0; + u32 *push; + + if (asyh->base.cpp) { + switch (asyh->base.cpp) { + case 8: bounds |= 0x00000500; break; + case 4: bounds |= 0x00000300; break; + case 2: bounds |= 0x00000100; break; + case 1: bounds |= 0x00000000; break; + default: + WARN_ON(1); + break; + } + bounds |= 0x00000001; + } + + if ((push = evo_wait(core, 2))) { + evo_mthd(push, 0x04d0 + head->base.index * 0x300, 1); + evo_data(push, bounds); + evo_kick(push, core); + } +} + +void +head907d_curs_clr(struct nv50_head *head) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 4))) { + evo_mthd(push, 0x0480 + head->base.index * 0x300, 1); + evo_data(push, 0x05000000); + evo_mthd(push, 0x048c + head->base.index * 0x300, 1); + evo_data(push, 0x00000000); + evo_kick(push, core); + } +} + +void +head907d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 5))) { + evo_mthd(push, 0x0480 + head->base.index * 0x300, 2); + evo_data(push, 0x80000000 | asyh->curs.layout << 26 | + asyh->curs.format << 24); + evo_data(push, asyh->curs.offset >> 8); + evo_mthd(push, 0x048c + head->base.index * 0x300, 1); + evo_data(push, asyh->curs.handle); + evo_kick(push, core); + } +} + +void +head907d_core_clr(struct nv50_head *head) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 2))) { + evo_mthd(push, 0x0474 + head->base.index * 0x300, 1); + evo_data(push, 0x00000000); + evo_kick(push, core); + } +} + +void +head907d_core_set(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 9))) { + evo_mthd(push, 0x0460 + head->base.index * 0x300, 1); + evo_data(push, asyh->core.offset >> 8); + evo_mthd(push, 0x0468 + head->base.index * 0x300, 4); + evo_data(push, asyh->core.h << 16 | asyh->core.w); + evo_data(push, asyh->core.layout << 24 | + (asyh->core.pitch >> 8) << 8 | + asyh->core.block); + evo_data(push, asyh->core.format << 8); + evo_data(push, asyh->core.handle); + evo_mthd(push, 0x04b0 + head->base.index * 0x300, 1); + evo_data(push, asyh->core.y << 16 | asyh->core.x); + evo_kick(push, core); + } +} + +void +head907d_ilut_clr(struct nv50_head *head) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 4))) { + evo_mthd(push, 0x0440 + (head->base.index * 0x300), 1); + evo_data(push, 0x03000000); + evo_mthd(push, 0x045c + (head->base.index * 0x300), 1); + evo_data(push, 0x00000000); + evo_kick(push, core); + } +} + +void +head907d_ilut_set(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 7))) { + evo_mthd(push, 0x0440 + (head->base.index * 0x300), 4); + evo_data(push, 0x80000000 | asyh->ilut.mode << 24); + evo_data(push, asyh->ilut.offset >> 8); + evo_data(push, 0x00000000); + evo_data(push, 0x00000000); + evo_mthd(push, 0x045c + (head->base.index * 0x300), 1); + evo_data(push, asyh->ilut.handle); + evo_kick(push, core); + } +} + +void +head907d_mode(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + struct nv50_head_mode *m = &asyh->mode; + u32 *push; + if ((push = evo_wait(core, 14))) { + evo_mthd(push, 0x0410 + (head->base.index * 0x300), 6); + evo_data(push, 0x00000000); + evo_data(push, m->v.active << 16 | m->h.active ); + evo_data(push, m->v.synce << 16 | m->h.synce ); + evo_data(push, m->v.blanke << 16 | m->h.blanke ); + evo_data(push, m->v.blanks << 16 | m->h.blanks ); + evo_data(push, m->v.blank2e << 16 | m->v.blank2s); + evo_mthd(push, 0x042c + (head->base.index * 0x300), 2); + evo_data(push, 0x00000000); /* ??? */ + evo_data(push, 0xffffff00); + evo_mthd(push, 0x0450 + (head->base.index * 0x300), 3); + evo_data(push, m->clock * 1000); + evo_data(push, 0x00200000); /* ??? */ + evo_data(push, m->clock * 1000); + evo_kick(push, core); + } +} + +void +head907d_view(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 8))) { + evo_mthd(push, 0x0494 + (head->base.index * 0x300), 1); + evo_data(push, 0x00000000); + evo_mthd(push, 0x04b8 + (head->base.index * 0x300), 1); + evo_data(push, asyh->view.iH << 16 | asyh->view.iW); + evo_mthd(push, 0x04c0 + (head->base.index * 0x300), 3); + evo_data(push, asyh->view.oH << 16 | asyh->view.oW); + evo_data(push, asyh->view.oH << 16 | asyh->view.oW); + evo_data(push, asyh->view.oH << 16 | asyh->view.oW); + evo_kick(push, core); + } +} + +const struct nv50_head_func +head907d = { + .view = head907d_view, + .mode = head907d_mode, + .ilut_set = head907d_ilut_set, + .ilut_clr = head907d_ilut_clr, + .core_calc = head507d_core_calc, + .core_set = head907d_core_set, + .core_clr = head907d_core_clr, + .curs_set = head907d_curs_set, + .curs_clr = head907d_curs_clr, + .base = head907d_base, + .ovly = head907d_ovly, + .dither = head907d_dither, + .procamp = head907d_procamp, + .or = head907d_or, +}; diff --git a/drivers/gpu/drm/nouveau/dispnv50/head917d.c b/drivers/gpu/drm/nouveau/dispnv50/head917d.c new file mode 100644 index 0000000000000..5341ea3bc7b60 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/head917d.c @@ -0,0 +1,55 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "head.h" +#include "core.h" + +static void +head917d_dither(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 2))) { + evo_mthd(push, 0x04a0 + (head->base.index * 0x0300), 1); + evo_data(push, asyh->dither.mode << 3 | + asyh->dither.bits << 1 | + asyh->dither.enable); + evo_kick(push, core); + } +} + +const struct nv50_head_func +head917d = { + .view = head907d_view, + .mode = head907d_mode, + .ilut_set = head907d_ilut_set, + .ilut_clr = head907d_ilut_clr, + .core_calc = head507d_core_calc, + .core_set = head907d_core_set, + .core_clr = head907d_core_clr, + .curs_set = head907d_curs_set, + .curs_clr = head907d_curs_clr, + .base = head907d_base, + .ovly = head907d_ovly, + .dither = head917d_dither, + .procamp = head907d_procamp, + .or = head907d_or, +}; diff --git a/drivers/gpu/drm/nouveau/dispnv50/pior507d.c b/drivers/gpu/drm/nouveau/dispnv50/pior507d.c index a99ba6a7216f5..d2bac6a341dcb 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/pior507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/pior507d.c @@ -21,23 +21,19 @@ */ #include "core.h" -#include - static void pior507d_ctrl(struct nv50_core *core, int or, u32 ctrl, struct nv50_head_atom *asyh) { u32 *push; - if ((push = evo_wait(&core->chan, 8))) { - if (core->chan.base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - if (asyh) { - ctrl |= asyh->or.depth << 16; - ctrl |= asyh->or.nvsync << 13; - ctrl |= asyh->or.nhsync << 12; - } - evo_mthd(push, 0x0700 + (or * 0x040), 1); - evo_data(push, ctrl); + if ((push = evo_wait(&core->chan, 2))) { + if (asyh) { + ctrl |= asyh->or.depth << 16; + ctrl |= asyh->or.nvsync << 13; + ctrl |= asyh->or.nhsync << 12; } + evo_mthd(push, 0x0700 + (or * 0x040), 1); + evo_data(push, ctrl); evo_kick(push, &core->chan); } } diff --git a/drivers/gpu/drm/nouveau/dispnv50/sor507d.c b/drivers/gpu/drm/nouveau/dispnv50/sor507d.c index 2d540de27f592..5222fe6a9b21c 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/sor507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/sor507d.c @@ -21,24 +21,18 @@ */ #include "core.h" -#include - static void sor507d_ctrl(struct nv50_core *core, int or, u32 ctrl, struct nv50_head_atom *asyh) { u32 *push; - if ((push = evo_wait(&core->chan, 6))) { - if (core->chan.base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { - if (asyh) { - ctrl |= asyh->or.depth << 16; - ctrl |= asyh->or.nvsync << 13; - ctrl |= asyh->or.nhsync << 12; - } - evo_mthd(push, 0x0600 + (or * 0x40), 1); - } else { - evo_mthd(push, 0x0200 + (or * 0x20), 1); + if ((push = evo_wait(&core->chan, 2))) { + if (asyh) { + ctrl |= asyh->or.depth << 16; + ctrl |= asyh->or.nvsync << 13; + ctrl |= asyh->or.nhsync << 12; } + evo_mthd(push, 0x0600 + (or * 0x40), 1); evo_data(push, ctrl); evo_kick(push, &core->chan); } diff --git a/drivers/gpu/drm/nouveau/dispnv50/sor907d.c b/drivers/gpu/drm/nouveau/dispnv50/sor907d.c new file mode 100644 index 0000000000000..b0314ec11fb3b --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/sor907d.c @@ -0,0 +1,41 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "core.h" + +#include + +static void +sor907d_ctrl(struct nv50_core *core, int or, u32 ctrl, + struct nv50_head_atom *asyh) +{ + u32 *push; + if ((push = evo_wait(&core->chan, 2))) { + evo_mthd(push, 0x0200 + (or * 0x20), 1); + evo_data(push, ctrl); + evo_kick(push, &core->chan); + } +} + +const struct nv50_outp_func +sor907d = { + .ctrl = sor907d_ctrl, +}; From ccd27db8c731817ef36e75de2b5fdc2e79550213 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 117/165] drm/nouveau/kms/nv50-: split base implementation by hardware class Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/Kbuild | 2 + drivers/gpu/drm/nouveau/dispnv50/base.c | 12 +-- drivers/gpu/drm/nouveau/dispnv50/base.h | 21 ++++ drivers/gpu/drm/nouveau/dispnv50/base507c.c | 101 ++++++++------------ drivers/gpu/drm/nouveau/dispnv50/base827c.c | 67 +++++++++++++ drivers/gpu/drm/nouveau/dispnv50/base907c.c | 80 ++++++++++++++++ drivers/gpu/drm/nouveau/dispnv50/disp.c | 11 +-- drivers/gpu/drm/nouveau/dispnv50/wndw.c | 22 ++++- drivers/gpu/drm/nouveau/dispnv50/wndw.h | 5 +- 9 files changed, 242 insertions(+), 79 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/dispnv50/base827c.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/base907c.c diff --git a/drivers/gpu/drm/nouveau/dispnv50/Kbuild b/drivers/gpu/drm/nouveau/dispnv50/Kbuild index cde3ae98191a0..674221dea7a11 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/Kbuild +++ b/drivers/gpu/drm/nouveau/dispnv50/Kbuild @@ -24,6 +24,8 @@ nouveau-y += dispnv50/wndw.o nouveau-y += dispnv50/base.o nouveau-y += dispnv50/base507c.o +nouveau-y += dispnv50/base827c.o +nouveau-y += dispnv50/base907c.o nouveau-y += dispnv50/curs.o nouveau-y += dispnv50/curs507a.o diff --git a/drivers/gpu/drm/nouveau/dispnv50/base.c b/drivers/gpu/drm/nouveau/dispnv50/base.c index 12ca5d70509c2..5f184ab833e80 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base.c @@ -31,12 +31,12 @@ nv50_base_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) int version; int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); } bases[] = { - { GK110_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, - { GK104_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, - { GF110_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, - { GT214_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, - { GT200_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, - { G82_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, + { GK110_DISP_BASE_CHANNEL_DMA, 0, base907c_new }, + { GK104_DISP_BASE_CHANNEL_DMA, 0, base907c_new }, + { GF110_DISP_BASE_CHANNEL_DMA, 0, base907c_new }, + { GT214_DISP_BASE_CHANNEL_DMA, 0, base827c_new }, + { GT200_DISP_BASE_CHANNEL_DMA, 0, base827c_new }, + { G82_DISP_BASE_CHANNEL_DMA, 0, base827c_new }, { NV50_DISP_BASE_CHANNEL_DMA, 0, base507c_new }, {} }; diff --git a/drivers/gpu/drm/nouveau/dispnv50/base.h b/drivers/gpu/drm/nouveau/dispnv50/base.h index 1daba7319ba98..edf96a8d645f2 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base.h +++ b/drivers/gpu/drm/nouveau/dispnv50/base.h @@ -3,6 +3,27 @@ #include "wndw.h" int base507c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); +int base507c_new_(const struct nv50_wndw_func *, const u32 *format, + struct nouveau_drm *, int head, s32 oclass, + struct nv50_wndw **); +extern const u32 base507c_format[]; +int base507c_acquire(struct nv50_wndw *, struct nv50_wndw_atom *, + struct nv50_head_atom *); +void base507c_release(struct nv50_wndw *, struct nv50_wndw_atom *, + struct nv50_head_atom *); +void base507c_sema_set(struct nv50_wndw *, struct nv50_wndw_atom *); +void base507c_sema_clr(struct nv50_wndw *); +void base507c_ntfy_reset(struct nouveau_bo *, u32); +void base507c_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *); +void base507c_ntfy_clr(struct nv50_wndw *); +int base507c_ntfy_wait_begun(struct nouveau_bo *, u32, struct nvif_device *); +void base507c_image_clr(struct nv50_wndw *); +void base507c_lut(struct nv50_wndw *, struct nv50_wndw_atom *); +u32 base507c_update(struct nv50_wndw *, u32); + +int base827c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); + +int base907c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); int nv50_base_new(struct nouveau_drm *, int head, struct nv50_wndw **); #endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/base507c.c b/drivers/gpu/drm/nouveau/dispnv50/base507c.c index b73e7b4d86a56..850c8de670b7b 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base507c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base507c.c @@ -21,7 +21,6 @@ */ #include "base.h" -#include #include #include @@ -29,23 +28,20 @@ #include #include "nouveau_bo.h" -static u32 +u32 base507c_update(struct nv50_wndw *wndw, u32 interlock) { u32 *push; - - if (!(push = evo_wait(&wndw->wndw, 2))) - return 0; - evo_mthd(push, 0x0080, 1); - evo_data(push, interlock); - evo_kick(push, &wndw->wndw); - - if (wndw->wndw.base.user.oclass < GF110_DISP_BASE_CHANNEL_DMA) + if ((push = evo_wait(&wndw->wndw, 2))) { + evo_mthd(push, 0x0080, 1); + evo_data(push, interlock); + evo_kick(push, &wndw->wndw); return interlock ? 2 << (wndw->id * 8) : 0; - return interlock ? 2 << (wndw->id * 4) : 0; + } + return 0; } -static void +void base507c_lut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { u32 *push; @@ -56,7 +52,7 @@ base507c_lut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) } } -static void +void base507c_image_clr(struct nv50_wndw *wndw) { u32 *push; @@ -72,7 +68,6 @@ base507c_image_clr(struct nv50_wndw *wndw) static void base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - const s32 oclass = wndw->wndw.base.user.oclass; u32 *push; if ((push = evo_wait(&wndw->wndw, 10))) { evo_mthd(push, 0x0084, 1); @@ -80,56 +75,33 @@ base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) asyw->image.interval << 4); evo_mthd(push, 0x00c0, 1); evo_data(push, asyw->image.handle); - if (oclass < G82_DISP_BASE_CHANNEL_DMA) { - evo_mthd(push, 0x0800, 5); - evo_data(push, asyw->image.offset >> 8); - evo_data(push, 0x00000000); - evo_data(push, (asyw->image.h << 16) | asyw->image.w); - evo_data(push, (asyw->image.layout << 20) | - asyw->image.pitch | - asyw->image.block); - evo_data(push, (asyw->image.kind << 16) | - (asyw->image.format << 8)); - } else - if (oclass < GF110_DISP_BASE_CHANNEL_DMA) { - evo_mthd(push, 0x0800, 5); - evo_data(push, asyw->image.offset >> 8); - evo_data(push, 0x00000000); - evo_data(push, (asyw->image.h << 16) | asyw->image.w); - evo_data(push, (asyw->image.layout << 20) | - asyw->image.pitch | - asyw->image.block); - evo_data(push, asyw->image.format << 8); - } else { - evo_mthd(push, 0x0400, 5); - evo_data(push, asyw->image.offset >> 8); - evo_data(push, 0x00000000); - evo_data(push, (asyw->image.h << 16) | asyw->image.w); - evo_data(push, (asyw->image.layout << 24) | - asyw->image.pitch | - asyw->image.block); - evo_data(push, asyw->image.format << 8); - } + evo_mthd(push, 0x0800, 5); + evo_data(push, asyw->image.offset >> 8); + evo_data(push, 0x00000000); + evo_data(push, asyw->image.h << 16 | asyw->image.w); + evo_data(push, asyw->image.layout << 20 | + asyw->image.pitch | + asyw->image.block); + evo_data(push, asyw->image.kind << 16 | + asyw->image.format << 8); evo_kick(push, &wndw->wndw); } } -static int -base507c_ntfy_wait_begun(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +int +base507c_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset, + struct nvif_device *device) { - struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev); - struct nv50_disp *disp = nv50_disp(wndw->plane.dev); - if (nvif_msec(&drm->client.device, 2000ULL, - u32 data = nouveau_bo_rd32(disp->sync, asyw->ntfy.offset / 4); + s64 time = nvif_msec(device, 2000ULL, + u32 data = nouveau_bo_rd32(bo, offset / 4); if ((data & 0xc0000000) == 0x40000000) break; usleep_range(1, 2); - ) < 0) - return -ETIMEDOUT; - return 0; + ); + return time < 0 ? time : 0; } -static void +void base507c_ntfy_clr(struct nv50_wndw *wndw) { u32 *push; @@ -140,7 +112,7 @@ base507c_ntfy_clr(struct nv50_wndw *wndw) } } -static void +void base507c_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { u32 *push; @@ -152,7 +124,13 @@ base507c_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) } } -static void +void +base507c_ntfy_reset(struct nouveau_bo *bo, u32 offset) +{ + nouveau_bo_wr32(bo, offset / 4, 0x00000000); +} + +void base507c_sema_clr(struct nv50_wndw *wndw) { u32 *push; @@ -163,7 +141,7 @@ base507c_sema_clr(struct nv50_wndw *wndw) } } -static void +void base507c_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { u32 *push; @@ -177,14 +155,14 @@ base507c_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) } } -static void +void base507c_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, struct nv50_head_atom *asyh) { asyh->base.cpp = 0; } -static int +int base507c_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, struct nv50_head_atom *asyh) { @@ -229,7 +207,7 @@ base507c_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, return 0; } -static const u32 +const u32 base507c_format[] = { DRM_FORMAT_C8, DRM_FORMAT_RGB565, @@ -250,6 +228,7 @@ base507c = { .release = base507c_release, .sema_set = base507c_sema_set, .sema_clr = base507c_sema_clr, + .ntfy_reset = base507c_ntfy_reset, .ntfy_set = base507c_ntfy_set, .ntfy_clr = base507c_ntfy_clr, .ntfy_wait_begun = base507c_ntfy_wait_begun, @@ -259,7 +238,7 @@ base507c = { .update = base507c_update, }; -static int +int base507c_new_(const struct nv50_wndw_func *func, const u32 *format, struct nouveau_drm *drm, int head, s32 oclass, struct nv50_wndw **pwndw) diff --git a/drivers/gpu/drm/nouveau/dispnv50/base827c.c b/drivers/gpu/drm/nouveau/dispnv50/base827c.c new file mode 100644 index 0000000000000..0d356aeeda2b9 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/base827c.c @@ -0,0 +1,67 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "base.h" + +static void +base827c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 10))) { + evo_mthd(push, 0x0084, 1); + evo_data(push, asyw->image.mode << 8 | + asyw->image.interval << 4); + evo_mthd(push, 0x00c0, 1); + evo_data(push, asyw->image.handle); + evo_mthd(push, 0x0800, 5); + evo_data(push, asyw->image.offset >> 8); + evo_data(push, 0x00000000); + evo_data(push, asyw->image.h << 16 | asyw->image.w); + evo_data(push, asyw->image.layout << 20 | + asyw->image.pitch | + asyw->image.block); + evo_data(push, asyw->image.format << 8); + evo_kick(push, &wndw->wndw); + } +} + +static const struct nv50_wndw_func +base827c = { + .acquire = base507c_acquire, + .release = base507c_release, + .sema_set = base507c_sema_set, + .sema_clr = base507c_sema_clr, + .ntfy_reset = base507c_ntfy_reset, + .ntfy_set = base507c_ntfy_set, + .ntfy_clr = base507c_ntfy_clr, + .ntfy_wait_begun = base507c_ntfy_wait_begun, + .image_set = base827c_image_set, + .image_clr = base507c_image_clr, + .lut = base507c_lut, + .update = base507c_update, +}; + +int +base827c_new(struct nouveau_drm *drm, int head, s32 oclass, + struct nv50_wndw **pwndw) +{ + return base507c_new_(&base827c, base507c_format, drm, head, oclass, pwndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/base907c.c b/drivers/gpu/drm/nouveau/dispnv50/base907c.c new file mode 100644 index 0000000000000..171d978729629 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/base907c.c @@ -0,0 +1,80 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "base.h" + +static u32 +base907c_update(struct nv50_wndw *wndw, u32 interlock) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 2))) { + evo_mthd(push, 0x0080, 1); + evo_data(push, interlock); + evo_kick(push, &wndw->wndw); + return interlock ? 2 << (wndw->id * 4) : 0; + } + return 0; +} + +static void +base907c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 10))) { + evo_mthd(push, 0x0084, 1); + evo_data(push, asyw->image.mode << 8 | + asyw->image.interval << 4); + evo_mthd(push, 0x00c0, 1); + evo_data(push, asyw->image.handle); + evo_mthd(push, 0x0400, 5); + evo_data(push, asyw->image.offset >> 8); + evo_data(push, 0x00000000); + evo_data(push, asyw->image.h << 16 | asyw->image.w); + evo_data(push, asyw->image.layout << 24 | + asyw->image.pitch | + asyw->image.block); + evo_data(push, asyw->image.format << 8); + evo_kick(push, &wndw->wndw); + } +} + +static const struct nv50_wndw_func +base907c = { + .acquire = base507c_acquire, + .release = base507c_release, + .sema_set = base507c_sema_set, + .sema_clr = base507c_sema_clr, + .ntfy_reset = base507c_ntfy_reset, + .ntfy_set = base507c_ntfy_set, + .ntfy_clr = base507c_ntfy_clr, + .ntfy_wait_begun = base507c_ntfy_wait_begun, + .image_set = base907c_image_set, + .image_clr = base507c_image_clr, + .lut = base507c_lut, + .update = base907c_update, +}; + +int +base907c_new(struct nouveau_drm *drm, int head, s32 oclass, + struct nv50_wndw **pwndw) +{ + return base507c_new_(&base907c, base507c_format, drm, head, oclass, pwndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 6136beeba3fcf..c2b1578ed5529 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1812,7 +1812,6 @@ nv50_disp_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state, bool nonblock) { struct nouveau_drm *drm = nouveau_drm(dev); - struct nv50_disp *disp = nv50_disp(dev); struct drm_plane_state *new_plane_state; struct drm_plane *plane; struct drm_crtc *crtc; @@ -1847,14 +1846,8 @@ nv50_disp_atomic_commit(struct drm_device *dev, struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state); struct nv50_wndw *wndw = nv50_wndw(plane); - if (asyw->set.image) { - asyw->ntfy.handle = wndw->wndw.sync.handle; - asyw->ntfy.offset = wndw->ntfy; - asyw->ntfy.awaken = false; - asyw->set.ntfy = true; - nouveau_bo_wr32(disp->sync, wndw->ntfy / 4, 0x00000000); - wndw->ntfy ^= 0x10; - } + if (asyw->set.image) + nv50_wndw_ntfy_enable(wndw, asyw); } drm_atomic_state_get(state); diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index 71a4c50af8ecb..a1e53c74c8a82 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -98,8 +98,12 @@ nv50_wndw_ctxdma_new(struct nv50_wndw *wndw, struct nouveau_framebuffer *fb) int nv50_wndw_wait_armed(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - if (asyw->set.ntfy) - return wndw->func->ntfy_wait_begun(wndw, asyw); + struct nv50_disp *disp = nv50_disp(wndw->plane.dev); + if (asyw->set.ntfy) { + return wndw->func->ntfy_wait_begun(disp->sync, + asyw->ntfy.offset, + wndw->wndw.base.device); + } return 0; } @@ -138,6 +142,20 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 interlock, return wndw->func->update ? wndw->func->update(wndw, interlock) : 0; } +void +nv50_wndw_ntfy_enable(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + struct nv50_disp *disp = nv50_disp(wndw->plane.dev); + + asyw->ntfy.handle = wndw->wndw.sync.handle; + asyw->ntfy.offset = wndw->ntfy; + asyw->ntfy.awaken = false; + asyw->set.ntfy = true; + + wndw->func->ntfy_reset(disp->sync, wndw->ntfy); + wndw->ntfy ^= 0x10; +} + static void nv50_wndw_atomic_check_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.h b/drivers/gpu/drm/nouveau/dispnv50/wndw.h index 1931e30681152..70259732d9380 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.h +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.h @@ -41,6 +41,7 @@ u32 nv50_wndw_flush_set(struct nv50_wndw *, u32 interlock, struct nv50_wndw_atom *); u32 nv50_wndw_flush_clr(struct nv50_wndw *, u32 interlock, bool flush, struct nv50_wndw_atom *); +void nv50_wndw_ntfy_enable(struct nv50_wndw *, struct nv50_wndw_atom *); int nv50_wndw_wait_armed(struct nv50_wndw *, struct nv50_wndw_atom *); struct nv50_wndw_func { @@ -53,9 +54,11 @@ struct nv50_wndw_func { void (*sema_set)(struct nv50_wndw *, struct nv50_wndw_atom *); void (*sema_clr)(struct nv50_wndw *); + void (*ntfy_reset)(struct nouveau_bo *, u32 offset); void (*ntfy_set)(struct nv50_wndw *, struct nv50_wndw_atom *); void (*ntfy_clr)(struct nv50_wndw *); - int (*ntfy_wait_begun)(struct nv50_wndw *, struct nv50_wndw_atom *); + int (*ntfy_wait_begun)(struct nouveau_bo *, u32 offset, + struct nvif_device *); void (*image_set)(struct nv50_wndw *, struct nv50_wndw_atom *); void (*image_clr)(struct nv50_wndw *); void (*lut)(struct nv50_wndw *, struct nv50_wndw_atom *); From 9d6c2fe1917fc5ba6a9e8586ca16d007410baf42 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 118/165] drm/nouveau/kms/nv50-: allow specification of valid heads for a window This will be required to support Volta, where window ID != head. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/base507c.c | 2 +- drivers/gpu/drm/nouveau/dispnv50/curs507a.c | 2 +- drivers/gpu/drm/nouveau/dispnv50/ovly507e.c | 2 +- drivers/gpu/drm/nouveau/dispnv50/wndw.c | 4 ++-- drivers/gpu/drm/nouveau/dispnv50/wndw.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/base507c.c b/drivers/gpu/drm/nouveau/dispnv50/base507c.c index 850c8de670b7b..548a6a67f874b 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base507c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base507c.c @@ -251,7 +251,7 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format, int ret; ret = nv50_wndw_new_(func, drm->dev, DRM_PLANE_TYPE_PRIMARY, - "base", head, format, &wndw); + "base", head, format, BIT(head), &wndw); if (*pwndw = wndw, ret) return ret; diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c index 1a3e199b5b450..3e5e98c835a3c 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c +++ b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c @@ -126,7 +126,7 @@ curs507a_new_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, int ret; ret = nv50_wndw_new_(&curs507a_wndw, drm->dev, DRM_PLANE_TYPE_CURSOR, - "curs", head, curs507a_format, &wndw); + "curs", head, curs507a_format, BIT(head), &wndw); if (*pwndw = wndw, ret) return ret; diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c b/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c index ceec5127a17dc..1b85262bf23bb 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c @@ -47,7 +47,7 @@ ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format, int ret; ret = nv50_wndw_new_(func, drm->dev, DRM_PLANE_TYPE_OVERLAY, - "ovly", head, format, &wndw); + "ovly", head, format, BIT(head), &wndw); if (*pwndw = wndw, ret) return ret; diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index a1e53c74c8a82..764db736cf293 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -420,7 +420,7 @@ nv50_wndw_init(struct nv50_wndw *wndw) int nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, enum drm_plane_type type, const char *name, int index, - const u32 *format, struct nv50_wndw **pwndw) + const u32 *format, u32 heads, struct nv50_wndw **pwndw) { struct nv50_wndw *wndw; int nformat; @@ -436,7 +436,7 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, for (nformat = 0; format[nformat]; nformat++); - ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw, + ret = drm_universal_plane_init(dev, &wndw->plane, heads, &nv50_wndw, format, nformat, NULL, type, "%s-%d", name, index); if (ret) { diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.h b/drivers/gpu/drm/nouveau/dispnv50/wndw.h index 70259732d9380..8672c280a6a42 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.h +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.h @@ -34,7 +34,7 @@ struct nv50_wndw { int nv50_wndw_new_(const struct nv50_wndw_func *, struct drm_device *, enum drm_plane_type, const char *name, int index, - const u32 *format, struct nv50_wndw **); + const u32 *format, u32 heads, struct nv50_wndw **); void nv50_wndw_init(struct nv50_wndw *); void nv50_wndw_fini(struct nv50_wndw *); u32 nv50_wndw_flush_set(struct nv50_wndw *, u32 interlock, From f88bc9d3ecca5ddc29642269f4624d07265c1bf5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 119/165] drm/nouveau/kms/nv50-: unify set/clr masks This is a simplification that'll be used to improve interlock handling. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/atom.h | 26 ++++--------------------- drivers/gpu/drm/nouveau/dispnv50/disp.c | 11 ++--------- drivers/gpu/drm/nouveau/dispnv50/head.c | 15 +++++++------- drivers/gpu/drm/nouveau/dispnv50/wndw.c | 12 ++++++------ 4 files changed, 20 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/atom.h b/drivers/gpu/drm/nouveau/dispnv50/atom.h index 8c97e25c881f0..8bf180666bb7a 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/atom.h +++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h @@ -105,16 +105,7 @@ struct nv50_head_atom { u8 depth:4; } or; - union { - struct { - bool ilut:1; - bool core:1; - bool curs:1; - }; - u8 mask; - } clr; - - union { + union nv50_head_atom_mask { struct { bool ilut:1; bool core:1; @@ -128,7 +119,7 @@ struct nv50_head_atom { bool or:1; }; u16 mask; - } set; + } set, clr; }; static inline struct nv50_head_atom * @@ -184,16 +175,7 @@ struct nv50_wndw_atom { u16 y; } point; - union { - struct { - bool ntfy:1; - bool sema:1; - bool image:1; - }; - u8 mask; - } clr; - - union { + union nv50_wndw_atom_mask { struct { bool ntfy:1; bool sema:1; @@ -202,6 +184,6 @@ struct nv50_wndw_atom { bool point:1; }; u8 mask; - } set; + } set, clr; }; #endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index c2b1578ed5529..006562f7f23e7 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -62,19 +62,12 @@ struct nv50_outp_atom { struct drm_encoder *encoder; bool flush_disable; - union { + union nv50_outp_atom_mask { struct { bool ctrl:1; }; u8 mask; - } clr; - - union { - struct { - bool ctrl:1; - }; - u8 mask; - } set; + } set, clr; }; /****************************************************************************** diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c index 1335c00500d16..2eb7fdb611310 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head.c @@ -81,14 +81,15 @@ nv50_head_lut_load(struct drm_property_blob *blob, int mode, } void -nv50_head_flush_clr(struct nv50_head *head, struct nv50_head_atom *asyh, bool y) +nv50_head_flush_clr(struct nv50_head *head, + struct nv50_head_atom *asyh, bool flush) { - if (asyh->clr.ilut && (!asyh->set.ilut || y)) - head->func->ilut_clr(head); - if (asyh->clr.core && (!asyh->set.core || y)) - head->func->core_clr(head); - if (asyh->clr.curs && (!asyh->set.curs || y)) - head->func->curs_clr(head); + union nv50_head_atom_mask clr = { + .mask = asyh->clr.mask & ~(flush ? 0 : asyh->set.mask), + }; + if (clr.ilut) head->func->ilut_clr(head); + if (clr.core) head->func->core_clr(head); + if (clr.curs) head->func->curs_clr(head); } void diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index 764db736cf293..8a7636f8a2421 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -111,12 +111,12 @@ u32 nv50_wndw_flush_clr(struct nv50_wndw *wndw, u32 interlock, bool flush, struct nv50_wndw_atom *asyw) { - if (asyw->clr.sema && (!asyw->set.sema || flush)) - wndw->func->sema_clr(wndw); - if (asyw->clr.ntfy && (!asyw->set.ntfy || flush)) - wndw->func->ntfy_clr(wndw); - if (asyw->clr.image && (!asyw->set.image || flush)) - wndw->func->image_clr(wndw); + union nv50_wndw_atom_mask clr = { + .mask = asyw->clr.mask & ~(flush ? 0 : asyw->set.mask), + }; + if (clr.sema ) wndw->func-> sema_clr(wndw); + if (clr.ntfy ) wndw->func-> ntfy_clr(wndw); + if (clr.image) wndw->func->image_clr(wndw); return flush ? wndw->func->update(wndw, interlock) : 0; } From 43c181e9deb5f4215d4ef0cb227fde509da7cc5e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 120/165] drm/nouveau/kms/nv50-: move drm format->hw conversion into common code This will be required to support additional HW features. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/base507c.c | 16 ------------- drivers/gpu/drm/nouveau/dispnv50/curs507a.c | 4 ++-- drivers/gpu/drm/nouveau/dispnv50/wndw.c | 25 +++++++++++++++++++++ 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/base507c.c b/drivers/gpu/drm/nouveau/dispnv50/base507c.c index 548a6a67f874b..43dcbcd49e719 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base507c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base507c.c @@ -186,22 +186,6 @@ base507c_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, asyh->base.w = asyw->state.fb->width; asyh->base.h = asyw->state.fb->height; - switch (fb->format->format) { - case DRM_FORMAT_C8 : asyw->image.format = 0x1e; break; - case DRM_FORMAT_RGB565 : asyw->image.format = 0xe8; break; - case DRM_FORMAT_XRGB1555 : - case DRM_FORMAT_ARGB1555 : asyw->image.format = 0xe9; break; - case DRM_FORMAT_XRGB8888 : - case DRM_FORMAT_ARGB8888 : asyw->image.format = 0xcf; break; - case DRM_FORMAT_XBGR2101010: - case DRM_FORMAT_ABGR2101010: asyw->image.format = 0xd1; break; - case DRM_FORMAT_XBGR8888 : - case DRM_FORMAT_ABGR8888 : asyw->image.format = 0xd5; break; - default: - WARN_ON(1); - return -EINVAL; - } - asyw->lut.enable = 1; asyw->set.image = true; return 0; diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c index 3e5e98c835a3c..f7e56a88e77d5 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c +++ b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c @@ -91,8 +91,8 @@ curs507a_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, if (asyw->state.fb->width != asyw->state.fb->height) return -EINVAL; - switch (asyw->state.fb->format->format) { - case DRM_FORMAT_ARGB8888: asyh->curs.format = 1; break; + switch (asyw->image.format) { + case 0xcf: asyh->curs.format = 1; break; default: WARN_ON(1); return -EINVAL; diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index 8a7636f8a2421..cfd998a854185 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -168,6 +168,27 @@ nv50_wndw_atomic_check_release(struct nv50_wndw *wndw, asyw->sema.handle = 0; } +static int +nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw) +{ + switch (asyw->state.fb->format->format) { + case DRM_FORMAT_C8 : asyw->image.format = 0x1e; break; + case DRM_FORMAT_XRGB8888 : + case DRM_FORMAT_ARGB8888 : asyw->image.format = 0xcf; break; + case DRM_FORMAT_RGB565 : asyw->image.format = 0xe8; break; + case DRM_FORMAT_XRGB1555 : + case DRM_FORMAT_ARGB1555 : asyw->image.format = 0xe9; break; + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_ABGR2101010: asyw->image.format = 0xd1; break; + case DRM_FORMAT_XBGR8888 : + case DRM_FORMAT_ABGR8888 : asyw->image.format = 0xd5; break; + default: + WARN_ON(1); + return -EINVAL; + } + return 0; +} + static int nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, @@ -183,6 +204,10 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, asyw->image.h = fb->base.height; asyw->image.kind = fb->nvbo->kind; + ret = nv50_wndw_atomic_check_acquire_rgb(asyw); + if (ret) + return ret; + if (asyh->state.pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC) asyw->interval = 0; else From 261fcfa96991d6652b061262c1879cc0bdd1aa3a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 121/165] drm/nouveau/kms/nv50-: extend window image data for stereo/planar formats Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/atom.h | 6 +++--- drivers/gpu/drm/nouveau/dispnv50/base507c.c | 6 +++--- drivers/gpu/drm/nouveau/dispnv50/base827c.c | 6 +++--- drivers/gpu/drm/nouveau/dispnv50/base907c.c | 6 +++--- drivers/gpu/drm/nouveau/dispnv50/curs507a.c | 2 +- drivers/gpu/drm/nouveau/dispnv50/wndw.c | 10 +++++----- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/atom.h b/drivers/gpu/drm/nouveau/dispnv50/atom.h index 8bf180666bb7a..53638ee833615 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/atom.h +++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h @@ -162,12 +162,12 @@ struct nv50_wndw_atom { u8 kind:7; u8 layout:1; u8 block:4; - u32 pitch:20; + u32 pitch[3]; u16 w; u16 h; - u32 handle; - u64 offset; + u32 handle[6]; + u64 offset[6]; } image; struct { diff --git a/drivers/gpu/drm/nouveau/dispnv50/base507c.c b/drivers/gpu/drm/nouveau/dispnv50/base507c.c index 43dcbcd49e719..1c65ddc4747e0 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base507c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base507c.c @@ -74,13 +74,13 @@ base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) evo_data(push, asyw->image.mode << 8 | asyw->image.interval << 4); evo_mthd(push, 0x00c0, 1); - evo_data(push, asyw->image.handle); + evo_data(push, asyw->image.handle[0]); evo_mthd(push, 0x0800, 5); - evo_data(push, asyw->image.offset >> 8); + evo_data(push, asyw->image.offset[0] >> 8); evo_data(push, 0x00000000); evo_data(push, asyw->image.h << 16 | asyw->image.w); evo_data(push, asyw->image.layout << 20 | - asyw->image.pitch | + asyw->image.pitch[0] | asyw->image.block); evo_data(push, asyw->image.kind << 16 | asyw->image.format << 8); diff --git a/drivers/gpu/drm/nouveau/dispnv50/base827c.c b/drivers/gpu/drm/nouveau/dispnv50/base827c.c index 0d356aeeda2b9..9dc968c83c667 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base827c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base827c.c @@ -30,13 +30,13 @@ base827c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) evo_data(push, asyw->image.mode << 8 | asyw->image.interval << 4); evo_mthd(push, 0x00c0, 1); - evo_data(push, asyw->image.handle); + evo_data(push, asyw->image.handle[0]); evo_mthd(push, 0x0800, 5); - evo_data(push, asyw->image.offset >> 8); + evo_data(push, asyw->image.offset[0] >> 8); evo_data(push, 0x00000000); evo_data(push, asyw->image.h << 16 | asyw->image.w); evo_data(push, asyw->image.layout << 20 | - asyw->image.pitch | + asyw->image.pitch[0] | asyw->image.block); evo_data(push, asyw->image.format << 8); evo_kick(push, &wndw->wndw); diff --git a/drivers/gpu/drm/nouveau/dispnv50/base907c.c b/drivers/gpu/drm/nouveau/dispnv50/base907c.c index 171d978729629..5321c55951b91 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base907c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base907c.c @@ -43,13 +43,13 @@ base907c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) evo_data(push, asyw->image.mode << 8 | asyw->image.interval << 4); evo_mthd(push, 0x00c0, 1); - evo_data(push, asyw->image.handle); + evo_data(push, asyw->image.handle[0]); evo_mthd(push, 0x0400, 5); - evo_data(push, asyw->image.offset >> 8); + evo_data(push, asyw->image.offset[0] >> 8); evo_data(push, 0x00000000); evo_data(push, asyw->image.h << 16 | asyw->image.w); evo_data(push, asyw->image.layout << 24 | - asyw->image.pitch | + asyw->image.pitch[0] | asyw->image.block); evo_data(push, asyw->image.format << 8); evo_kick(push, &wndw->wndw); diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c index f7e56a88e77d5..589c75c22b3a2 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c +++ b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c @@ -52,7 +52,7 @@ curs507a_prepare(struct nv50_wndw *wndw, struct nv50_head_atom *asyh, struct nv50_wndw_atom *asyw) { u32 handle = nv50_disp(wndw->plane.dev)->core->chan.vram.handle; - u32 offset = asyw->image.offset; + u32 offset = asyw->image.offset[0]; if (asyh->curs.handle != handle || asyh->curs.offset != offset) { asyh->curs.handle = handle; asyh->curs.offset = offset; diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index cfd998a854185..4b64f64b78910 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -219,11 +219,11 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, asyw->image.block = fb->nvbo->mode >> 4; else asyw->image.block = fb->nvbo->mode; - asyw->image.pitch = (fb->base.pitches[0] / 4) << 4; + asyw->image.pitch[0] = (fb->base.pitches[0] / 4) << 4; } else { asyw->image.layout = 1; asyw->image.block = 0; - asyw->image.pitch = fb->base.pitches[0]; + asyw->image.pitch[0] = fb->base.pitches[0]; } ret = wndw->func->acquire(wndw, asyw, asyh); @@ -287,7 +287,7 @@ nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) asyw->clr.ntfy = armw->ntfy.handle != 0; asyw->clr.sema = armw->sema.handle != 0; if (wndw->func->image_clr) - asyw->clr.image = armw->image.handle != 0; + asyw->clr.image = armw->image.handle[0] != 0; asyw->set.lut = wndw->func->lut && asyv; } @@ -333,8 +333,8 @@ nv50_wndw_prepare_fb(struct drm_plane *plane, struct drm_plane_state *state) } asyw->state.fence = reservation_object_get_excl_rcu(fb->nvbo->bo.resv); - asyw->image.handle = ctxdma->object.handle; - asyw->image.offset = fb->nvbo->bo.offset; + asyw->image.handle[0] = ctxdma->object.handle; + asyw->image.offset[0] = fb->nvbo->bo.offset; if (wndw->func->prepare) { asyh = nv50_head_atom_get(asyw->state.state, asyw->state.crtc); From 34508f9d260cbd7b91f988c858f50ad956750ee3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 122/165] drm/nouveau/kms/nv50-: determine MST support from DP Info Table GV100 doesn't support MST, use the information provided in VBIOS tables to detect its presence instead. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 9 +++++++-- drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dp.h | 4 ++++ drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 006562f7f23e7..eaa63b43282bf 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -52,6 +52,8 @@ #include "nouveau_fence.h" #include "nouveau_fbcon.h" +#include + /****************************************************************************** * Atomic state *****************************************************************************/ @@ -1383,9 +1385,12 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe) { struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_drm *drm = nouveau_drm(connector->dev); + struct nvkm_bios *bios = nvxx_bios(&drm->client.device); struct nvkm_i2c *i2c = nvxx_i2c(&drm->client.device); struct nouveau_encoder *nv_encoder; struct drm_encoder *encoder; + u8 ver, hdr, cnt, len; + u32 data; int type, ret; switch (dcbe->type) { @@ -1429,8 +1434,8 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe) nv_encoder->aux = aux; } - /*TODO: Use DP Info Table to check for support. */ - if (disp->disp->object.oclass >= GF110_DISP) { + if ((data = nvbios_dp_table(bios, &ver, &hdr, &cnt, &len)) && + ver >= 0x40 && (nvbios_rd08(bios, data + 0x08) & 0x04)) { ret = nv50_mstm_new(nv_encoder, &nv_connector->aux, 16, nv_connector->base.base.id, &nv_encoder->dp.mstm); diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dp.h index df34b41838d60..512e25a41803b 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dp.h @@ -1,6 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0 */ #ifndef __NVBIOS_DP_H__ #define __NVBIOS_DP_H__ + +u16 +nvbios_dp_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); + struct nvbios_dpout { u16 type; u16 mask; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c index 7c7efa4ea0d0e..3133b28f849c7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c @@ -25,7 +25,7 @@ #include #include -static u16 +u16 nvbios_dp_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) { struct bit_entry d; From 53e0a3e70de69dc9f498d26c6b5495b2771ee374 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 123/165] drm/nouveau/kms/nv50-: simplify tracking of channel interlocks Instead of windows returning their core channel interlock mask if they know core has been modified, it's recorded unconditionally and used if required when update methods are emitted. This will be required to support Volta. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/Kbuild | 3 ++ drivers/gpu/drm/nouveau/dispnv50/base.h | 4 +- drivers/gpu/drm/nouveau/dispnv50/base507c.c | 16 ++++---- drivers/gpu/drm/nouveau/dispnv50/base827c.c | 3 +- drivers/gpu/drm/nouveau/dispnv50/base907c.c | 18 ++------- drivers/gpu/drm/nouveau/dispnv50/core.h | 5 ++- drivers/gpu/drm/nouveau/dispnv50/core507d.c | 5 ++- drivers/gpu/drm/nouveau/dispnv50/curs.c | 4 +- drivers/gpu/drm/nouveau/dispnv50/curs.h | 6 +++ drivers/gpu/drm/nouveau/dispnv50/curs507a.c | 18 +++++---- drivers/gpu/drm/nouveau/dispnv50/curs907a.c | 30 ++++++++++++++ drivers/gpu/drm/nouveau/dispnv50/disp.c | 42 +++++++++----------- drivers/gpu/drm/nouveau/dispnv50/disp.h | 11 ++++++ drivers/gpu/drm/nouveau/dispnv50/ovly.c | 10 ++--- drivers/gpu/drm/nouveau/dispnv50/ovly.h | 8 ++++ drivers/gpu/drm/nouveau/dispnv50/ovly507e.c | 11 ++++-- drivers/gpu/drm/nouveau/dispnv50/ovly827e.c | 43 +++++++++++++++++++++ drivers/gpu/drm/nouveau/dispnv50/ovly907e.c | 34 ++++++++++++++++ drivers/gpu/drm/nouveau/dispnv50/wndw.c | 23 +++++++---- drivers/gpu/drm/nouveau/dispnv50/wndw.h | 16 ++++---- 20 files changed, 224 insertions(+), 86 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/dispnv50/curs907a.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/ovly827e.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/ovly907e.c diff --git a/drivers/gpu/drm/nouveau/dispnv50/Kbuild b/drivers/gpu/drm/nouveau/dispnv50/Kbuild index 674221dea7a11..3e53484b4589d 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/Kbuild +++ b/drivers/gpu/drm/nouveau/dispnv50/Kbuild @@ -29,9 +29,12 @@ nouveau-y += dispnv50/base907c.o nouveau-y += dispnv50/curs.o nouveau-y += dispnv50/curs507a.o +nouveau-y += dispnv50/curs907a.o nouveau-y += dispnv50/oimm.o nouveau-y += dispnv50/oimm507b.o nouveau-y += dispnv50/ovly.o nouveau-y += dispnv50/ovly507e.o +nouveau-y += dispnv50/ovly827e.o +nouveau-y += dispnv50/ovly907e.o diff --git a/drivers/gpu/drm/nouveau/dispnv50/base.h b/drivers/gpu/drm/nouveau/dispnv50/base.h index edf96a8d645f2..71fc10369b373 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base.h +++ b/drivers/gpu/drm/nouveau/dispnv50/base.h @@ -5,7 +5,7 @@ int base507c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); int base507c_new_(const struct nv50_wndw_func *, const u32 *format, struct nouveau_drm *, int head, s32 oclass, - struct nv50_wndw **); + u32 interlock_data, struct nv50_wndw **); extern const u32 base507c_format[]; int base507c_acquire(struct nv50_wndw *, struct nv50_wndw_atom *, struct nv50_head_atom *); @@ -19,7 +19,7 @@ void base507c_ntfy_clr(struct nv50_wndw *); int base507c_ntfy_wait_begun(struct nouveau_bo *, u32, struct nvif_device *); void base507c_image_clr(struct nv50_wndw *); void base507c_lut(struct nv50_wndw *, struct nv50_wndw_atom *); -u32 base507c_update(struct nv50_wndw *, u32); +void base507c_update(struct nv50_wndw *, u32 *); int base827c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); diff --git a/drivers/gpu/drm/nouveau/dispnv50/base507c.c b/drivers/gpu/drm/nouveau/dispnv50/base507c.c index 1c65ddc4747e0..819403f4b958d 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base507c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base507c.c @@ -28,17 +28,15 @@ #include #include "nouveau_bo.h" -u32 -base507c_update(struct nv50_wndw *wndw, u32 interlock) +void +base507c_update(struct nv50_wndw *wndw, u32 *interlock) { u32 *push; if ((push = evo_wait(&wndw->wndw, 2))) { evo_mthd(push, 0x0080, 1); - evo_data(push, interlock); + evo_data(push, interlock[NV50_DISP_INTERLOCK_CORE]); evo_kick(push, &wndw->wndw); - return interlock ? 2 << (wndw->id * 8) : 0; } - return 0; } void @@ -224,7 +222,7 @@ base507c = { int base507c_new_(const struct nv50_wndw_func *func, const u32 *format, - struct nouveau_drm *drm, int head, s32 oclass, + struct nouveau_drm *drm, int head, s32 oclass, u32 interlock_data, struct nv50_wndw **pwndw) { struct nv50_disp_base_channel_dma_v0 args = { @@ -235,7 +233,8 @@ base507c_new_(const struct nv50_wndw_func *func, const u32 *format, int ret; ret = nv50_wndw_new_(func, drm->dev, DRM_PLANE_TYPE_PRIMARY, - "base", head, format, BIT(head), &wndw); + "base", head, format, BIT(head), + NV50_DISP_INTERLOCK_BASE, interlock_data, &wndw); if (*pwndw = wndw, ret) return ret; @@ -266,5 +265,6 @@ int base507c_new(struct nouveau_drm *drm, int head, s32 oclass, struct nv50_wndw **pwndw) { - return base507c_new_(&base507c, base507c_format, drm, head, oclass, pwndw); + return base507c_new_(&base507c, base507c_format, drm, head, oclass, + 0x00000002 << (head * 8), pwndw); } diff --git a/drivers/gpu/drm/nouveau/dispnv50/base827c.c b/drivers/gpu/drm/nouveau/dispnv50/base827c.c index 9dc968c83c667..240a6409329d2 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base827c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base827c.c @@ -63,5 +63,6 @@ int base827c_new(struct nouveau_drm *drm, int head, s32 oclass, struct nv50_wndw **pwndw) { - return base507c_new_(&base827c, base507c_format, drm, head, oclass, pwndw); + return base507c_new_(&base827c, base507c_format, drm, head, oclass, + 0x00000002 << (head * 8), pwndw); } diff --git a/drivers/gpu/drm/nouveau/dispnv50/base907c.c b/drivers/gpu/drm/nouveau/dispnv50/base907c.c index 5321c55951b91..6c32a4e5cb7d9 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base907c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base907c.c @@ -21,19 +21,6 @@ */ #include "base.h" -static u32 -base907c_update(struct nv50_wndw *wndw, u32 interlock) -{ - u32 *push; - if ((push = evo_wait(&wndw->wndw, 2))) { - evo_mthd(push, 0x0080, 1); - evo_data(push, interlock); - evo_kick(push, &wndw->wndw); - return interlock ? 2 << (wndw->id * 4) : 0; - } - return 0; -} - static void base907c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { @@ -69,12 +56,13 @@ base907c = { .image_set = base907c_image_set, .image_clr = base507c_image_clr, .lut = base507c_lut, - .update = base907c_update, + .update = base507c_update, }; int base907c_new(struct nouveau_drm *drm, int head, s32 oclass, struct nv50_wndw **pwndw) { - return base507c_new_(&base907c, base507c_format, drm, head, oclass, pwndw); + return base507c_new_(&base907c, base507c_format, drm, head, oclass, + 0x00000002 << (head * 4), pwndw); } diff --git a/drivers/gpu/drm/nouveau/dispnv50/core.h b/drivers/gpu/drm/nouveau/dispnv50/core.h index 5fd7ddd31e5e4..c490d7d497b2e 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core.h +++ b/drivers/gpu/drm/nouveau/dispnv50/core.h @@ -16,7 +16,7 @@ struct nv50_core_func { void (*ntfy_init)(struct nouveau_bo *, u32 offset); int (*ntfy_wait_done)(struct nouveau_bo *, u32 offset, struct nvif_device *); - void (*update)(struct nv50_core *, u32 interlock, bool ntfy); + void (*update)(struct nv50_core *, u32 *interlock, bool ntfy); const struct nv50_head_func *head; const struct nv50_outp_func { @@ -31,7 +31,8 @@ int core507d_new_(const struct nv50_core_func *, struct nouveau_drm *, s32, void core507d_init(struct nv50_core *); void core507d_ntfy_init(struct nouveau_bo *, u32); int core507d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *); -void core507d_update(struct nv50_core *, u32, bool); +void core507d_update(struct nv50_core *, u32 *, bool); + extern const struct nv50_outp_func dac507d; extern const struct nv50_outp_func sor507d; extern const struct nv50_outp_func pior507d; diff --git a/drivers/gpu/drm/nouveau/dispnv50/core507d.c b/drivers/gpu/drm/nouveau/dispnv50/core507d.c index 96d7d8fde669c..e7fcfa6e64676 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/core507d.c @@ -27,7 +27,7 @@ #include "nouveau_bo.h" void -core507d_update(struct nv50_core *core, u32 interlock, bool ntfy) +core507d_update(struct nv50_core *core, u32 *interlock, bool ntfy) { u32 *push; if ((push = evo_wait(&core->chan, 5))) { @@ -36,7 +36,8 @@ core507d_update(struct nv50_core *core, u32 interlock, bool ntfy) evo_data(push, 0x80000000 | NV50_DISP_CORE_NTFY); } evo_mthd(push, 0x0080, 2); - evo_data(push, interlock); + evo_data(push, interlock[NV50_DISP_INTERLOCK_BASE] | + interlock[NV50_DISP_INTERLOCK_OVLY]); evo_data(push, 0x00000000); evo_kick(push, &core->chan); } diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs.c b/drivers/gpu/drm/nouveau/dispnv50/curs.c index 6d60e978db69d..fb842ed2592f1 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/curs.c +++ b/drivers/gpu/drm/nouveau/dispnv50/curs.c @@ -31,8 +31,8 @@ nv50_curs_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) int version; int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); } curses[] = { - { GK104_DISP_CURSOR, 0, curs507a_new }, - { GF110_DISP_CURSOR, 0, curs507a_new }, + { GK104_DISP_CURSOR, 0, curs907a_new }, + { GF110_DISP_CURSOR, 0, curs907a_new }, { GT214_DISP_CURSOR, 0, curs507a_new }, { G82_DISP_CURSOR, 0, curs507a_new }, { NV50_DISP_CURSOR, 0, curs507a_new }, diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs.h b/drivers/gpu/drm/nouveau/dispnv50/curs.h index b85ca9fa419c7..2285247dc2a3a 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/curs.h +++ b/drivers/gpu/drm/nouveau/dispnv50/curs.h @@ -3,6 +3,12 @@ #include "wndw.h" int curs507a_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); +int curs507a_new_(const struct nv50_wimm_func *, struct nouveau_drm *, + int head, s32 oclass, u32 interlock_data, + struct nv50_wndw **); +extern const struct nv50_wimm_func curs507a; + +int curs907a_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); int nv50_curs_new(struct nouveau_drm *, int head, struct nv50_wndw **); #endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c index 589c75c22b3a2..ba05bcb13ae79 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c +++ b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c @@ -27,11 +27,10 @@ #include #include -static u32 -curs507a_update(struct nv50_wndw *wndw, u32 interlock) +static void +curs507a_update(struct nv50_wndw *wndw, u32 *interlock) { nvif_wr32(&wndw->wimm.base.user, 0x0080, 0x00000000); - return 0; } static void @@ -41,7 +40,7 @@ curs507a_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) asyw->point.x); } -static const struct nv50_wimm_func +const struct nv50_wimm_func curs507a = { .point = curs507a_point, .update = curs507a_update, @@ -114,9 +113,10 @@ curs507a_wndw = { .prepare = curs507a_prepare, }; -static int +int curs507a_new_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, - int head, s32 oclass, struct nv50_wndw **pwndw) + int head, s32 oclass, u32 interlock_data, + struct nv50_wndw **pwndw) { struct nv50_disp_cursor_v0 args = { .head = head, @@ -126,7 +126,8 @@ curs507a_new_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, int ret; ret = nv50_wndw_new_(&curs507a_wndw, drm->dev, DRM_PLANE_TYPE_CURSOR, - "curs", head, curs507a_format, BIT(head), &wndw); + "curs", head, curs507a_format, BIT(head), + NV50_DISP_INTERLOCK_CURS, interlock_data, &wndw); if (*pwndw = wndw, ret) return ret; @@ -147,5 +148,6 @@ int curs507a_new(struct nouveau_drm *drm, int head, s32 oclass, struct nv50_wndw **pwndw) { - return curs507a_new_(&curs507a, drm, head, oclass, pwndw); + return curs507a_new_(&curs507a, drm, head, oclass, + 0x00000001 << (head * 8), pwndw); } diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs907a.c b/drivers/gpu/drm/nouveau/dispnv50/curs907a.c new file mode 100644 index 0000000000000..d742362de03e0 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/curs907a.c @@ -0,0 +1,30 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "curs.h" + +int +curs907a_new(struct nouveau_drm *drm, int head, s32 oclass, + struct nv50_wndw **pwndw) +{ + return curs507a_new_(&curs507a, drm, head, oclass, + 0x00000001 << (head * 4), pwndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index eaa63b43282bf..e80d11c9a456e 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1582,14 +1582,14 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe) *****************************************************************************/ static void -nv50_disp_atomic_commit_core(struct nouveau_drm *drm, u32 interlock) +nv50_disp_atomic_commit_core(struct nouveau_drm *drm, u32 *interlock) { struct nv50_disp *disp = nv50_disp(drm->dev); struct nv50_core *core = disp->core; struct nv50_mstm *mstm; struct drm_encoder *encoder; - NV_ATOMIC(drm, "commit core %08x\n", interlock); + NV_ATOMIC(drm, "commit core %08x\n", interlock[NV50_DISP_INTERLOCK_BASE]); drm_for_each_encoder(encoder, drm->dev) { if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) { @@ -1626,8 +1626,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) struct nv50_disp *disp = nv50_disp(dev); struct nv50_atom *atom = nv50_atom(state); struct nv50_outp_atom *outp, *outt; - u32 interlock_core = 0; - u32 interlock_chan = 0; + u32 interlock[NV50_DISP_INTERLOCK__SIZE] = {}; int i; NV_ATOMIC(drm, "commit %d %d\n", atom->lock_core, atom->flush_disable); @@ -1650,7 +1649,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) if (asyh->clr.mask) { nv50_head_flush_clr(head, asyh, atom->flush_disable); - interlock_core |= 1; + interlock[NV50_DISP_INTERLOCK_CORE] |= 1; } } @@ -1664,9 +1663,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) if (!asyw->clr.mask) continue; - interlock_chan |= nv50_wndw_flush_clr(wndw, interlock_core, - atom->flush_disable, - asyw); + nv50_wndw_flush_clr(wndw, interlock, atom->flush_disable, asyw); } /* Disable output path(s). */ @@ -1682,21 +1679,19 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) if (outp->clr.mask) { help->disable(encoder); - interlock_core |= 1; + interlock[NV50_DISP_INTERLOCK_CORE] |= 1; if (outp->flush_disable) { - nv50_disp_atomic_commit_core(drm, interlock_chan); - interlock_core = 0; - interlock_chan = 0; + nv50_disp_atomic_commit_core(drm, interlock); + memset(interlock, 0x00, sizeof(interlock)); } } } /* Flush disable. */ - if (interlock_core) { + if (interlock[NV50_DISP_INTERLOCK_CORE]) { if (atom->flush_disable) { - nv50_disp_atomic_commit_core(drm, interlock_chan); - interlock_core = 0; - interlock_chan = 0; + nv50_disp_atomic_commit_core(drm, interlock); + memset(interlock, 0x00, sizeof(interlock)); } } @@ -1713,7 +1708,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) if (outp->set.mask) { help->enable(encoder); - interlock_core = 1; + interlock[NV50_DISP_INTERLOCK_CORE] = 1; } list_del(&outp->head); @@ -1730,7 +1725,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) if (asyh->set.mask) { nv50_head_flush_set(head, asyh); - interlock_core = 1; + interlock[NV50_DISP_INTERLOCK_CORE] = 1; } if (new_crtc_state->active) { @@ -1752,15 +1747,16 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) (!asyw->clr.mask || atom->flush_disable)) continue; - interlock_chan |= nv50_wndw_flush_set(wndw, interlock_core, asyw); + nv50_wndw_flush_set(wndw, interlock, asyw); } /* Flush update. */ - if (interlock_core) { - if (interlock_chan || !atom->state.legacy_cursor_update) - nv50_disp_atomic_commit_core(drm, interlock_chan); + if (interlock[NV50_DISP_INTERLOCK_CORE]) { + if (interlock[NV50_DISP_INTERLOCK_BASE] || + !atom->state.legacy_cursor_update) + nv50_disp_atomic_commit_core(drm, interlock); else - disp->core->func->update(disp->core, 0, false); + disp->core->func->update(disp->core, interlock, false); } if (atom->lock_core) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.h b/drivers/gpu/drm/nouveau/dispnv50/disp.h index 7cbd668497436..f3a963b0ab77e 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.h +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.h @@ -27,6 +27,17 @@ nv50_disp(struct drm_device *dev) return nouveau_display(dev)->priv; } +struct nv50_disp_interlock { + enum nv50_disp_interlock_type { + NV50_DISP_INTERLOCK_CORE = 0, + NV50_DISP_INTERLOCK_CURS, + NV50_DISP_INTERLOCK_BASE, + NV50_DISP_INTERLOCK_OVLY, + NV50_DISP_INTERLOCK__SIZE + } type; + u32 data; +}; + struct nv50_chan { struct nvif_object user; struct nvif_device *device; diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly.c b/drivers/gpu/drm/nouveau/dispnv50/ovly.c index ac2d3b64f1863..be0f16fdcd5bd 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/ovly.c +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly.c @@ -32,11 +32,11 @@ nv50_ovly_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) int version; int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); } ovlys[] = { - { GK104_DISP_OVERLAY_CONTROL_DMA, 0, ovly507e_new }, - { GF110_DISP_OVERLAY_CONTROL_DMA, 0, ovly507e_new }, - { GT214_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new }, - { GT200_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new }, - { G82_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new }, + { GK104_DISP_OVERLAY_CONTROL_DMA, 0, ovly907e_new }, + { GF110_DISP_OVERLAY_CONTROL_DMA, 0, ovly907e_new }, + { GT214_DISP_OVERLAY_CHANNEL_DMA, 0, ovly827e_new }, + { GT200_DISP_OVERLAY_CHANNEL_DMA, 0, ovly827e_new }, + { G82_DISP_OVERLAY_CHANNEL_DMA, 0, ovly827e_new }, { NV50_DISP_OVERLAY_CHANNEL_DMA, 0, ovly507e_new }, {} }; diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly.h b/drivers/gpu/drm/nouveau/dispnv50/ovly.h index 90af1f2f0aa01..d149ef6f957e6 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/ovly.h +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly.h @@ -3,6 +3,14 @@ #include "wndw.h" int ovly507e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); +int ovly507e_new_(const struct nv50_wndw_func *, const u32 *format, + struct nouveau_drm *, int head, s32 oclass, + u32 interlock_data, struct nv50_wndw **); + +extern const u32 ovly827e_format[]; + +int ovly827e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); +int ovly907e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); int nv50_ovly_new(struct nouveau_drm *, int head, struct nv50_wndw **); #endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c b/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c index 1b85262bf23bb..732eea39e4de7 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c @@ -34,9 +34,9 @@ ovly507e_format[] = { 0 }; -static int +int ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format, - struct nouveau_drm *drm, int head, s32 oclass, + struct nouveau_drm *drm, int head, s32 oclass, u32 interlock_data, struct nv50_wndw **pwndw) { struct nv50_disp_overlay_channel_dma_v0 args = { @@ -47,7 +47,9 @@ ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format, int ret; ret = nv50_wndw_new_(func, drm->dev, DRM_PLANE_TYPE_OVERLAY, - "ovly", head, format, BIT(head), &wndw); + "ovly", head, format, BIT(head), + NV50_DISP_INTERLOCK_OVLY, interlock_data, + &wndw); if (*pwndw = wndw, ret) return ret; @@ -66,5 +68,6 @@ int ovly507e_new(struct nouveau_drm *drm, int head, s32 oclass, struct nv50_wndw **pwndw) { - return ovly507e_new_(&ovly507e, ovly507e_format, drm, head, oclass, pwndw); + return ovly507e_new_(&ovly507e, ovly507e_format, drm, head, oclass, + 0x00000004 << (head * 8), pwndw); } diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly827e.c b/drivers/gpu/drm/nouveau/dispnv50/ovly827e.c new file mode 100644 index 0000000000000..a8115f13406ee --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly827e.c @@ -0,0 +1,43 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "ovly.h" + +#include + +#include + +static const struct nv50_wndw_func +ovly827e = { +}; + +const u32 +ovly827e_format[] = { + 0 +}; + +int +ovly827e_new(struct nouveau_drm *drm, int head, s32 oclass, + struct nv50_wndw **pwndw) +{ + return ovly507e_new_(&ovly827e, ovly827e_format, drm, head, oclass, + 0x00000004 << (head * 8), pwndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly907e.c b/drivers/gpu/drm/nouveau/dispnv50/ovly907e.c new file mode 100644 index 0000000000000..f50da6461d41b --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly907e.c @@ -0,0 +1,34 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "ovly.h" + +static const struct nv50_wndw_func +ovly907e = { +}; + +int +ovly907e_new(struct nouveau_drm *drm, int head, s32 oclass, + struct nv50_wndw **pwndw) +{ + return ovly507e_new_(&ovly907e, ovly827e_format, drm, head, oclass, + 0x00000004 << (head * 4), pwndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index 4b64f64b78910..8f62c2a811ffb 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -107,8 +107,8 @@ nv50_wndw_wait_armed(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) return 0; } -u32 -nv50_wndw_flush_clr(struct nv50_wndw *wndw, u32 interlock, bool flush, +void +nv50_wndw_flush_clr(struct nv50_wndw *wndw, u32 *interlock, bool flush, struct nv50_wndw_atom *asyw) { union nv50_wndw_atom_mask clr = { @@ -118,11 +118,13 @@ nv50_wndw_flush_clr(struct nv50_wndw *wndw, u32 interlock, bool flush, if (clr.ntfy ) wndw->func-> ntfy_clr(wndw); if (clr.image) wndw->func->image_clr(wndw); - return flush ? wndw->func->update(wndw, interlock) : 0; + interlock[wndw->interlock.type] |= wndw->interlock.data; + if (flush) + wndw->func->update(wndw, interlock); } -u32 -nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 interlock, +void +nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock, struct nv50_wndw_atom *asyw) { if (interlock) { @@ -139,7 +141,9 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 interlock, wndw->immd->update(wndw, interlock); } - return wndw->func->update ? wndw->func->update(wndw, interlock) : 0; + interlock[wndw->interlock.type] |= wndw->interlock.data; + if (wndw->func->update) + wndw->func->update(wndw, interlock); } void @@ -445,7 +449,9 @@ nv50_wndw_init(struct nv50_wndw *wndw) int nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, enum drm_plane_type type, const char *name, int index, - const u32 *format, u32 heads, struct nv50_wndw **pwndw) + const u32 *format, u32 heads, + enum nv50_disp_interlock_type interlock_type, u32 interlock_data, + struct nv50_wndw **pwndw) { struct nv50_wndw *wndw; int nformat; @@ -455,6 +461,9 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, return -ENOMEM; wndw->func = func; wndw->id = index; + wndw->interlock.type = interlock_type; + wndw->interlock.data = interlock_data; + wndw->ctxdma.parent = &wndw->wndw.base.user; wndw->ctxdma.parent = &wndw->wndw.base.user; INIT_LIST_HEAD(&wndw->ctxdma.list); diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.h b/drivers/gpu/drm/nouveau/dispnv50/wndw.h index 8672c280a6a42..c26796c612f6b 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.h +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.h @@ -15,6 +15,7 @@ struct nv50_wndw { const struct nv50_wndw_func *func; const struct nv50_wimm_func *immd; int id; + struct nv50_disp_interlock interlock; struct { struct nvif_object *parent; @@ -34,13 +35,14 @@ struct nv50_wndw { int nv50_wndw_new_(const struct nv50_wndw_func *, struct drm_device *, enum drm_plane_type, const char *name, int index, - const u32 *format, u32 heads, struct nv50_wndw **); + const u32 *format, enum nv50_disp_interlock_type, + u32 interlock_data, u32 heads, struct nv50_wndw **); void nv50_wndw_init(struct nv50_wndw *); void nv50_wndw_fini(struct nv50_wndw *); -u32 nv50_wndw_flush_set(struct nv50_wndw *, u32 interlock, - struct nv50_wndw_atom *); -u32 nv50_wndw_flush_clr(struct nv50_wndw *, u32 interlock, bool flush, - struct nv50_wndw_atom *); +void nv50_wndw_flush_set(struct nv50_wndw *, u32 *interlock, + struct nv50_wndw_atom *); +void nv50_wndw_flush_clr(struct nv50_wndw *, u32 *interlock, bool flush, + struct nv50_wndw_atom *); void nv50_wndw_ntfy_enable(struct nv50_wndw *, struct nv50_wndw_atom *); int nv50_wndw_wait_armed(struct nv50_wndw *, struct nv50_wndw_atom *); @@ -63,7 +65,7 @@ struct nv50_wndw_func { void (*image_clr)(struct nv50_wndw *); void (*lut)(struct nv50_wndw *, struct nv50_wndw_atom *); - u32 (*update)(struct nv50_wndw *, u32 interlock); + void (*update)(struct nv50_wndw *, u32 *interlock); }; extern const struct drm_plane_funcs nv50_wndw; @@ -71,6 +73,6 @@ extern const struct drm_plane_funcs nv50_wndw; struct nv50_wimm_func { void (*point)(struct nv50_wndw *, struct nv50_wndw_atom *); - u32 (*update)(struct nv50_wndw *, u32 interlock); + void (*update)(struct nv50_wndw *, u32 *interlock); }; #endif From 04fc14be7726edbb34404f69297e74061a8a9563 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 124/165] drm/nouveau/kms/nv50-: decouple window state changes, and update method submisssion This will be required to support Volta. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 16 ++++++++++++++++ drivers/gpu/drm/nouveau/dispnv50/wndw.c | 4 ---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index e80d11c9a456e..0f2020010aab0 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1690,6 +1690,14 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) /* Flush disable. */ if (interlock[NV50_DISP_INTERLOCK_CORE]) { if (atom->flush_disable) { + for_each_new_plane_in_state(state, plane, new_plane_state, i) { + struct nv50_wndw *wndw = nv50_wndw(plane); + if (interlock[wndw->interlock.type] & wndw->interlock.data) { + if (wndw->func->update) + wndw->func->update(wndw, interlock); + } + } + nv50_disp_atomic_commit_core(drm, interlock); memset(interlock, 0x00, sizeof(interlock)); } @@ -1751,6 +1759,14 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) } /* Flush update. */ + for_each_new_plane_in_state(state, plane, new_plane_state, i) { + struct nv50_wndw *wndw = nv50_wndw(plane); + if (interlock[wndw->interlock.type] & wndw->interlock.data) { + if (wndw->func->update) + wndw->func->update(wndw, interlock); + } + } + if (interlock[NV50_DISP_INTERLOCK_CORE]) { if (interlock[NV50_DISP_INTERLOCK_BASE] || !atom->state.legacy_cursor_update) diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index 8f62c2a811ffb..0fba4e0a4bb4b 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -119,8 +119,6 @@ nv50_wndw_flush_clr(struct nv50_wndw *wndw, u32 *interlock, bool flush, if (clr.image) wndw->func->image_clr(wndw); interlock[wndw->interlock.type] |= wndw->interlock.data; - if (flush) - wndw->func->update(wndw, interlock); } void @@ -142,8 +140,6 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock, } interlock[wndw->interlock.type] |= wndw->interlock.data; - if (wndw->func->update) - wndw->func->update(wndw, interlock); } void From 45a2945a3759479c08a4aceaee181639c92f9d48 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 125/165] drm/nouveau/kms/nv50-: simplify swap interval handling This is just cleaning up some left-overs from when we needed a custom legacy page flip implementation. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/atom.h | 1 - drivers/gpu/drm/nouveau/dispnv50/wndw.c | 11 +++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/atom.h b/drivers/gpu/drm/nouveau/dispnv50/atom.h index 53638ee833615..b5b8a12a18f26 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/atom.h +++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h @@ -135,7 +135,6 @@ nv50_head_atom_get(struct drm_atomic_state *state, struct drm_crtc *crtc) struct nv50_wndw_atom { struct drm_plane_state state; - u8 interval; struct { u32 handle; diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index 0fba4e0a4bb4b..06d1696b7d03d 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -208,11 +208,6 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, if (ret) return ret; - if (asyh->state.pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC) - asyw->interval = 0; - else - asyw->interval = 1; - if (asyw->image.kind) { asyw->image.layout = 0; if (drm->client.device.info.chipset >= 0xc0) @@ -231,10 +226,11 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, return ret; if (asyw->set.image) { - if (!(asyw->image.mode = asyw->interval ? 0 : 1)) - asyw->image.interval = asyw->interval; + if (!(asyh->state.pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC)) + asyw->image.interval = 1; else asyw->image.interval = 0; + asyw->image.mode = asyw->image.interval ? 0 : 1; } return 0; @@ -371,7 +367,6 @@ nv50_wndw_atomic_duplicate_state(struct drm_plane *plane) if (!(asyw = kmalloc(sizeof(*asyw), GFP_KERNEL))) return NULL; __drm_atomic_helper_plane_duplicate_state(plane, &asyw->state); - asyw->interval = 1; asyw->sema = armw->sema; asyw->ntfy = armw->ntfy; asyw->image = armw->image; From 859b456b6b19a19761883cf52993dec645a36152 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 126/165] drm/nouveau/kms/nv50-: store window visibility in state Window visibility is going to become a little more complicated with the upcoming LUT changes, so store the calculated value to avoid needing to recalculate the armed state again. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/atom.h | 2 ++ drivers/gpu/drm/nouveau/dispnv50/wndw.c | 27 +++++++++++++++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/atom.h b/drivers/gpu/drm/nouveau/dispnv50/atom.h index b5b8a12a18f26..fefb9caaf7b8a 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/atom.h +++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h @@ -136,6 +136,8 @@ nv50_head_atom_get(struct drm_atomic_state *state, struct drm_crtc *crtc) struct nv50_wndw_atom { struct drm_plane_state state; + bool visible; + struct { u32 handle; u16 offset:12; diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index 06d1696b7d03d..4a685d78ed339 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -244,26 +244,33 @@ nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) struct nv50_wndw_atom *armw = nv50_wndw_atom(wndw->plane.state); struct nv50_wndw_atom *asyw = nv50_wndw_atom(state); struct nv50_head_atom *harm = NULL, *asyh = NULL; - bool varm = false, asyv = false, asym = false; + bool modeset = false; int ret; NV_ATOMIC(drm, "%s atomic_check\n", plane->name); + + /* Fetch the assembly state for the head the window will belong to, + * and determine whether the window will be visible. + */ if (asyw->state.crtc) { asyh = nv50_head_atom_get(asyw->state.state, asyw->state.crtc); if (IS_ERR(asyh)) return PTR_ERR(asyh); - asym = drm_atomic_crtc_needs_modeset(&asyh->state); - asyv = asyh->state.active; + modeset = drm_atomic_crtc_needs_modeset(&asyh->state); + asyw->visible = asyh->state.active; + } else { + asyw->visible = false; } + /* Fetch assembly state for the head the window used to belong to. */ if (armw->state.crtc) { harm = nv50_head_atom_get(asyw->state.state, armw->state.crtc); if (IS_ERR(harm)) return PTR_ERR(harm); - varm = harm->state.crtc->state->active; } - if (asyv) { + /* Calculate new window state. */ + if (asyw->visible) { asyw->point.x = asyw->state.crtc_x; asyw->point.y = asyw->state.crtc_y; if (memcmp(&armw->point, &asyw->point, sizeof(asyw->point))) @@ -273,18 +280,22 @@ nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) if (ret) return ret; } else - if (varm) { + if (armw->visible) { nv50_wndw_atomic_check_release(wndw, asyw, harm); } else { return 0; } - if (!asyv || asym) { + /* Aside from the obvious case where the window is actively being + * disabled, we might also need to temporarily disable the window + * when performing certain modeset operations. + */ + if (!asyw->visible || modeset) { asyw->clr.ntfy = armw->ntfy.handle != 0; asyw->clr.sema = armw->sema.handle != 0; if (wndw->func->image_clr) asyw->clr.image = armw->image.handle[0] != 0; - asyw->set.lut = wndw->func->lut && asyv; + asyw->set.lut = wndw->func->lut && asyw->visible; } return 0; From e349a05dc8faad6b27700383945a1783612cbae6 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 127/165] drm/nouveau/kms/nv50-: plane updates don't always require image_set() When only the position of a window changes, there's no need to submit an image update as well. Will be required to support the overlays, and Volta windows. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/base507c.c | 1 - drivers/gpu/drm/nouveau/dispnv50/wndw.c | 63 +++++++++++---------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/base507c.c b/drivers/gpu/drm/nouveau/dispnv50/base507c.c index 819403f4b958d..d8d3516693676 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base507c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base507c.c @@ -185,7 +185,6 @@ base507c_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, asyh->base.h = asyw->state.fb->height; asyw->lut.enable = 1; - asyw->set.image = true; return 0; } diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index 4a685d78ed339..0f6de6049be44 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -190,7 +190,8 @@ nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw) } static int -nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, +nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, + struct nv50_wndw_atom *armw, struct nv50_wndw_atom *asyw, struct nv50_head_atom *asyh) { @@ -200,40 +201,44 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, NV_ATOMIC(drm, "%s acquire\n", wndw->plane.name); - asyw->image.w = fb->base.width; - asyw->image.h = fb->base.height; - asyw->image.kind = fb->nvbo->kind; + if (asyw->state.fb != armw->state.fb || !armw->visible || modeset) { + asyw->image.w = fb->base.width; + asyw->image.h = fb->base.height; + asyw->image.kind = fb->nvbo->kind; - ret = nv50_wndw_atomic_check_acquire_rgb(asyw); - if (ret) - return ret; - - if (asyw->image.kind) { - asyw->image.layout = 0; - if (drm->client.device.info.chipset >= 0xc0) - asyw->image.block = fb->nvbo->mode >> 4; - else - asyw->image.block = fb->nvbo->mode; - asyw->image.pitch[0] = (fb->base.pitches[0] / 4) << 4; - } else { - asyw->image.layout = 1; - asyw->image.block = 0; - asyw->image.pitch[0] = fb->base.pitches[0]; - } + ret = nv50_wndw_atomic_check_acquire_rgb(asyw); + if (ret) + return ret; - ret = wndw->func->acquire(wndw, asyw, asyh); - if (ret) - return ret; + if (asyw->image.kind) { + asyw->image.layout = 0; + if (drm->client.device.info.chipset >= 0xc0) + asyw->image.block = fb->nvbo->mode >> 4; + else + asyw->image.block = fb->nvbo->mode; + asyw->image.pitch[0] = (fb->base.pitches[0] / 4) << 4; + } else { + asyw->image.layout = 1; + asyw->image.block = 0; + asyw->image.pitch[0] = fb->base.pitches[0]; + } - if (asyw->set.image) { if (!(asyh->state.pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC)) asyw->image.interval = 1; else asyw->image.interval = 0; asyw->image.mode = asyw->image.interval ? 0 : 1; + asyw->set.image = wndw->func->image_set != NULL; } - return 0; + if (wndw->immd) { + asyw->point.x = asyw->state.crtc_x; + asyw->point.y = asyw->state.crtc_y; + if (memcmp(&armw->point, &asyw->point, sizeof(asyw->point))) + asyw->set.point = true; + } + + return wndw->func->acquire(wndw, asyw, asyh); } int @@ -271,12 +276,8 @@ nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) /* Calculate new window state. */ if (asyw->visible) { - asyw->point.x = asyw->state.crtc_x; - asyw->point.y = asyw->state.crtc_y; - if (memcmp(&armw->point, &asyw->point, sizeof(asyw->point))) - asyw->set.point = true; - - ret = nv50_wndw_atomic_check_acquire(wndw, asyw, asyh); + ret = nv50_wndw_atomic_check_acquire(wndw, modeset, + armw, asyw, asyh); if (ret) return ret; } else From 119608a7f3f1ef899f1f98d05306340b92834836 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 128/165] drm/nouveau/kms/nv50-: handle degamma LUT from window channels Required to eventually support DRM colour management APIs, and to support Volta. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/Kbuild | 1 + drivers/gpu/drm/nouveau/dispnv50/atom.h | 25 ++- drivers/gpu/drm/nouveau/dispnv50/base.h | 3 +- drivers/gpu/drm/nouveau/dispnv50/base507c.c | 44 ++++-- drivers/gpu/drm/nouveau/dispnv50/base827c.c | 4 +- drivers/gpu/drm/nouveau/dispnv50/base907c.c | 43 +++++- drivers/gpu/drm/nouveau/dispnv50/disp.c | 11 ++ drivers/gpu/drm/nouveau/dispnv50/head.c | 160 ++++++++------------ drivers/gpu/drm/nouveau/dispnv50/head.h | 18 +-- drivers/gpu/drm/nouveau/dispnv50/head507d.c | 29 ++-- drivers/gpu/drm/nouveau/dispnv50/head827d.c | 17 ++- drivers/gpu/drm/nouveau/dispnv50/head907d.c | 33 ++-- drivers/gpu/drm/nouveau/dispnv50/head917d.c | 34 ++++- drivers/gpu/drm/nouveau/dispnv50/lut.c | 95 ++++++++++++ drivers/gpu/drm/nouveau/dispnv50/lut.h | 15 ++ drivers/gpu/drm/nouveau/dispnv50/wndw.c | 93 +++++++++++- drivers/gpu/drm/nouveau/dispnv50/wndw.h | 8 +- 17 files changed, 462 insertions(+), 171 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/dispnv50/lut.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/lut.h diff --git a/drivers/gpu/drm/nouveau/dispnv50/Kbuild b/drivers/gpu/drm/nouveau/dispnv50/Kbuild index 3e53484b4589d..d074bb8ecd1be 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/Kbuild +++ b/drivers/gpu/drm/nouveau/dispnv50/Kbuild @@ -1,4 +1,5 @@ nouveau-y += dispnv50/disp.o +nouveau-y += dispnv50/lut.o nouveau-y += dispnv50/core.o nouveau-y += dispnv50/core507d.o diff --git a/drivers/gpu/drm/nouveau/dispnv50/atom.h b/drivers/gpu/drm/nouveau/dispnv50/atom.h index fefb9caaf7b8a..3e9e8832d0dd1 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/atom.h +++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h @@ -16,6 +16,11 @@ struct nv50_atom { struct nv50_head_atom { struct drm_crtc_state state; + struct { + u32 mask; + u32 olut; + } wndw; + struct { u16 iW; u16 iH; @@ -47,8 +52,9 @@ struct nv50_head_atom { bool visible; u32 handle; u64 offset:40; - u8 mode:4; - } ilut; + u8 buffer:1; + u8 mode:4; + } olut; struct { bool visible; @@ -107,7 +113,7 @@ struct nv50_head_atom { union nv50_head_atom_mask { struct { - bool ilut:1; + bool olut:1; bool core:1; bool curs:1; bool view:1; @@ -136,6 +142,7 @@ nv50_head_atom_get(struct drm_atomic_state *state, struct drm_crtc *crtc) struct nv50_wndw_atom { struct drm_plane_state state; + struct drm_property_blob *ilut; bool visible; struct { @@ -152,8 +159,14 @@ struct nv50_wndw_atom { } sema; struct { - u8 enable:2; - } lut; + u32 handle; + struct { + u64 offset:40; + u8 buffer:1; + u8 enable:2; + u8 mode:4; + } i; + } xlut; struct { u8 mode:2; @@ -180,8 +193,8 @@ struct nv50_wndw_atom { struct { bool ntfy:1; bool sema:1; + bool xlut:1; bool image:1; - bool lut:1; bool point:1; }; u8 mask; diff --git a/drivers/gpu/drm/nouveau/dispnv50/base.h b/drivers/gpu/drm/nouveau/dispnv50/base.h index 71fc10369b373..87ec8394b7f3c 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base.h +++ b/drivers/gpu/drm/nouveau/dispnv50/base.h @@ -17,8 +17,9 @@ void base507c_ntfy_reset(struct nouveau_bo *, u32); void base507c_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *); void base507c_ntfy_clr(struct nv50_wndw *); int base507c_ntfy_wait_begun(struct nouveau_bo *, u32, struct nvif_device *); +void base507c_xlut_set(struct nv50_wndw *, struct nv50_wndw_atom *); +void base507c_xlut_clr(struct nv50_wndw *); void base507c_image_clr(struct nv50_wndw *); -void base507c_lut(struct nv50_wndw *, struct nv50_wndw_atom *); void base507c_update(struct nv50_wndw *, u32 *); int base827c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); diff --git a/drivers/gpu/drm/nouveau/dispnv50/base507c.c b/drivers/gpu/drm/nouveau/dispnv50/base507c.c index d8d3516693676..5d664d75b6451 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base507c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base507c.c @@ -39,17 +39,6 @@ base507c_update(struct nv50_wndw *wndw, u32 *interlock) } } -void -base507c_lut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) -{ - u32 *push; - if ((push = evo_wait(&wndw->wndw, 2))) { - evo_mthd(push, 0x00e0, 1); - evo_data(push, asyw->lut.enable << 30); - evo_kick(push, &wndw->wndw); - } -} - void base507c_image_clr(struct nv50_wndw *wndw) { @@ -86,6 +75,28 @@ base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) } } +void +base507c_xlut_clr(struct nv50_wndw *wndw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 2))) { + evo_mthd(push, 0x00e0, 1); + evo_data(push, 0x00000000); + evo_kick(push, &wndw->wndw); + } +} + +void +base507c_xlut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 2))) { + evo_mthd(push, 0x00e0, 1); + evo_data(push, 0x40000000); + evo_kick(push, &wndw->wndw); + } +} + int base507c_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset, struct nvif_device *device) @@ -177,14 +188,17 @@ base507c_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, if (ret) return ret; + if (!wndw->func->ilut) { + if ((asyh->base.cpp != 1) ^ (fb->format->cpp[0] != 1)) + asyh->state.color_mgmt_changed = true; + } + asyh->base.depth = fb->format->depth; asyh->base.cpp = fb->format->cpp[0]; asyh->base.x = asyw->state.src.x1 >> 16; asyh->base.y = asyw->state.src.y1 >> 16; asyh->base.w = asyw->state.fb->width; asyh->base.h = asyw->state.fb->height; - - asyw->lut.enable = 1; return 0; } @@ -213,9 +227,11 @@ base507c = { .ntfy_set = base507c_ntfy_set, .ntfy_clr = base507c_ntfy_clr, .ntfy_wait_begun = base507c_ntfy_wait_begun, + .olut_core = 1, + .xlut_set = base507c_xlut_set, + .xlut_clr = base507c_xlut_clr, .image_set = base507c_image_set, .image_clr = base507c_image_clr, - .lut = base507c_lut, .update = base507c_update, }; diff --git a/drivers/gpu/drm/nouveau/dispnv50/base827c.c b/drivers/gpu/drm/nouveau/dispnv50/base827c.c index 240a6409329d2..d886858a57240 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base827c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base827c.c @@ -53,9 +53,11 @@ base827c = { .ntfy_set = base507c_ntfy_set, .ntfy_clr = base507c_ntfy_clr, .ntfy_wait_begun = base507c_ntfy_wait_begun, + .olut_core = 1, + .xlut_set = base507c_xlut_set, + .xlut_clr = base507c_xlut_clr, .image_set = base827c_image_set, .image_clr = base507c_image_clr, - .lut = base507c_lut, .update = base507c_update, }; diff --git a/drivers/gpu/drm/nouveau/dispnv50/base907c.c b/drivers/gpu/drm/nouveau/dispnv50/base907c.c index 6c32a4e5cb7d9..2643592ad827c 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base907c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base907c.c @@ -43,6 +43,44 @@ base907c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) } } +static void +base907c_xlut_clr(struct nv50_wndw *wndw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 6))) { + evo_mthd(push, 0x00e0, 1); + evo_data(push, 0x00000000); + evo_mthd(push, 0x00e8, 1); + evo_data(push, 0x00000000); + evo_mthd(push, 0x00fc, 1); + evo_data(push, 0x00000000); + evo_kick(push, &wndw->wndw); + } +} + +static void +base907c_xlut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 6))) { + evo_mthd(push, 0x00e0, 3); + evo_data(push, asyw->xlut.i.enable << 30 | + asyw->xlut.i.mode << 24); + evo_data(push, asyw->xlut.i.offset >> 8); + evo_data(push, 0x40000000); + evo_mthd(push, 0x00fc, 1); + evo_data(push, asyw->xlut.handle); + evo_kick(push, &wndw->wndw); + } +} + +static void +base907c_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + asyw->xlut.i.mode = 7; + asyw->xlut.i.enable = 2; +} + static const struct nv50_wndw_func base907c = { .acquire = base507c_acquire, @@ -53,9 +91,12 @@ base907c = { .ntfy_set = base507c_ntfy_set, .ntfy_clr = base507c_ntfy_clr, .ntfy_wait_begun = base507c_ntfy_wait_begun, + .ilut = base907c_ilut, + .olut_core = true, + .xlut_set = base907c_xlut_set, + .xlut_clr = base907c_xlut_clr, .image_set = base907c_image_set, .image_clr = base507c_image_clr, - .lut = base507c_lut, .update = base507c_update, }; diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 0f2020010aab0..6c860e8b1b16f 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1971,8 +1971,19 @@ nv50_disp_atomic_check(struct drm_device *dev, struct drm_atomic_state *state) struct nv50_atom *atom = nv50_atom(state); struct drm_connector_state *old_connector_state, *new_connector_state; struct drm_connector *connector; + struct drm_crtc_state *new_crtc_state; + struct drm_crtc *crtc; int ret, i; + /* We need to handle colour management on a per-plane basis. */ + for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { + if (new_crtc_state->color_mgmt_changed) { + ret = drm_atomic_add_affected_planes(state, crtc); + if (ret) + return ret; + } + } + ret = drm_atomic_helper_check(dev, state); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c index 2eb7fdb611310..ca83006510b7f 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head.c @@ -30,56 +30,6 @@ #include #include #include "nouveau_connector.h" -#include "nouveau_bo.h" - -static void -nv50_head_lut_load(struct drm_property_blob *blob, int mode, - struct nouveau_bo *nvbo) -{ - struct drm_color_lut *in = (struct drm_color_lut *)blob->data; - void __iomem *lut = (u8 *)nvbo_kmap_obj_iovirtual(nvbo); - const int size = blob->length / sizeof(*in); - int bits, shift, i; - u16 zero, r, g, b; - - /* This can't happen.. But it shuts the compiler up. */ - if (WARN_ON(size != 256)) - return; - - switch (mode) { - case 0: /* LORES. */ - case 1: /* HIRES. */ - bits = 11; - shift = 3; - zero = 0x0000; - break; - case 7: /* INTERPOLATE_257_UNITY_RANGE. */ - bits = 14; - shift = 0; - zero = 0x6000; - break; - default: - WARN_ON(1); - return; - } - - for (i = 0; i < size; i++) { - r = (drm_color_lut_extract(in[i]. red, bits) + zero) << shift; - g = (drm_color_lut_extract(in[i].green, bits) + zero) << shift; - b = (drm_color_lut_extract(in[i]. blue, bits) + zero) << shift; - writew(r, lut + (i * 0x08) + 0); - writew(g, lut + (i * 0x08) + 2); - writew(b, lut + (i * 0x08) + 4); - } - - /* INTERPOLATE modes require a "next" entry to interpolate with, - * so we replicate the last entry to deal with this for now. - */ - writew(r, lut + (i * 0x08) + 0); - writew(g, lut + (i * 0x08) + 2); - writew(b, lut + (i * 0x08) + 4); -} - void nv50_head_flush_clr(struct nv50_head *head, struct nv50_head_atom *asyh, bool flush) @@ -87,7 +37,7 @@ nv50_head_flush_clr(struct nv50_head *head, union nv50_head_atom_mask clr = { .mask = asyh->clr.mask & ~(flush ? 0 : asyh->set.mask), }; - if (clr.ilut) head->func->ilut_clr(head); + if (clr.olut) head->func->olut_clr(head); if (clr.core) head->func->core_clr(head); if (clr.curs) head->func->curs_clr(head); } @@ -97,16 +47,14 @@ 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.ilut ) { - struct nouveau_bo *nvbo = head->ilut.nvbo[head->ilut.next]; - struct drm_property_blob *blob = asyh->state.gamma_lut; - if (blob) - nv50_head_lut_load(blob, asyh->ilut.mode, nvbo); - asyh->ilut.offset = nvbo->bo.offset; - head->ilut.next ^= 1; - head->func->ilut_set(head, asyh); - } if (asyh->set.core ) head->func->core_set(head, asyh); + if (asyh->set.olut ) { + asyh->olut.offset = nv50_lut_load(&head->olut, + asyh->olut.mode <= 1, + asyh->olut.buffer, + asyh->state.gamma_lut); + head->func->olut_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); @@ -240,35 +188,37 @@ nv50_head_atomic_check_view(struct nv50_head_atom *armh, asyh->set.view = true; } -static void +static int nv50_head_atomic_check_lut(struct nv50_head *head, - struct nv50_head_atom *armh, struct nv50_head_atom *asyh) { struct nv50_disp *disp = nv50_disp(head->base.base.dev); - - /* An I8 surface without an input LUT makes no sense, and - * EVO will throw an error if you try. - * - * Legacy clients actually cause this due to the order in - * which they call ioctls, so we will enable the LUT with - * whatever contents the buffer already contains to avoid - * triggering the error check. - */ - if (!asyh->state.gamma_lut && asyh->base.cpp != 1) { - asyh->ilut.handle = 0; - asyh->clr.ilut = armh->ilut.visible; - return; + struct drm_property_blob *olut = asyh->state.gamma_lut; + + /* Determine whether core output LUT should be enabled. */ + if (olut) { + /* Check if any window(s) have stolen the core output LUT + * to as an input LUT for legacy gamma + I8 colour format. + */ + if (asyh->wndw.olut) { + /* If any window has stolen the core output LUT, + * all of them must. + */ + if (asyh->wndw.olut != asyh->wndw.mask) + return -EINVAL; + olut = NULL; + } } - if (disp->disp->object.oclass < GF110_DISP) { - asyh->ilut.mode = (asyh->base.cpp == 1) ? 0 : 1; - asyh->set.ilut = true; - } else { - asyh->ilut.mode = 7; - asyh->set.ilut = asyh->state.color_mgmt_changed; + if (!olut) { + asyh->olut.handle = 0; + return 0; } - asyh->ilut.handle = disp->core->chan.vram.handle; + + asyh->olut.handle = disp->core->chan.vram.handle; + asyh->olut.buffer = !asyh->olut.buffer; + head->func->olut(head, asyh); + return 0; } static void @@ -360,9 +310,13 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) nv50_head_atomic_check_mode(head, asyh); if (asyh->state.color_mgmt_changed || - asyh->base.cpp != armh->base.cpp) - nv50_head_atomic_check_lut(head, armh, asyh); - asyh->ilut.visible = asyh->ilut.handle != 0; + memcmp(&armh->wndw, &asyh->wndw, sizeof(asyh->wndw))) { + int ret = nv50_head_atomic_check_lut(head, asyh); + if (ret) + return ret; + + asyh->olut.visible = asyh->olut.handle != 0; + } if (asyc) { if (asyc->set.scaler) @@ -373,13 +327,16 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) nv50_head_atomic_check_procamp(armh, asyh, asyc); } - if (head->func->core_calc) + if (head->func->core_calc) { head->func->core_calc(head, asyh); + if (!asyh->core.visible) + asyh->olut.visible = false; + } asyh->set.base = armh->base.cpp != asyh->base.cpp; asyh->set.ovly = armh->ovly.cpp != asyh->ovly.cpp; } else { - asyh->ilut.visible = false; + asyh->olut.visible = false; asyh->core.visible = false; asyh->curs.visible = false; asyh->base.cpp = 0; @@ -402,11 +359,19 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) if (armh->curs.visible) { asyh->clr.curs = true; } + + if (asyh->olut.visible) { + if (memcmp(&armh->olut, &asyh->olut, sizeof(asyh->olut))) + asyh->set.olut = true; + } else + if (armh->olut.visible) { + asyh->clr.olut = true; + } } else { - asyh->clr.ilut = armh->ilut.visible; + asyh->clr.olut = armh->olut.visible; asyh->clr.core = armh->core.visible; asyh->clr.curs = armh->curs.visible; - asyh->set.ilut = asyh->ilut.visible; + asyh->set.olut = asyh->olut.visible; asyh->set.core = asyh->core.visible; asyh->set.curs = asyh->curs.visible; } @@ -438,9 +403,10 @@ nv50_head_atomic_duplicate_state(struct drm_crtc *crtc) if (!(asyh = kmalloc(sizeof(*asyh), GFP_KERNEL))) return NULL; __drm_atomic_helper_crtc_duplicate_state(crtc, &asyh->state); + asyh->wndw = armh->wndw; asyh->view = armh->view; asyh->mode = armh->mode; - asyh->ilut = armh->ilut; + asyh->olut = armh->olut; asyh->core = armh->core; asyh->curs = armh->curs; asyh->base = armh->base; @@ -477,11 +443,7 @@ static void nv50_head_destroy(struct drm_crtc *crtc) { struct nv50_head *head = nv50_head(crtc); - int i; - - for (i = 0; i < ARRAY_SIZE(head->ilut.nvbo); i++) - nouveau_bo_unmap_unpin_unref(&head->ilut.nvbo[i]); - + nv50_lut_fini(&head->olut); drm_crtc_cleanup(crtc); kfree(head); } @@ -505,7 +467,7 @@ nv50_head_create(struct drm_device *dev, int index) struct nv50_head *head; struct nv50_wndw *curs, *wndw; struct drm_crtc *crtc; - int ret, i; + int ret; head = kzalloc(sizeof(*head), GFP_KERNEL); if (!head) @@ -527,10 +489,8 @@ nv50_head_create(struct drm_device *dev, int index) drm_crtc_helper_add(crtc, &nv50_head_help); drm_mode_crtc_set_gamma_size(crtc, 256); - for (i = 0; i < ARRAY_SIZE(head->ilut.nvbo); i++) { - ret = nouveau_bo_new_pin_map(&drm->client, 1025 * 8, 0x100, - TTM_PL_FLAG_VRAM, - &head->ilut.nvbo[i]); + if (head->func->olut_set) { + ret = nv50_lut_init(disp, &drm->client.mmu, &head->olut); if (ret) goto out; } diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.h b/drivers/gpu/drm/nouveau/dispnv50/head.h index d00cebdbd2600..0802271bc90cc 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.h +++ b/drivers/gpu/drm/nouveau/dispnv50/head.h @@ -3,16 +3,14 @@ #define nv50_head(c) container_of((c), struct nv50_head, base.base) #include "disp.h" #include "atom.h" +#include "lut.h" #include "nouveau_crtc.h" struct nv50_head { const struct nv50_head_func *func; struct nouveau_crtc base; - struct { - struct nouveau_bo *nvbo[2]; - int next; - } ilut; + struct nv50_lut olut; }; int nv50_head_create(struct drm_device *, int index); @@ -22,8 +20,9 @@ void nv50_head_flush_clr(struct nv50_head *, struct nv50_head_atom *, bool y); struct nv50_head_func { void (*view)(struct nv50_head *, struct nv50_head_atom *); void (*mode)(struct nv50_head *, struct nv50_head_atom *); - void (*ilut_set)(struct nv50_head *, struct nv50_head_atom *); - void (*ilut_clr)(struct nv50_head *); + void (*olut)(struct nv50_head *, struct nv50_head_atom *); + void (*olut_set)(struct nv50_head *, struct nv50_head_atom *); + void (*olut_clr)(struct nv50_head *); void (*core_calc)(struct nv50_head *, struct nv50_head_atom *); void (*core_set)(struct nv50_head *, struct nv50_head_atom *); void (*core_clr)(struct nv50_head *); @@ -39,6 +38,7 @@ struct nv50_head_func { extern const struct nv50_head_func head507d; void head507d_view(struct nv50_head *, struct nv50_head_atom *); void head507d_mode(struct nv50_head *, struct nv50_head_atom *); +void head507d_olut(struct nv50_head *, struct nv50_head_atom *); void head507d_core_calc(struct nv50_head *, struct nv50_head_atom *); void head507d_core_clr(struct nv50_head *); void head507d_base(struct nv50_head *, struct nv50_head_atom *); @@ -51,13 +51,13 @@ extern const struct nv50_head_func head827d; extern const struct nv50_head_func head907d; void head907d_view(struct nv50_head *, struct nv50_head_atom *); void head907d_mode(struct nv50_head *, struct nv50_head_atom *); -void head907d_ilut_set(struct nv50_head *, struct nv50_head_atom *); -void head907d_ilut_clr(struct nv50_head *); +void head907d_olut(struct nv50_head *, struct nv50_head_atom *); +void head907d_olut_set(struct nv50_head *, struct nv50_head_atom *); +void head907d_olut_clr(struct nv50_head *); void head907d_core_set(struct nv50_head *, struct nv50_head_atom *); void head907d_core_clr(struct nv50_head *); void head907d_curs_set(struct nv50_head *, struct nv50_head_atom *); void head907d_curs_clr(struct nv50_head *); -void head907d_base(struct nv50_head *, struct nv50_head_atom *); void head907d_ovly(struct nv50_head *, struct nv50_head_atom *); void head907d_procamp(struct nv50_head *, struct nv50_head_atom *); void head907d_or(struct nv50_head *, struct nv50_head_atom *); diff --git a/drivers/gpu/drm/nouveau/dispnv50/head507d.c b/drivers/gpu/drm/nouveau/dispnv50/head507d.c index 5f06fa174832f..75575c33c5d67 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head507d.c @@ -165,6 +165,7 @@ head507d_core_set(struct nv50_head *head, struct nv50_head_atom *asyh) * without also updating HeadSetOffsetCursor. */ asyh->set.curs = asyh->curs.visible; + asyh->set.olut = asyh->olut.handle != 0; } } @@ -178,8 +179,8 @@ head507d_core_calc(struct nv50_head *head, struct nv50_head_atom *asyh) asyh->core.w = asyh->base.w; asyh->core.h = asyh->base.h; } else - if ((asyh->core.visible = asyh->curs.visible) || - (asyh->core.visible = asyh->ilut.visible)) { + if ((asyh->core.visible = (asyh->ovly.cpp != 0)) || + (asyh->core.visible = asyh->curs.visible)) { /*XXX: We need to either find some way of having the * primary base layer appear black, while still * being able to display the other layers, or we @@ -200,30 +201,39 @@ head507d_core_calc(struct nv50_head *head, struct nv50_head_atom *asyh) } static void -head507d_ilut_clr(struct nv50_head *head) +head507d_olut_clr(struct nv50_head *head) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if ((push = evo_wait(core, 2))) { evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1); - evo_data(push, 0x40000000); + evo_data(push, 0x00000000); evo_kick(push, core); } } static void -head507d_ilut_set(struct nv50_head *head, struct nv50_head_atom *asyh) +head507d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if ((push = evo_wait(core, 3))) { evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2); - evo_data(push, 0x80000000 | asyh->ilut.mode << 30); - evo_data(push, asyh->ilut.offset >> 8); + evo_data(push, 0x80000000 | asyh->olut.mode << 30); + evo_data(push, asyh->olut.offset >> 8); evo_kick(push, core); } } +void +head507d_olut(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + if (asyh->base.cpp == 1) + asyh->olut.mode = 0; + else + asyh->olut.mode = 1; +} + void head507d_mode(struct nv50_head *head, struct nv50_head_atom *asyh) { @@ -269,8 +279,9 @@ const struct nv50_head_func head507d = { .view = head507d_view, .mode = head507d_mode, - .ilut_set = head507d_ilut_set, - .ilut_clr = head507d_ilut_clr, + .olut = head507d_olut, + .olut_set = head507d_olut_set, + .olut_clr = head507d_olut_clr, .core_calc = head507d_core_calc, .core_set = head507d_core_set, .core_clr = head507d_core_clr, diff --git a/drivers/gpu/drm/nouveau/dispnv50/head827d.c b/drivers/gpu/drm/nouveau/dispnv50/head827d.c index 84ce595fbe793..ddc143bac3055 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head827d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head827d.c @@ -74,13 +74,13 @@ head827d_core_set(struct nv50_head *head, struct nv50_head_atom *asyh) } static void -head827d_ilut_clr(struct nv50_head *head) +head827d_olut_clr(struct nv50_head *head) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if ((push = evo_wait(core, 4))) { evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1); - evo_data(push, 0x40000000); + evo_data(push, 0x00000000); evo_mthd(push, 0x085c + (head->base.index * 0x400), 1); evo_data(push, 0x00000000); evo_kick(push, core); @@ -88,16 +88,16 @@ head827d_ilut_clr(struct nv50_head *head) } static void -head827d_ilut_set(struct nv50_head *head, struct nv50_head_atom *asyh) +head827d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if ((push = evo_wait(core, 5))) { evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2); - evo_data(push, 0x80000000 | asyh->ilut.mode << 30); - evo_data(push, asyh->ilut.offset >> 8); + evo_data(push, 0x80000000 | asyh->olut.mode << 30); + evo_data(push, asyh->olut.offset >> 8); evo_mthd(push, 0x085c + (head->base.index * 0x400), 1); - evo_data(push, asyh->ilut.handle); + evo_data(push, asyh->olut.handle); evo_kick(push, core); } } @@ -106,8 +106,9 @@ const struct nv50_head_func head827d = { .view = head507d_view, .mode = head507d_mode, - .ilut_set = head827d_ilut_set, - .ilut_clr = head827d_ilut_clr, + .olut = head507d_olut, + .olut_set = head827d_olut_set, + .olut_clr = head827d_olut_clr, .core_calc = head507d_core_calc, .core_set = head827d_core_set, .core_clr = head507d_core_clr, diff --git a/drivers/gpu/drm/nouveau/dispnv50/head907d.c b/drivers/gpu/drm/nouveau/dispnv50/head907d.c index 0035eccd62d61..0fa0159bfafb8 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head907d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head907d.c @@ -91,7 +91,7 @@ head907d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh) } } -void +static void head907d_base(struct nv50_head *head, struct nv50_head_atom *asyh) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; @@ -182,13 +182,13 @@ head907d_core_set(struct nv50_head *head, struct nv50_head_atom *asyh) } void -head907d_ilut_clr(struct nv50_head *head) +head907d_olut_clr(struct nv50_head *head) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; if ((push = evo_wait(core, 4))) { - evo_mthd(push, 0x0440 + (head->base.index * 0x300), 1); - evo_data(push, 0x03000000); + evo_mthd(push, 0x0448 + (head->base.index * 0x300), 1); + evo_data(push, 0x00000000); evo_mthd(push, 0x045c + (head->base.index * 0x300), 1); evo_data(push, 0x00000000); evo_kick(push, core); @@ -196,22 +196,26 @@ head907d_ilut_clr(struct nv50_head *head) } void -head907d_ilut_set(struct nv50_head *head, struct nv50_head_atom *asyh) +head907d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh) { struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; u32 *push; - if ((push = evo_wait(core, 7))) { - evo_mthd(push, 0x0440 + (head->base.index * 0x300), 4); - evo_data(push, 0x80000000 | asyh->ilut.mode << 24); - evo_data(push, asyh->ilut.offset >> 8); - evo_data(push, 0x00000000); - evo_data(push, 0x00000000); + if ((push = evo_wait(core, 5))) { + evo_mthd(push, 0x0448 + (head->base.index * 0x300), 2); + evo_data(push, 0x80000000 | asyh->olut.mode << 24); + evo_data(push, asyh->olut.offset >> 8); evo_mthd(push, 0x045c + (head->base.index * 0x300), 1); - evo_data(push, asyh->ilut.handle); + evo_data(push, asyh->olut.handle); evo_kick(push, core); } } +void +head907d_olut(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + asyh->olut.mode = 7; +} + void head907d_mode(struct nv50_head *head, struct nv50_head_atom *asyh) { @@ -259,8 +263,9 @@ const struct nv50_head_func head907d = { .view = head907d_view, .mode = head907d_mode, - .ilut_set = head907d_ilut_set, - .ilut_clr = head907d_ilut_clr, + .olut = head907d_olut, + .olut_set = head907d_olut_set, + .olut_clr = head907d_olut_clr, .core_calc = head507d_core_calc, .core_set = head907d_core_set, .core_clr = head907d_core_clr, diff --git a/drivers/gpu/drm/nouveau/dispnv50/head917d.c b/drivers/gpu/drm/nouveau/dispnv50/head917d.c index 5341ea3bc7b60..5f654512c8c26 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head917d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head917d.c @@ -36,18 +36,46 @@ head917d_dither(struct nv50_head *head, struct nv50_head_atom *asyh) } } +static void +head917d_base(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 bounds = 0; + u32 *push; + + if (asyh->base.cpp) { + switch (asyh->base.cpp) { + case 8: bounds |= 0x00000500; break; + case 4: bounds |= 0x00000300; break; + case 2: bounds |= 0x00000100; break; + case 1: bounds |= 0x00000000; break; + default: + WARN_ON(1); + break; + } + bounds |= 0x00020001; + } + + if ((push = evo_wait(core, 2))) { + evo_mthd(push, 0x04d0 + head->base.index * 0x300, 1); + evo_data(push, bounds); + evo_kick(push, core); + } +} + const struct nv50_head_func head917d = { .view = head907d_view, .mode = head907d_mode, - .ilut_set = head907d_ilut_set, - .ilut_clr = head907d_ilut_clr, + .olut = head907d_olut, + .olut_set = head907d_olut_set, + .olut_clr = head907d_olut_clr, .core_calc = head507d_core_calc, .core_set = head907d_core_set, .core_clr = head907d_core_clr, .curs_set = head907d_curs_set, .curs_clr = head907d_curs_clr, - .base = head907d_base, + .base = head917d_base, .ovly = head907d_ovly, .dither = head917d_dither, .procamp = head907d_procamp, diff --git a/drivers/gpu/drm/nouveau/dispnv50/lut.c b/drivers/gpu/drm/nouveau/dispnv50/lut.c new file mode 100644 index 0000000000000..a6b96ae2a22f8 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/lut.c @@ -0,0 +1,95 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "lut.h" +#include "disp.h" + +#include +#include +#include + +#include + +u32 +nv50_lut_load(struct nv50_lut *lut, bool legacy, int buffer, + struct drm_property_blob *blob) +{ + struct drm_color_lut *in = (struct drm_color_lut *)blob->data; + void __iomem *mem = lut->mem[buffer].object.map.ptr; + const int size = blob->length / sizeof(*in); + int bits, shift, i; + u16 zero, r, g, b; + u32 addr = lut->mem[buffer].addr; + + /* This can't happen.. But it shuts the compiler up. */ + if (WARN_ON(size != 256)) + return 0; + + if (legacy) { + bits = 11; + shift = 3; + zero = 0x0000; + } else { + bits = 14; + shift = 0; + zero = 0x6000; + } + + for (i = 0; i < size; i++) { + r = (drm_color_lut_extract(in[i]. red, bits) + zero) << shift; + g = (drm_color_lut_extract(in[i].green, bits) + zero) << shift; + b = (drm_color_lut_extract(in[i]. blue, bits) + zero) << shift; + writew(r, mem + (i * 0x08) + 0); + writew(g, mem + (i * 0x08) + 2); + writew(b, mem + (i * 0x08) + 4); + } + + /* INTERPOLATE modes require a "next" entry to interpolate with, + * so we replicate the last entry to deal with this for now. + */ + writew(r, mem + (i * 0x08) + 0); + writew(g, mem + (i * 0x08) + 2); + writew(b, mem + (i * 0x08) + 4); + return addr; +} + +void +nv50_lut_fini(struct nv50_lut *lut) +{ + int i; + for (i = 0; i < ARRAY_SIZE(lut->mem); i++) + nvif_mem_fini(&lut->mem[i]); +} + +int +nv50_lut_init(struct nv50_disp *disp, struct nvif_mmu *mmu, + struct nv50_lut *lut) +{ + const u32 size = disp->disp->object.oclass < GF110_DISP ? 257 : 1025; + int i; + for (i = 0; i < ARRAY_SIZE(lut->mem); i++) { + int ret = nvif_mem_init_map(mmu, NVIF_MEM_VRAM, size * 8, + &lut->mem[i]); + if (ret) + return ret; + } + return 0; +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/lut.h b/drivers/gpu/drm/nouveau/dispnv50/lut.h new file mode 100644 index 0000000000000..6d7b8352e4cb2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/lut.h @@ -0,0 +1,15 @@ +#ifndef __NV50_KMS_LUT_H__ +#define __NV50_KMS_LUT_H__ +#include +struct drm_property_blob; +struct nv50_disp; + +struct nv50_lut { + struct nvif_mem mem[2]; +}; + +int nv50_lut_init(struct nv50_disp *, struct nvif_mmu *, struct nv50_lut *); +void nv50_lut_fini(struct nv50_lut *); +u32 nv50_lut_load(struct nv50_lut *, bool legacy, int buffer, + struct drm_property_blob *); +#endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index 0f6de6049be44..fbaf8b7ed203a 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -116,6 +116,7 @@ nv50_wndw_flush_clr(struct nv50_wndw *wndw, u32 *interlock, bool flush, }; if (clr.sema ) wndw->func-> sema_clr(wndw); if (clr.ntfy ) wndw->func-> ntfy_clr(wndw); + if (clr.xlut ) wndw->func-> xlut_clr(wndw); if (clr.image) wndw->func->image_clr(wndw); interlock[wndw->interlock.type] |= wndw->interlock.data; @@ -133,7 +134,18 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock, if (asyw->set.sema ) wndw->func->sema_set (wndw, asyw); if (asyw->set.ntfy ) wndw->func->ntfy_set (wndw, asyw); if (asyw->set.image) wndw->func->image_set(wndw, asyw); - if (asyw->set.lut ) wndw->func->lut (wndw, asyw); + + if (asyw->set.xlut ) { + if (asyw->ilut) { + asyw->xlut.i.offset = + nv50_lut_load(&wndw->ilut, + asyw->xlut.i.mode <= 1, + asyw->xlut.i.buffer, + asyw->ilut); + } + wndw->func->xlut_set(wndw, asyw); + } + if (asyw->set.point) { wndw->immd->point(wndw, asyw); wndw->immd->update(wndw, interlock); @@ -241,7 +253,56 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, return wndw->func->acquire(wndw, asyw, asyh); } -int +static void +nv50_wndw_atomic_check_lut(struct nv50_wndw *wndw, + struct nv50_wndw_atom *armw, + struct nv50_wndw_atom *asyw, + struct nv50_head_atom *asyh) +{ + struct drm_property_blob *ilut = asyh->state.degamma_lut; + + /* I8 format without an input LUT makes no sense, and the + * HW error-checks for this. + * + * In order to handle legacy gamma, when there's no input + * LUT we need to steal the output LUT and use it instead. + */ + if (!ilut && asyw->state.fb->format->format == DRM_FORMAT_C8) { + /* This should be an error, but there's legacy clients + * that do a modeset before providing a gamma table. + * + * We keep the window disabled to avoid angering HW. + */ + if (!(ilut = asyh->state.gamma_lut)) { + asyw->visible = false; + return; + } + + if (wndw->func->ilut) + asyh->wndw.olut |= BIT(wndw->id); + } else { + asyh->wndw.olut &= ~BIT(wndw->id); + } + + /* Recalculate LUT state. */ + memset(&asyw->xlut, 0x00, sizeof(asyw->xlut)); + if ((asyw->ilut = wndw->func->ilut ? ilut : NULL)) { + wndw->func->ilut(wndw, asyw); + asyw->xlut.handle = wndw->wndw.vram.handle; + asyw->xlut.i.buffer = !asyw->xlut.i.buffer; + asyw->set.xlut = true; + } + + /* Handle setting base SET_OUTPUT_LUT_LO_ENABLE_USE_CORE_LUT. */ + if (wndw->func->olut_core && + (!armw->visible || (armw->xlut.handle && !asyw->xlut.handle))) + asyw->set.xlut = true; + + /* Can't do an immediate flip while changing the LUT. */ + asyh->state.pageflip_flags &= ~DRM_MODE_PAGE_FLIP_ASYNC; +} + +static int nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { struct nouveau_drm *drm = nouveau_drm(plane->dev); @@ -274,15 +335,26 @@ nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) return PTR_ERR(harm); } + /* LUT configuration can potentially cause the window to be disabled. */ + if (asyw->visible && wndw->func->xlut_set && + (!armw->visible || + asyh->state.color_mgmt_changed || + asyw->state.fb->format->format != + armw->state.fb->format->format)) + nv50_wndw_atomic_check_lut(wndw, armw, asyw, asyh); + /* Calculate new window state. */ if (asyw->visible) { ret = nv50_wndw_atomic_check_acquire(wndw, modeset, armw, asyw, asyh); if (ret) return ret; + + asyh->wndw.mask |= BIT(wndw->id); } else if (armw->visible) { nv50_wndw_atomic_check_release(wndw, asyw, harm); + harm->wndw.mask &= ~BIT(wndw->id); } else { return 0; } @@ -294,9 +366,9 @@ nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) if (!asyw->visible || modeset) { asyw->clr.ntfy = armw->ntfy.handle != 0; asyw->clr.sema = armw->sema.handle != 0; + asyw->clr.xlut = armw->xlut.handle != 0; if (wndw->func->image_clr) asyw->clr.image = armw->image.handle[0] != 0; - asyw->set.lut = wndw->func->lut && asyw->visible; } return 0; @@ -381,9 +453,10 @@ nv50_wndw_atomic_duplicate_state(struct drm_plane *plane) __drm_atomic_helper_plane_duplicate_state(plane, &asyw->state); asyw->sema = armw->sema; asyw->ntfy = armw->ntfy; + asyw->ilut = NULL; + asyw->xlut = armw->xlut; asyw->image = armw->image; asyw->point = armw->point; - asyw->lut = armw->lut; asyw->clr.mask = 0; asyw->set.mask = 0; return &asyw->state; @@ -417,6 +490,9 @@ nv50_wndw_destroy(struct drm_plane *plane) nvif_notify_fini(&wndw->notify); nv50_dmac_destroy(&wndw->wimm); nv50_dmac_destroy(&wndw->wndw); + + nv50_lut_fini(&wndw->ilut); + drm_plane_cleanup(&wndw->plane); kfree(wndw); } @@ -456,6 +532,9 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, enum nv50_disp_interlock_type interlock_type, u32 interlock_data, struct nv50_wndw **pwndw) { + struct nouveau_drm *drm = nouveau_drm(dev); + struct nvif_mmu *mmu = &drm->client.mmu; + struct nv50_disp *disp = nv50_disp(dev); struct nv50_wndw *wndw; int nformat; int ret; @@ -484,6 +563,12 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, drm_plane_helper_add(&wndw->plane, &nv50_wndw_helper); + if (wndw->func->ilut) { + ret = nv50_lut_init(disp, mmu, &wndw->ilut); + if (ret) + return ret; + } + wndw->notify.func = nv50_wndw_notify; return 0; } diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.h b/drivers/gpu/drm/nouveau/dispnv50/wndw.h index c26796c612f6b..223cf3f37dae3 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.h +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.h @@ -3,6 +3,7 @@ #define nv50_wndw(p) container_of((p), struct nv50_wndw, plane) #include "disp.h" #include "atom.h" +#include "lut.h" #include @@ -24,6 +25,8 @@ struct nv50_wndw { struct drm_plane plane; + struct nv50_lut ilut; + struct nv50_dmac wndw; struct nv50_dmac wimm; @@ -61,9 +64,12 @@ struct nv50_wndw_func { void (*ntfy_clr)(struct nv50_wndw *); int (*ntfy_wait_begun)(struct nouveau_bo *, u32 offset, struct nvif_device *); + void (*ilut)(struct nv50_wndw *, struct nv50_wndw_atom *); + bool olut_core; + void (*xlut_set)(struct nv50_wndw *, struct nv50_wndw_atom *); + void (*xlut_clr)(struct nv50_wndw *); void (*image_set)(struct nv50_wndw *, struct nv50_wndw_atom *); void (*image_clr)(struct nv50_wndw *); - void (*lut)(struct nv50_wndw *, struct nv50_wndw_atom *); void (*update)(struct nv50_wndw *, u32 *interlock); }; From b05d873808c77fedd25130b0355acc0da1c11e19 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 129/165] drm/nouveau/kms/nv50-: separate blocklinear vs linear pitch Will be required to support Volta. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/atom.h | 6 ++++-- drivers/gpu/drm/nouveau/dispnv50/base507c.c | 5 +++-- drivers/gpu/drm/nouveau/dispnv50/base827c.c | 5 +++-- drivers/gpu/drm/nouveau/dispnv50/base907c.c | 5 +++-- drivers/gpu/drm/nouveau/dispnv50/head507d.c | 8 +++++--- drivers/gpu/drm/nouveau/dispnv50/head827d.c | 3 ++- drivers/gpu/drm/nouveau/dispnv50/head907d.c | 3 ++- drivers/gpu/drm/nouveau/dispnv50/wndw.c | 10 ++++++---- 8 files changed, 28 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/atom.h b/drivers/gpu/drm/nouveau/dispnv50/atom.h index 3e9e8832d0dd1..0409947bf1962 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/atom.h +++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h @@ -63,7 +63,8 @@ struct nv50_head_atom { u8 format; u8 kind:7; u8 layout:1; - u8 block:4; + u8 blockh:4; + u16 blocks:12; u32 pitch:20; u16 x; u16 y; @@ -175,7 +176,8 @@ struct nv50_wndw_atom { u8 format; u8 kind:7; u8 layout:1; - u8 block:4; + u8 blockh:4; + u16 blocks[3]; u32 pitch[3]; u16 w; u16 h; diff --git a/drivers/gpu/drm/nouveau/dispnv50/base507c.c b/drivers/gpu/drm/nouveau/dispnv50/base507c.c index 5d664d75b6451..d5e295ca2caa5 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base507c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base507c.c @@ -67,8 +67,9 @@ base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) evo_data(push, 0x00000000); evo_data(push, asyw->image.h << 16 | asyw->image.w); evo_data(push, asyw->image.layout << 20 | - asyw->image.pitch[0] | - asyw->image.block); + (asyw->image.pitch[0] >> 8) << 8 | + asyw->image.blocks[0] << 8 | + asyw->image.blockh); evo_data(push, asyw->image.kind << 16 | asyw->image.format << 8); evo_kick(push, &wndw->wndw); diff --git a/drivers/gpu/drm/nouveau/dispnv50/base827c.c b/drivers/gpu/drm/nouveau/dispnv50/base827c.c index d886858a57240..73646819a0d68 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base827c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base827c.c @@ -36,8 +36,9 @@ base827c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) evo_data(push, 0x00000000); evo_data(push, asyw->image.h << 16 | asyw->image.w); evo_data(push, asyw->image.layout << 20 | - asyw->image.pitch[0] | - asyw->image.block); + (asyw->image.pitch[0] >> 8) << 8 | + asyw->image.blocks[0] << 8 | + asyw->image.blockh); evo_data(push, asyw->image.format << 8); evo_kick(push, &wndw->wndw); } diff --git a/drivers/gpu/drm/nouveau/dispnv50/base907c.c b/drivers/gpu/drm/nouveau/dispnv50/base907c.c index 2643592ad827c..8edc0598bda83 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base907c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base907c.c @@ -36,8 +36,9 @@ base907c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) evo_data(push, 0x00000000); evo_data(push, asyw->image.h << 16 | asyw->image.w); evo_data(push, asyw->image.layout << 24 | - asyw->image.pitch[0] | - asyw->image.block); + (asyw->image.pitch[0] >> 8) << 8 | + asyw->image.blocks[0] << 8 | + asyw->image.blockh); evo_data(push, asyw->image.format << 8); evo_kick(push, &wndw->wndw); } diff --git a/drivers/gpu/drm/nouveau/dispnv50/head507d.c b/drivers/gpu/drm/nouveau/dispnv50/head507d.c index 75575c33c5d67..8a8aa9b69ef83 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head507d.c @@ -151,8 +151,9 @@ head507d_core_set(struct nv50_head *head, struct nv50_head_atom *asyh) evo_mthd(push, 0x0868 + head->base.index * 0x400, 4); evo_data(push, asyh->core.h << 16 | asyh->core.w); evo_data(push, asyh->core.layout << 20 | - asyh->core.pitch >> 8 << 8 | - asyh->core.block); + (asyh->core.pitch >> 8) << 8 | + asyh->core.blocks << 8 | + asyh->core.blockh); evo_data(push, asyh->core.kind << 16 | asyh->core.format << 8); evo_data(push, asyh->core.handle); @@ -196,7 +197,8 @@ head507d_core_calc(struct nv50_head *head, struct nv50_head_atom *asyh) asyh->core.format = 0xcf; asyh->core.kind = 0; asyh->core.layout = 1; - asyh->core.block = 0; + asyh->core.blockh = 0; + asyh->core.blocks = 0; asyh->core.pitch = ALIGN(asyh->core.w, 64) * 4; } diff --git a/drivers/gpu/drm/nouveau/dispnv50/head827d.c b/drivers/gpu/drm/nouveau/dispnv50/head827d.c index ddc143bac3055..ae33e21790ee7 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head827d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head827d.c @@ -64,7 +64,8 @@ head827d_core_set(struct nv50_head *head, struct nv50_head_atom *asyh) evo_data(push, asyh->core.h << 16 | asyh->core.w); evo_data(push, asyh->core.layout << 20 | (asyh->core.pitch >> 8) << 8 | - asyh->core.block); + asyh->core.blocks << 8 | + asyh->core.blockh); evo_data(push, asyh->core.format << 8); evo_data(push, asyh->core.handle); evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1); diff --git a/drivers/gpu/drm/nouveau/dispnv50/head907d.c b/drivers/gpu/drm/nouveau/dispnv50/head907d.c index 0fa0159bfafb8..a05dfccadcfa6 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head907d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head907d.c @@ -172,7 +172,8 @@ head907d_core_set(struct nv50_head *head, struct nv50_head_atom *asyh) evo_data(push, asyh->core.h << 16 | asyh->core.w); evo_data(push, asyh->core.layout << 24 | (asyh->core.pitch >> 8) << 8 | - asyh->core.block); + asyh->core.blocks << 8 | + asyh->core.blockh); evo_data(push, asyh->core.format << 8); evo_data(push, asyh->core.handle); evo_mthd(push, 0x04b0 + head->base.index * 0x300, 1); diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index fbaf8b7ed203a..b96dc3d4dab59 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -225,13 +225,15 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, if (asyw->image.kind) { asyw->image.layout = 0; if (drm->client.device.info.chipset >= 0xc0) - asyw->image.block = fb->nvbo->mode >> 4; + asyw->image.blockh = fb->nvbo->mode >> 4; else - asyw->image.block = fb->nvbo->mode; - asyw->image.pitch[0] = (fb->base.pitches[0] / 4) << 4; + asyw->image.blockh = fb->nvbo->mode; + asyw->image.blocks[0] = fb->base.pitches[0] / 64; + asyw->image.pitch[0] = 0; } else { asyw->image.layout = 1; - asyw->image.block = 0; + asyw->image.blockh = 0; + asyw->image.blocks[0] = 0; asyw->image.pitch[0] = fb->base.pitches[0]; } From 01d380ab4f702fffa6da60c4b006547b8dd66de8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 130/165] drm/nouveau/kms/gk104-: support additional cursor sizes Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/atom.h | 2 +- drivers/gpu/drm/nouveau/dispnv50/curs507a.c | 22 ++++++---------- drivers/gpu/drm/nouveau/dispnv50/head.h | 8 ++++++ drivers/gpu/drm/nouveau/dispnv50/head507d.c | 28 +++++++++++++++++++++ drivers/gpu/drm/nouveau/dispnv50/head827d.c | 2 ++ drivers/gpu/drm/nouveau/dispnv50/head907d.c | 2 ++ drivers/gpu/drm/nouveau/dispnv50/head917d.c | 17 +++++++++++++ 7 files changed, 65 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/atom.h b/drivers/gpu/drm/nouveau/dispnv50/atom.h index 0409947bf1962..3d059df78322b 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/atom.h +++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h @@ -76,7 +76,7 @@ struct nv50_head_atom { bool visible; u32 handle; u64 offset:40; - u8 layout:1; + u8 layout:2; u8 format:1; } curs; diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c index ba05bcb13ae79..291c08117ab65 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c +++ b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c @@ -21,6 +21,7 @@ */ #include "curs.h" #include "core.h" +#include "head.h" #include @@ -70,6 +71,7 @@ static int curs507a_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, struct nv50_head_atom *asyh) { + struct nv50_head *head = nv50_head(asyw->state.crtc); int ret; ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state, @@ -80,24 +82,14 @@ curs507a_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, if (ret || !asyh->curs.visible) return ret; - switch (asyw->state.fb->width) { - case 32: asyh->curs.layout = 0; break; - case 64: asyh->curs.layout = 1; break; - default: - return -EINVAL; - } - - if (asyw->state.fb->width != asyw->state.fb->height) + if (asyw->image.w != asyw->image.h) return -EINVAL; - switch (asyw->image.format) { - case 0xcf: asyh->curs.format = 1; break; - default: - WARN_ON(1); - return -EINVAL; - } + ret = head->func->curs_layout(head, asyw, asyh); + if (ret) + return ret; - return 0; + return head->func->curs_format(head, asyw, asyh); } static const u32 diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.h b/drivers/gpu/drm/nouveau/dispnv50/head.h index 0802271bc90cc..8f2c3ffa4e610 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.h +++ b/drivers/gpu/drm/nouveau/dispnv50/head.h @@ -26,6 +26,10 @@ struct nv50_head_func { void (*core_calc)(struct nv50_head *, struct nv50_head_atom *); void (*core_set)(struct nv50_head *, struct nv50_head_atom *); void (*core_clr)(struct nv50_head *); + int (*curs_layout)(struct nv50_head *, struct nv50_wndw_atom *, + struct nv50_head_atom *); + int (*curs_format)(struct nv50_head *, struct nv50_wndw_atom *, + struct nv50_head_atom *); void (*curs_set)(struct nv50_head *, struct nv50_head_atom *); void (*curs_clr)(struct nv50_head *); void (*base)(struct nv50_head *, struct nv50_head_atom *); @@ -41,6 +45,10 @@ void head507d_mode(struct nv50_head *, struct nv50_head_atom *); void head507d_olut(struct nv50_head *, struct nv50_head_atom *); void head507d_core_calc(struct nv50_head *, struct nv50_head_atom *); void head507d_core_clr(struct nv50_head *); +int head507d_curs_layout(struct nv50_head *, struct nv50_wndw_atom *, + struct nv50_head_atom *); +int head507d_curs_format(struct nv50_head *, struct nv50_wndw_atom *, + struct nv50_head_atom *); void head507d_base(struct nv50_head *, struct nv50_head_atom *); void head507d_ovly(struct nv50_head *, struct nv50_head_atom *); void head507d_dither(struct nv50_head *, struct nv50_head_atom *); diff --git a/drivers/gpu/drm/nouveau/dispnv50/head507d.c b/drivers/gpu/drm/nouveau/dispnv50/head507d.c index 8a8aa9b69ef83..5b6a280ab804c 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head507d.c @@ -128,6 +128,32 @@ head507d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh) } } +int +head507d_curs_format(struct nv50_head *head, struct nv50_wndw_atom *asyw, + struct nv50_head_atom *asyh) +{ + switch (asyw->image.format) { + case 0xcf: asyh->curs.format = 1; break; + default: + WARN_ON(1); + return -EINVAL; + } + return 0; +} + +int +head507d_curs_layout(struct nv50_head *head, struct nv50_wndw_atom *asyw, + struct nv50_head_atom *asyh) +{ + switch (asyw->image.w) { + case 32: asyh->curs.layout = 0; break; + case 64: asyh->curs.layout = 1; break; + default: + return -EINVAL; + } + return 0; +} + void head507d_core_clr(struct nv50_head *head) { @@ -287,6 +313,8 @@ head507d = { .core_calc = head507d_core_calc, .core_set = head507d_core_set, .core_clr = head507d_core_clr, + .curs_layout = head507d_curs_layout, + .curs_format = head507d_curs_format, .curs_set = head507d_curs_set, .curs_clr = head507d_curs_clr, .base = head507d_base, diff --git a/drivers/gpu/drm/nouveau/dispnv50/head827d.c b/drivers/gpu/drm/nouveau/dispnv50/head827d.c index ae33e21790ee7..af5e7bd5978bf 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head827d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head827d.c @@ -113,6 +113,8 @@ head827d = { .core_calc = head507d_core_calc, .core_set = head827d_core_set, .core_clr = head507d_core_clr, + .curs_layout = head507d_curs_layout, + .curs_format = head507d_curs_format, .curs_set = head827d_curs_set, .curs_clr = head827d_curs_clr, .base = head507d_base, diff --git a/drivers/gpu/drm/nouveau/dispnv50/head907d.c b/drivers/gpu/drm/nouveau/dispnv50/head907d.c index a05dfccadcfa6..c09620f540f9f 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head907d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head907d.c @@ -270,6 +270,8 @@ head907d = { .core_calc = head507d_core_calc, .core_set = head907d_core_set, .core_clr = head907d_core_clr, + .curs_layout = head507d_curs_layout, + .curs_format = head507d_curs_format, .curs_set = head907d_curs_set, .curs_clr = head907d_curs_clr, .base = head907d_base, diff --git a/drivers/gpu/drm/nouveau/dispnv50/head917d.c b/drivers/gpu/drm/nouveau/dispnv50/head917d.c index 5f654512c8c26..4c019a4417ea1 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head917d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head917d.c @@ -63,6 +63,21 @@ head917d_base(struct nv50_head *head, struct nv50_head_atom *asyh) } } +static int +head917d_curs_layout(struct nv50_head *head, struct nv50_wndw_atom *asyw, + struct nv50_head_atom *asyh) +{ + switch (asyw->state.fb->width) { + case 32: asyh->curs.layout = 0; break; + case 64: asyh->curs.layout = 1; break; + case 128: asyh->curs.layout = 2; break; + case 256: asyh->curs.layout = 3; break; + default: + return -EINVAL; + } + return 0; +} + const struct nv50_head_func head917d = { .view = head907d_view, @@ -73,6 +88,8 @@ head917d = { .core_calc = head507d_core_calc, .core_set = head907d_core_set, .core_clr = head907d_core_clr, + .curs_layout = head917d_curs_layout, + .curs_format = head507d_curs_format, .curs_set = head907d_curs_set, .curs_clr = head907d_curs_clr, .base = head917d_base, From 88b600d421a5550cd56e13f2eda34cbefe417c28 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 131/165] drm/nouveau/kms/gk104-: add support for [XA]2R10G10B10 formats Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/Kbuild | 1 + drivers/gpu/drm/nouveau/dispnv50/base.c | 4 +- drivers/gpu/drm/nouveau/dispnv50/base.h | 3 ++ drivers/gpu/drm/nouveau/dispnv50/base907c.c | 2 +- drivers/gpu/drm/nouveau/dispnv50/base917c.c | 48 +++++++++++++++++++++ drivers/gpu/drm/nouveau/dispnv50/wndw.c | 2 + 6 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/dispnv50/base917c.c diff --git a/drivers/gpu/drm/nouveau/dispnv50/Kbuild b/drivers/gpu/drm/nouveau/dispnv50/Kbuild index d074bb8ecd1be..7c337fd801587 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/Kbuild +++ b/drivers/gpu/drm/nouveau/dispnv50/Kbuild @@ -27,6 +27,7 @@ nouveau-y += dispnv50/base.o nouveau-y += dispnv50/base507c.o nouveau-y += dispnv50/base827c.o nouveau-y += dispnv50/base907c.o +nouveau-y += dispnv50/base917c.o nouveau-y += dispnv50/curs.o nouveau-y += dispnv50/curs507a.o diff --git a/drivers/gpu/drm/nouveau/dispnv50/base.c b/drivers/gpu/drm/nouveau/dispnv50/base.c index 5f184ab833e80..7c752acf2b48d 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base.c @@ -31,8 +31,8 @@ nv50_base_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) int version; int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); } bases[] = { - { GK110_DISP_BASE_CHANNEL_DMA, 0, base907c_new }, - { GK104_DISP_BASE_CHANNEL_DMA, 0, base907c_new }, + { GK110_DISP_BASE_CHANNEL_DMA, 0, base917c_new }, + { GK104_DISP_BASE_CHANNEL_DMA, 0, base917c_new }, { GF110_DISP_BASE_CHANNEL_DMA, 0, base907c_new }, { GT214_DISP_BASE_CHANNEL_DMA, 0, base827c_new }, { GT200_DISP_BASE_CHANNEL_DMA, 0, base827c_new }, diff --git a/drivers/gpu/drm/nouveau/dispnv50/base.h b/drivers/gpu/drm/nouveau/dispnv50/base.h index 87ec8394b7f3c..7afd9e26f9f96 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base.h +++ b/drivers/gpu/drm/nouveau/dispnv50/base.h @@ -25,6 +25,9 @@ void base507c_update(struct nv50_wndw *, u32 *); int base827c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); int base907c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); +extern const struct nv50_wndw_func base907c; + +int base917c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); int nv50_base_new(struct nouveau_drm *, int head, struct nv50_wndw **); #endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/base907c.c b/drivers/gpu/drm/nouveau/dispnv50/base907c.c index 8edc0598bda83..a562fc94ce599 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base907c.c +++ b/drivers/gpu/drm/nouveau/dispnv50/base907c.c @@ -82,7 +82,7 @@ base907c_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) asyw->xlut.i.enable = 2; } -static const struct nv50_wndw_func +const struct nv50_wndw_func base907c = { .acquire = base507c_acquire, .release = base507c_release, diff --git a/drivers/gpu/drm/nouveau/dispnv50/base917c.c b/drivers/gpu/drm/nouveau/dispnv50/base917c.c new file mode 100644 index 0000000000000..54d705bb81a5d --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/base917c.c @@ -0,0 +1,48 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "base.h" +#include "atom.h" + +const u32 +base917c_format[] = { + DRM_FORMAT_C8, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGB565, + DRM_FORMAT_XRGB1555, + DRM_FORMAT_ARGB1555, + DRM_FORMAT_XBGR2101010, + DRM_FORMAT_ABGR2101010, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_ABGR8888, + DRM_FORMAT_XRGB2101010, + DRM_FORMAT_ARGB2101010, + 0 +}; + +int +base917c_new(struct nouveau_drm *drm, int head, s32 oclass, + struct nv50_wndw **pwndw) +{ + return base507c_new_(&base907c, base917c_format, drm, head, oclass, + 0x00000002 << (head * 4), pwndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index b96dc3d4dab59..861fb0ec6b615 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -194,6 +194,8 @@ nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw) case DRM_FORMAT_ABGR2101010: asyw->image.format = 0xd1; break; case DRM_FORMAT_XBGR8888 : case DRM_FORMAT_ABGR8888 : asyw->image.format = 0xd5; break; + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_ARGB2101010: asyw->image.format = 0xdf; break; default: WARN_ON(1); return -EINVAL; From 2ce7f38629891eeaf3e5d406add102a3fa6f6632 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 132/165] drm/nouveau/kms/nv50-: initial overlay support Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/Kbuild | 1 + drivers/gpu/drm/nouveau/dispnv50/atom.h | 11 ++ drivers/gpu/drm/nouveau/dispnv50/base.h | 2 - drivers/gpu/drm/nouveau/dispnv50/curs.h | 1 - drivers/gpu/drm/nouveau/dispnv50/disp.h | 3 + drivers/gpu/drm/nouveau/dispnv50/head507d.c | 3 +- drivers/gpu/drm/nouveau/dispnv50/head907d.c | 2 + drivers/gpu/drm/nouveau/dispnv50/oimm507b.c | 6 +- drivers/gpu/drm/nouveau/dispnv50/ovly.c | 2 +- drivers/gpu/drm/nouveau/dispnv50/ovly.h | 14 ++ drivers/gpu/drm/nouveau/dispnv50/ovly507e.c | 144 ++++++++++++++++++++ drivers/gpu/drm/nouveau/dispnv50/ovly827e.c | 66 ++++++++- drivers/gpu/drm/nouveau/dispnv50/ovly907e.c | 38 +++++- drivers/gpu/drm/nouveau/dispnv50/ovly917e.c | 45 ++++++ drivers/gpu/drm/nouveau/dispnv50/wndw.c | 35 ++++- drivers/gpu/drm/nouveau/dispnv50/wndw.h | 6 + 16 files changed, 364 insertions(+), 15 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/dispnv50/ovly917e.c diff --git a/drivers/gpu/drm/nouveau/dispnv50/Kbuild b/drivers/gpu/drm/nouveau/dispnv50/Kbuild index 7c337fd801587..ebd18cb9fedac 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/Kbuild +++ b/drivers/gpu/drm/nouveau/dispnv50/Kbuild @@ -40,3 +40,4 @@ nouveau-y += dispnv50/ovly.o nouveau-y += dispnv50/ovly507e.o nouveau-y += dispnv50/ovly827e.o nouveau-y += dispnv50/ovly907e.o +nouveau-y += dispnv50/ovly917e.o diff --git a/drivers/gpu/drm/nouveau/dispnv50/atom.h b/drivers/gpu/drm/nouveau/dispnv50/atom.h index 3d059df78322b..d8337e7996e80 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/atom.h +++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h @@ -173,6 +173,7 @@ struct nv50_wndw_atom { u8 mode:2; u8 interval:4; + u8 colorspace:2; u8 format; u8 kind:7; u8 layout:1; @@ -186,6 +187,15 @@ struct nv50_wndw_atom { u64 offset[6]; } image; + struct { + u16 sx; + u16 sy; + u16 sw; + u16 sh; + u16 dw; + u16 dh; + } scale; + struct { u16 x; u16 y; @@ -197,6 +207,7 @@ struct nv50_wndw_atom { bool sema:1; bool xlut:1; bool image:1; + bool scale:1; bool point:1; }; u8 mask; diff --git a/drivers/gpu/drm/nouveau/dispnv50/base.h b/drivers/gpu/drm/nouveau/dispnv50/base.h index 7afd9e26f9f96..e7f14f230f35b 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/base.h +++ b/drivers/gpu/drm/nouveau/dispnv50/base.h @@ -13,10 +13,8 @@ void base507c_release(struct nv50_wndw *, struct nv50_wndw_atom *, struct nv50_head_atom *); void base507c_sema_set(struct nv50_wndw *, struct nv50_wndw_atom *); void base507c_sema_clr(struct nv50_wndw *); -void base507c_ntfy_reset(struct nouveau_bo *, u32); void base507c_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *); void base507c_ntfy_clr(struct nv50_wndw *); -int base507c_ntfy_wait_begun(struct nouveau_bo *, u32, struct nvif_device *); void base507c_xlut_set(struct nv50_wndw *, struct nv50_wndw_atom *); void base507c_xlut_clr(struct nv50_wndw *); void base507c_image_clr(struct nv50_wndw *); diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs.h b/drivers/gpu/drm/nouveau/dispnv50/curs.h index 2285247dc2a3a..8edac4507ec89 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/curs.h +++ b/drivers/gpu/drm/nouveau/dispnv50/curs.h @@ -6,7 +6,6 @@ int curs507a_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); int curs507a_new_(const struct nv50_wimm_func *, struct nouveau_drm *, int head, s32 oclass, u32 interlock_data, struct nv50_wndw **); -extern const struct nv50_wimm_func curs507a; int curs907a_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.h b/drivers/gpu/drm/nouveau/dispnv50/disp.h index f3a963b0ab77e..a89b83f95187e 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.h +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.h @@ -16,6 +16,9 @@ struct nv50_disp { #define NV50_DISP_BASE_SEM0(c) NV50_DISP_WNDW_SEM0(0 + (c)) #define NV50_DISP_BASE_SEM1(c) NV50_DISP_WNDW_SEM1(0 + (c)) #define NV50_DISP_BASE_NTFY(c) NV50_DISP_WNDW_NTFY(0 + (c)) +#define NV50_DISP_OVLY_SEM0(c) NV50_DISP_WNDW_SEM0(4 + (c)) +#define NV50_DISP_OVLY_SEM1(c) NV50_DISP_WNDW_SEM1(4 + (c)) +#define NV50_DISP_OVLY_NTFY(c) NV50_DISP_WNDW_NTFY(4 + (c)) struct nouveau_bo *sync; struct mutex mutex; diff --git a/drivers/gpu/drm/nouveau/dispnv50/head507d.c b/drivers/gpu/drm/nouveau/dispnv50/head507d.c index 5b6a280ab804c..51bc5996fd37a 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head507d.c @@ -58,7 +58,6 @@ head507d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh) if (asyh->ovly.cpp) { switch (asyh->ovly.cpp) { - case 8: bounds |= 0x00000500; break; case 4: bounds |= 0x00000300; break; case 2: bounds |= 0x00000100; break; default: @@ -66,6 +65,8 @@ head507d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh) break; } bounds |= 0x00000001; + } else { + bounds |= 0x00000100; } if ((push = evo_wait(core, 2))) { diff --git a/drivers/gpu/drm/nouveau/dispnv50/head907d.c b/drivers/gpu/drm/nouveau/dispnv50/head907d.c index c09620f540f9f..633907163eb1f 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head907d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head907d.c @@ -82,6 +82,8 @@ head907d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh) break; } bounds |= 0x00000001; + } else { + bounds |= 0x00000100; } if ((push = evo_wait(core, 2))) { diff --git a/drivers/gpu/drm/nouveau/dispnv50/oimm507b.c b/drivers/gpu/drm/nouveau/dispnv50/oimm507b.c index c4baca82de14b..2ee404b3e19ff 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/oimm507b.c +++ b/drivers/gpu/drm/nouveau/dispnv50/oimm507b.c @@ -23,10 +23,6 @@ #include -static const struct nv50_wimm_func -oimm507b = { -}; - static int oimm507b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, s32 oclass, struct nv50_wndw *wndw) @@ -52,5 +48,5 @@ oimm507b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, int oimm507b_init(struct nouveau_drm *drm, s32 oclass, struct nv50_wndw *wndw) { - return oimm507b_init_(&oimm507b, drm, oclass, wndw); + return oimm507b_init_(&curs507a, drm, oclass, wndw); } diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly.c b/drivers/gpu/drm/nouveau/dispnv50/ovly.c index be0f16fdcd5bd..90c246d47604c 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/ovly.c +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly.c @@ -32,7 +32,7 @@ nv50_ovly_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) int version; int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); } ovlys[] = { - { GK104_DISP_OVERLAY_CONTROL_DMA, 0, ovly907e_new }, + { GK104_DISP_OVERLAY_CONTROL_DMA, 0, ovly917e_new }, { GF110_DISP_OVERLAY_CONTROL_DMA, 0, ovly907e_new }, { GT214_DISP_OVERLAY_CHANNEL_DMA, 0, ovly827e_new }, { GT200_DISP_OVERLAY_CHANNEL_DMA, 0, ovly827e_new }, diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly.h b/drivers/gpu/drm/nouveau/dispnv50/ovly.h index d149ef6f957e6..4869d52d17860 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/ovly.h +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly.h @@ -6,11 +6,25 @@ int ovly507e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); int ovly507e_new_(const struct nv50_wndw_func *, const u32 *format, struct nouveau_drm *, int head, s32 oclass, u32 interlock_data, struct nv50_wndw **); +int ovly507e_acquire(struct nv50_wndw *, struct nv50_wndw_atom *, + struct nv50_head_atom *); +void ovly507e_release(struct nv50_wndw *, struct nv50_wndw_atom *, + struct nv50_head_atom *); +void ovly507e_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *); +void ovly507e_ntfy_clr(struct nv50_wndw *); +void ovly507e_image_clr(struct nv50_wndw *); +void ovly507e_scale_set(struct nv50_wndw *, struct nv50_wndw_atom *); +void ovly507e_update(struct nv50_wndw *, u32 *); extern const u32 ovly827e_format[]; +void ovly827e_ntfy_reset(struct nouveau_bo *, u32); +int ovly827e_ntfy_wait_begun(struct nouveau_bo *, u32, struct nvif_device *); + +extern const struct nv50_wndw_func ovly907e; int ovly827e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); int ovly907e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); +int ovly917e_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); int nv50_ovly_new(struct nouveau_drm *, int head, struct nv50_wndw **); #endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c b/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c index 732eea39e4de7..cc417664f8231 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly507e.c @@ -20,17 +20,149 @@ * OTHER DEALINGS IN THE SOFTWARE. */ #include "ovly.h" +#include "atom.h" + +#include +#include #include +#include + +void +ovly507e_update(struct nv50_wndw *wndw, u32 *interlock) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 2))) { + evo_mthd(push, 0x0080, 1); + evo_data(push, interlock[NV50_DISP_INTERLOCK_CORE]); + evo_kick(push, &wndw->wndw); + } +} + +void +ovly507e_scale_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 4))) { + evo_mthd(push, 0x00e0, 3); + evo_data(push, asyw->scale.sy << 16 | asyw->scale.sx); + evo_data(push, asyw->scale.sh << 16 | asyw->scale.sw); + evo_data(push, asyw->scale.dw); + evo_kick(push, &wndw->wndw); + } +} + +void +ovly507e_image_clr(struct nv50_wndw *wndw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 4))) { + evo_mthd(push, 0x0084, 1); + evo_data(push, 0x00000000); + evo_mthd(push, 0x00c0, 1); + evo_data(push, 0x00000000); + evo_kick(push, &wndw->wndw); + } +} + +static void +ovly507e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 12))) { + evo_mthd(push, 0x0084, 1); + evo_data(push, asyw->image.interval << 4); + evo_mthd(push, 0x00c0, 1); + evo_data(push, asyw->image.handle[0]); + evo_mthd(push, 0x0100, 1); + evo_data(push, 0x00000002); + evo_mthd(push, 0x0800, 1); + evo_data(push, asyw->image.offset[0] >> 8); + evo_mthd(push, 0x0808, 3); + evo_data(push, asyw->image.h << 16 | asyw->image.w); + evo_data(push, asyw->image.layout << 20 | + (asyw->image.pitch[0] >> 8) << 8 | + asyw->image.blocks[0] << 8 | + asyw->image.blockh); + evo_data(push, asyw->image.kind << 16 | + asyw->image.format << 8 | + asyw->image.colorspace); + evo_kick(push, &wndw->wndw); + } +} + +void +ovly507e_ntfy_clr(struct nv50_wndw *wndw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 2))) { + evo_mthd(push, 0x00a4, 1); + evo_data(push, 0x00000000); + evo_kick(push, &wndw->wndw); + } +} + +void +ovly507e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 3))) { + evo_mthd(push, 0x00a0, 2); + evo_data(push, asyw->ntfy.awaken << 30 | asyw->ntfy.offset); + evo_data(push, asyw->ntfy.handle); + evo_kick(push, &wndw->wndw); + } +} + +void +ovly507e_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, + struct nv50_head_atom *asyh) +{ + asyh->ovly.cpp = 0; +} + +int +ovly507e_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, + struct nv50_head_atom *asyh) +{ + const struct drm_framebuffer *fb = asyw->state.fb; + int ret; + + ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state, + DRM_PLANE_HELPER_NO_SCALING, + DRM_PLANE_HELPER_NO_SCALING, + true, true); + if (ret) + return ret; + + asyh->ovly.cpp = fb->format->cpp[0]; + return 0; +} #include "nouveau_bo.h" static const struct nv50_wndw_func ovly507e = { + .acquire = ovly507e_acquire, + .release = ovly507e_release, + .ntfy_set = ovly507e_ntfy_set, + .ntfy_clr = ovly507e_ntfy_clr, + .ntfy_reset = base507c_ntfy_reset, + .ntfy_wait_begun = base507c_ntfy_wait_begun, + .image_set = ovly507e_image_set, + .image_clr = ovly507e_image_clr, + .scale_set = ovly507e_scale_set, + .update = ovly507e_update, }; static const u32 ovly507e_format[] = { + DRM_FORMAT_YUYV, + DRM_FORMAT_UYVY, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_XRGB1555, + DRM_FORMAT_ARGB1555, 0 }; @@ -61,6 +193,18 @@ ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format, return ret; } + ret = nvif_notify_init(&wndw->wndw.base.user, wndw->notify.func, false, + NV50_DISP_OVERLAY_CHANNEL_DMA_V0_NTFY_UEVENT, + &(struct nvif_notify_uevent_req) {}, + sizeof(struct nvif_notify_uevent_req), + sizeof(struct nvif_notify_uevent_rep), + &wndw->notify); + if (ret) + return ret; + + wndw->ntfy = NV50_DISP_OVLY_NTFY(wndw->id); + wndw->sema = NV50_DISP_OVLY_SEM0(wndw->id); + wndw->data = 0x00000000; return 0; } diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly827e.c b/drivers/gpu/drm/nouveau/dispnv50/ovly827e.c index a8115f13406ee..aaa9fe5a4fc8a 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/ovly827e.c +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly827e.c @@ -20,17 +20,81 @@ * OTHER DEALINGS IN THE SOFTWARE. */ #include "ovly.h" +#include "atom.h" #include -#include +static void +ovly827e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 12))) { + evo_mthd(push, 0x0084, 1); + evo_data(push, asyw->image.interval << 4); + evo_mthd(push, 0x00c0, 1); + evo_data(push, asyw->image.handle[0]); + evo_mthd(push, 0x0100, 1); + evo_data(push, 0x00000002); + evo_mthd(push, 0x0800, 1); + evo_data(push, asyw->image.offset[0] >> 8); + evo_mthd(push, 0x0808, 3); + evo_data(push, asyw->image.h << 16 | asyw->image.w); + evo_data(push, asyw->image.layout << 20 | + (asyw->image.pitch[0] >> 8) << 8 | + asyw->image.blocks[0] << 8 | + asyw->image.blockh); + evo_data(push, asyw->image.format << 8 | + asyw->image.colorspace); + evo_kick(push, &wndw->wndw); + } +} + +int +ovly827e_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset, + struct nvif_device *device) +{ + s64 time = nvif_msec(device, 2000ULL, + u32 data = nouveau_bo_rd32(bo, offset / 4 + 3); + if ((data & 0xffff0000) == 0xffff0000) + break; + usleep_range(1, 2); + ); + return time < 0 ? time : 0; +} + +void +ovly827e_ntfy_reset(struct nouveau_bo *bo, u32 offset) +{ + nouveau_bo_wr32(bo, offset / 4 + 0, 0x00000000); + nouveau_bo_wr32(bo, offset / 4 + 1, 0x00000000); + nouveau_bo_wr32(bo, offset / 4 + 2, 0x00000000); + nouveau_bo_wr32(bo, offset / 4 + 3, 0x80000000); +} static const struct nv50_wndw_func ovly827e = { + .acquire = ovly507e_acquire, + .release = ovly507e_release, + .ntfy_set = ovly507e_ntfy_set, + .ntfy_clr = ovly507e_ntfy_clr, + .ntfy_reset = ovly827e_ntfy_reset, + .ntfy_wait_begun = ovly827e_ntfy_wait_begun, + .image_set = ovly827e_image_set, + .image_clr = ovly507e_image_clr, + .scale_set = ovly507e_scale_set, + .update = ovly507e_update, }; const u32 ovly827e_format[] = { + DRM_FORMAT_YUYV, + DRM_FORMAT_UYVY, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_XRGB1555, + DRM_FORMAT_ARGB1555, + DRM_FORMAT_XBGR2101010, + DRM_FORMAT_ABGR2101010, 0 }; diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly907e.c b/drivers/gpu/drm/nouveau/dispnv50/ovly907e.c index f50da6461d41b..a3ce53046015c 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/ovly907e.c +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly907e.c @@ -20,9 +20,45 @@ * OTHER DEALINGS IN THE SOFTWARE. */ #include "ovly.h" +#include "atom.h" -static const struct nv50_wndw_func +static void +ovly907e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 12))) { + evo_mthd(push, 0x0084, 1); + evo_data(push, asyw->image.interval << 4); + evo_mthd(push, 0x00c0, 1); + evo_data(push, asyw->image.handle[0]); + evo_mthd(push, 0x0100, 1); + evo_data(push, 0x00000002); + evo_mthd(push, 0x0400, 1); + evo_data(push, asyw->image.offset[0] >> 8); + evo_mthd(push, 0x0408, 3); + evo_data(push, asyw->image.h << 16 | asyw->image.w); + evo_data(push, asyw->image.layout << 24 | + (asyw->image.pitch[0] >> 8) << 8 | + asyw->image.blocks[0] << 8 | + asyw->image.blockh); + evo_data(push, asyw->image.format << 8 | + asyw->image.colorspace); + evo_kick(push, &wndw->wndw); + } +} + +const struct nv50_wndw_func ovly907e = { + .acquire = ovly507e_acquire, + .release = ovly507e_release, + .ntfy_set = ovly507e_ntfy_set, + .ntfy_clr = ovly507e_ntfy_clr, + .ntfy_reset = ovly827e_ntfy_reset, + .ntfy_wait_begun = ovly827e_ntfy_wait_begun, + .image_set = ovly907e_image_set, + .image_clr = ovly507e_image_clr, + .scale_set = ovly507e_scale_set, + .update = ovly507e_update, }; int diff --git a/drivers/gpu/drm/nouveau/dispnv50/ovly917e.c b/drivers/gpu/drm/nouveau/dispnv50/ovly917e.c new file mode 100644 index 0000000000000..505fa7e785230 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/ovly917e.c @@ -0,0 +1,45 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "ovly.h" + +static const u32 +ovly917e_format[] = { + DRM_FORMAT_YUYV, + DRM_FORMAT_UYVY, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_XRGB1555, + DRM_FORMAT_ARGB1555, + DRM_FORMAT_XBGR2101010, + DRM_FORMAT_ABGR2101010, + DRM_FORMAT_XRGB2101010, + DRM_FORMAT_ARGB2101010, + 0 +}; + +int +ovly917e_new(struct nouveau_drm *drm, int head, s32 oclass, + struct nv50_wndw **pwndw) +{ + return ovly507e_new_(&ovly907e, ovly917e_format, drm, head, oclass, + 0x00000004 << (head * 4), pwndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index 861fb0ec6b615..c7c08fae383f3 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -146,6 +146,7 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock, wndw->func->xlut_set(wndw, asyw); } + if (asyw->set.scale) wndw->func->scale_set(wndw, asyw); if (asyw->set.point) { wndw->immd->point(wndw, asyw); wndw->immd->update(wndw, interlock); @@ -180,6 +181,20 @@ nv50_wndw_atomic_check_release(struct nv50_wndw *wndw, asyw->sema.handle = 0; } +static int +nv50_wndw_atomic_check_acquire_yuv(struct nv50_wndw_atom *asyw) +{ + switch (asyw->state.fb->format->format) { + case DRM_FORMAT_YUYV: asyw->image.format = 0x28; break; + case DRM_FORMAT_UYVY: asyw->image.format = 0x29; break; + default: + WARN_ON(1); + return -EINVAL; + } + asyw->image.colorspace = 1; + return 0; +} + static int nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw) { @@ -197,9 +212,9 @@ nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw) case DRM_FORMAT_XRGB2101010: case DRM_FORMAT_ARGB2101010: asyw->image.format = 0xdf; break; default: - WARN_ON(1); return -EINVAL; } + asyw->image.colorspace = 0; return 0; } @@ -221,8 +236,11 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, asyw->image.kind = fb->nvbo->kind; ret = nv50_wndw_atomic_check_acquire_rgb(asyw); - if (ret) - return ret; + if (ret) { + ret = nv50_wndw_atomic_check_acquire_yuv(asyw); + if (ret) + return ret; + } if (asyw->image.kind) { asyw->image.layout = 0; @@ -247,6 +265,17 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset, asyw->set.image = wndw->func->image_set != NULL; } + if (wndw->func->scale_set) { + asyw->scale.sx = asyw->state.src_x >> 16; + asyw->scale.sy = asyw->state.src_y >> 16; + asyw->scale.sw = asyw->state.src_w >> 16; + asyw->scale.sh = asyw->state.src_h >> 16; + asyw->scale.dw = asyw->state.crtc_w; + asyw->scale.dh = asyw->state.crtc_h; + if (memcmp(&armw->scale, &asyw->scale, sizeof(asyw->scale))) + asyw->set.scale = true; + } + if (wndw->immd) { asyw->point.x = asyw->state.crtc_x; asyw->point.y = asyw->state.crtc_y; diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.h b/drivers/gpu/drm/nouveau/dispnv50/wndw.h index 223cf3f37dae3..745304d06af19 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.h +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.h @@ -70,15 +70,21 @@ struct nv50_wndw_func { void (*xlut_clr)(struct nv50_wndw *); void (*image_set)(struct nv50_wndw *, struct nv50_wndw_atom *); void (*image_clr)(struct nv50_wndw *); + void (*scale_set)(struct nv50_wndw *, struct nv50_wndw_atom *); void (*update)(struct nv50_wndw *, u32 *interlock); }; extern const struct drm_plane_funcs nv50_wndw; +void base507c_ntfy_reset(struct nouveau_bo *, u32); +int base507c_ntfy_wait_begun(struct nouveau_bo *, u32, struct nvif_device *); + struct nv50_wimm_func { void (*point)(struct nv50_wndw *, struct nv50_wndw_atom *); void (*update)(struct nv50_wndw *, u32 *interlock); }; + +extern const struct nv50_wimm_func curs507a; #endif From 890c85f3ee106e2f13cb510d3ee73f0214e1c620 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 133/165] drm/nouveau/core: increase maximum number of copy engines to 9 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/core/device.h | 9 ++++++--- drivers/gpu/drm/nouveau/nvkm/core/subdev.c | 3 +++ drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 6 ++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index f2f9b9e7ce2ea..08c52e3afc030 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h @@ -38,7 +38,10 @@ enum nvkm_devidx { NVKM_ENGINE_CE3, NVKM_ENGINE_CE4, NVKM_ENGINE_CE5, - NVKM_ENGINE_CE_LAST = NVKM_ENGINE_CE5, + NVKM_ENGINE_CE6, + NVKM_ENGINE_CE7, + NVKM_ENGINE_CE8, + NVKM_ENGINE_CE_LAST = NVKM_ENGINE_CE8, NVKM_ENGINE_CIPHER, NVKM_ENGINE_DISP, @@ -145,7 +148,7 @@ struct nvkm_device { struct nvkm_volt *volt; struct nvkm_engine *bsp; - struct nvkm_engine *ce[6]; + struct nvkm_engine *ce[9]; struct nvkm_engine *cipher; struct nvkm_disp *disp; struct nvkm_dma *dma; @@ -217,7 +220,7 @@ struct nvkm_device_chip { int (*volt )(struct nvkm_device *, int idx, struct nvkm_volt **); int (*bsp )(struct nvkm_device *, int idx, struct nvkm_engine **); - int (*ce[6] )(struct nvkm_device *, int idx, struct nvkm_engine **); + int (*ce[9] )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*cipher )(struct nvkm_device *, int idx, struct nvkm_engine **); int (*disp )(struct nvkm_device *, int idx, struct nvkm_disp **); int (*dma )(struct nvkm_device *, int idx, struct nvkm_dma **); diff --git a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c index b96f9e2f237a2..03f676c18aad5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c @@ -61,6 +61,9 @@ nvkm_subdev_name[NVKM_SUBDEV_NR] = { [NVKM_ENGINE_CE3 ] = "ce3", [NVKM_ENGINE_CE4 ] = "ce4", [NVKM_ENGINE_CE5 ] = "ce5", + [NVKM_ENGINE_CE6 ] = "ce6", + [NVKM_ENGINE_CE7 ] = "ce7", + [NVKM_ENGINE_CE8 ] = "ce8", [NVKM_ENGINE_CIPHER ] = "cipher", [NVKM_ENGINE_DISP ] = "disp", [NVKM_ENGINE_DMAOBJ ] = "dma", diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 5c79c795acaa5..b9b6bef3b805e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2471,6 +2471,9 @@ nvkm_device_engine(struct nvkm_device *device, int index) _(CE3 , device->ce[3] , device->ce[3]); _(CE4 , device->ce[4] , device->ce[4]); _(CE5 , device->ce[5] , device->ce[5]); + _(CE6 , device->ce[6] , device->ce[6]); + _(CE7 , device->ce[7] , device->ce[7]); + _(CE8 , device->ce[8] , device->ce[8]); _(CIPHER , device->cipher , device->cipher); _(DISP , device->disp , &device->disp->engine); _(DMAOBJ , device->dma , &device->dma->engine); @@ -2925,6 +2928,9 @@ nvkm_device_ctor(const struct nvkm_device_func *func, _(NVKM_ENGINE_CE3 , ce[3]); _(NVKM_ENGINE_CE4 , ce[4]); _(NVKM_ENGINE_CE5 , ce[5]); + _(NVKM_ENGINE_CE6 , ce[6]); + _(NVKM_ENGINE_CE7 , ce[7]); + _(NVKM_ENGINE_CE8 , ce[8]); _(NVKM_ENGINE_CIPHER , cipher); _(NVKM_ENGINE_DISP , disp); _(NVKM_ENGINE_DMAOBJ , dma); From c1f856bb99499f82420d74886884d193e9d63db7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 134/165] drm/nouveau/core: recognise gv100 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/cl0080.h | 1 + drivers/gpu/drm/nouveau/include/nvkm/core/device.h | 1 + drivers/gpu/drm/nouveau/nouveau_abi16.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 7 +++++++ drivers/gpu/drm/nouveau/nvkm/engine/device/user.c | 1 + 5 files changed, 11 insertions(+) diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl0080.h b/drivers/gpu/drm/nouveau/include/nvif/cl0080.h index 49c1c90d2bde0..4f5233107f5f8 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/cl0080.h +++ b/drivers/gpu/drm/nouveau/include/nvif/cl0080.h @@ -31,6 +31,7 @@ struct nv_device_info_v0 { #define NV_DEVICE_INFO_V0_KEPLER 0x08 #define NV_DEVICE_INFO_V0_MAXWELL 0x09 #define NV_DEVICE_INFO_V0_PASCAL 0x0a +#define NV_DEVICE_INFO_V0_VOLTA 0x0b __u8 family; __u8 pad06[2]; __u64 ram_size; diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index 08c52e3afc030..d83d834b74521 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h @@ -113,6 +113,7 @@ struct nvkm_device { NV_E0 = 0xe0, GM100 = 0x110, GP100 = 0x130, + GV100 = 0x140, } card_type; u32 chipset; u8 chiprev; diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index ea2472770b21b..e2211bb2cf79e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -103,6 +103,7 @@ nouveau_abi16_swclass(struct nouveau_drm *drm) case NV_DEVICE_INFO_V0_KEPLER: case NV_DEVICE_INFO_V0_MAXWELL: case NV_DEVICE_INFO_V0_PASCAL: + case NV_DEVICE_INFO_V0_VOLTA: return NVIF_CLASS_SW_GF100; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index b9b6bef3b805e..e0e4d286f7e6c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2394,6 +2394,11 @@ nv13b_chipset = { .sw = gf100_sw_new, }; +static const struct nvkm_device_chip +nv140_chipset = { + .name = "GV100", +}; + static int nvkm_device_event_ctor(struct nvkm_object *object, void *data, u32 size, struct nvkm_notify *notify) @@ -2750,6 +2755,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, case 0x110: case 0x120: device->card_type = GM100; break; case 0x130: device->card_type = GP100; break; + case 0x140: device->card_type = GV100; break; default: break; } @@ -2841,6 +2847,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, case 0x137: device->chip = &nv137_chipset; break; case 0x138: device->chip = &nv138_chipset; break; case 0x13b: device->chip = &nv13b_chipset; break; + case 0x140: device->chip = &nv140_chipset; break; default: nvdev_error(device, "unknown chipset (%08x)\n", boot0); goto done; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c index 600bdb8704627..dde6bbafa709f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c @@ -174,6 +174,7 @@ nvkm_udevice_info(struct nvkm_udevice *udev, void *data, u32 size) case NV_E0: args->v0.family = NV_DEVICE_INFO_V0_KEPLER; break; case GM100: args->v0.family = NV_DEVICE_INFO_V0_MAXWELL; break; case GP100: args->v0.family = NV_DEVICE_INFO_V0_PASCAL; break; + case GV100: args->v0.family = NV_DEVICE_INFO_V0_VOLTA; break; default: args->v0.family = 0; break; From 893855d8215f5ec6b0e1fac399960405c8237c53 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 135/165] drm/nouveau/pci/gv100: initial support Appears to be compatible with GP100. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index e0e4d286f7e6c..3674db6a1a0f2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2397,6 +2397,7 @@ nv13b_chipset = { static const struct nvkm_device_chip nv140_chipset = { .name = "GV100", + .pci = gp100_pci_new, }; static int From 75e482efd38a40497e06c217e6ae9f92940b218e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 136/165] drm/nouveau/bios/gv100: initial support No real surprises here so far. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 3674db6a1a0f2..939452276a2db 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2397,6 +2397,7 @@ nv13b_chipset = { static const struct nvkm_device_chip nv140_chipset = { .name = "GV100", + .bios = nvkm_bios_new, .pci = gp100_pci_new, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c index 0f537c22804cf..3634cd0630b81 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c @@ -78,7 +78,10 @@ pramin_init(struct nvkm_bios *bios, const char *name) * important as we don't want to be touching vram on an * uninitialised board */ - addr = nvkm_rd32(device, 0x619f04); + if (device->card_type >= GV100) + addr = nvkm_rd32(device, 0x625f04); + else + addr = nvkm_rd32(device, 0x619f04); if (!(addr & 0x00000008)) { nvkm_debug(subdev, "... not enabled\n"); return ERR_PTR(-ENODEV); From 6827c9a8683d8102479ba7add0cc7ab181143c82 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 137/165] drm/nouveau/bios/pll: limits table 5.0 Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/subdev/bios/pll.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c index 2ca23a9157ab9..e6e804cee2bc8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c @@ -193,7 +193,10 @@ pll_map_type(struct nvkm_bios *bios, u8 type, u32 *reg, u8 *ver, u8 *len) data += hdr; while (cnt--) { if (nvbios_rd08(bios, data + 0) == type) { - *reg = nvbios_rd32(bios, data + 3); + if (*ver < 0x50) + *reg = nvbios_rd32(bios, data + 3); + else + *reg = 0; return data; } data += *len; @@ -361,6 +364,20 @@ nvbios_pll_parse(struct nvkm_bios *bios, u32 type, struct nvbios_pll *info) info->min_p = nvbios_rd08(bios, data + 12); info->max_p = nvbios_rd08(bios, data + 13); break; + case 0x50: + info->refclk = nvbios_rd16(bios, data + 1) * 1000; + /* info->refclk_alt = nvbios_rd16(bios, data + 3) * 1000; */ + info->vco1.min_freq = nvbios_rd16(bios, data + 5) * 1000; + info->vco1.max_freq = nvbios_rd16(bios, data + 7) * 1000; + info->vco1.min_inputfreq = nvbios_rd16(bios, data + 9) * 1000; + info->vco1.max_inputfreq = nvbios_rd16(bios, data + 11) * 1000; + info->vco1.min_m = nvbios_rd08(bios, data + 13); + info->vco1.max_m = nvbios_rd08(bios, data + 14); + info->vco1.min_n = nvbios_rd08(bios, data + 15); + info->vco1.max_n = nvbios_rd08(bios, data + 16); + info->min_p = nvbios_rd08(bios, data + 17); + info->max_p = nvbios_rd08(bios, data + 18); + break; default: nvkm_error(subdev, "unknown pll limits version 0x%02x\n", ver); return -EINVAL; From 8769dc989c53e5ed38460b7585d55f381f51e9d8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 138/165] drm/nouveau/devinit/gv100: initial support Signed-off-by: Ben Skeggs --- .../drm/nouveau/include/nvkm/subdev/devinit.h | 1 + .../gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + .../drm/nouveau/nvkm/subdev/devinit/Kbuild | 1 + .../drm/nouveau/nvkm/subdev/devinit/gm200.c | 2 +- .../drm/nouveau/nvkm/subdev/devinit/gv100.c | 79 +++++++++++++++++++ .../drm/nouveau/nvkm/subdev/devinit/nv50.h | 2 + 6 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gv100.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h index 40558064d589b..486e7635c29d7 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h @@ -30,4 +30,5 @@ int mcp89_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); int gf100_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); int gm107_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); int gm200_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); +int gv100_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 939452276a2db..4a2d413f12b92 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2398,6 +2398,7 @@ static const struct nvkm_device_chip nv140_chipset = { .name = "GV100", .bios = nvkm_bios_new, + .devinit = gv100_devinit_new, .pci = gp100_pci_new, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/Kbuild index eac88e3dc6e58..50a4369264841 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/Kbuild @@ -12,3 +12,4 @@ nvkm-y += nvkm/subdev/devinit/mcp89.o nvkm-y += nvkm/subdev/devinit/gf100.o nvkm-y += nvkm/subdev/devinit/gm107.o nvkm-y += nvkm/subdev/devinit/gm200.o +nvkm-y += nvkm/subdev/devinit/gv100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm200.c index 1730371933df7..b80618e354919 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm200.c @@ -107,7 +107,7 @@ pmu_load(struct nv50_devinit *init, u8 type, bool post, return pmu_exec(init, pmu.init_addr_pmu), 0; } -static int +int gm200_devinit_post(struct nvkm_devinit *base, bool post) { struct nv50_devinit *init = nv50_devinit(base); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gv100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gv100.c new file mode 100644 index 0000000000000..fbde6828bd38e --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gv100.c @@ -0,0 +1,79 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "nv50.h" + +#include +#include +#include + +static int +gv100_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq) +{ + struct nvkm_subdev *subdev = &init->subdev; + struct nvkm_device *device = subdev->device; + struct nvbios_pll info; + int head = type - PLL_VPLL0; + int N, fN, M, P; + int ret; + + ret = nvbios_pll_parse(device->bios, type, &info); + if (ret) + return ret; + + ret = gt215_pll_calc(subdev, &info, freq, &N, &fN, &M, &P); + if (ret < 0) + return ret; + + switch (info.type) { + case PLL_VPLL0: + case PLL_VPLL1: + case PLL_VPLL2: + case PLL_VPLL3: + nvkm_wr32(device, 0x00ef10 + (head * 0x40), fN << 16); + nvkm_wr32(device, 0x00ef04 + (head * 0x40), (P << 16) | + (N << 8) | + (M << 0)); + break; + default: + nvkm_warn(subdev, "%08x/%dKhz unimplemented\n", type, freq); + ret = -EINVAL; + break; + } + + return ret; +} + +static const struct nvkm_devinit_func +gv100_devinit = { + .preinit = gf100_devinit_preinit, + .init = nv50_devinit_init, + .post = gm200_devinit_post, + .pll_set = gv100_devinit_pll_set, + .disable = gm107_devinit_disable, +}; + +int +gv100_devinit_new(struct nvkm_device *device, int index, + struct nvkm_devinit **pinit) +{ + return nv50_devinit_new_(&gv100_devinit, device, index, pinit); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h index 315ebaff1165b..9b9f0dc1e1928 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h @@ -24,4 +24,6 @@ int gf100_devinit_pll_set(struct nvkm_devinit *, u32, u32); void gf100_devinit_preinit(struct nvkm_devinit *); u64 gm107_devinit_disable(struct nvkm_devinit *); + +int gm200_devinit_post(struct nvkm_devinit *, bool); #endif From a1c771a5cb86e2a45bb4516b40f6127112aaa464 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 139/165] drm/nouveau/top/gv100: initial support Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 4a2d413f12b92..777ba68f4a0f8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2400,6 +2400,7 @@ nv140_chipset = { .bios = nvkm_bios_new, .devinit = gv100_devinit_new, .pci = gp100_pci_new, + .top = gk104_top_new, }; static int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c index fea4957291da2..4f1f3e8906506 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c @@ -48,7 +48,8 @@ gk104_top_oneinit(struct nvkm_top *top) case 0x00000001: /* DATA */ inst = (data & 0x3c000000) >> 26; info->addr = (data & 0x00fff000); - info->fault = (data & 0x000000f8) >> 3; + if (data & 0x00000004) + info->fault = (data & 0x000003f8) >> 3; break; case 0x00000002: /* ENUM */ if (data & 0x00000020) From 46fe1a813adf9abcf71d0a6641ef2de4ce443485 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 140/165] drm/nouveau/ibus/gv100: initial support Appears to be compatible with GM200. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 777ba68f4a0f8..def4acdb860ee 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2399,6 +2399,7 @@ nv140_chipset = { .name = "GV100", .bios = nvkm_bios_new, .devinit = gv100_devinit_new, + .ibus = gm200_ibus_new, .pci = gp100_pci_new, .top = gk104_top_new, }; From 8afbcca54976abd47d3cd77ffd99aa8103944483 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 141/165] drm/nouveau/gpio/gv100: initial support Appears to be compatible with GK104. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index def4acdb860ee..5fbc0867cd2c2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2399,6 +2399,7 @@ nv140_chipset = { .name = "GV100", .bios = nvkm_bios_new, .devinit = gv100_devinit_new, + .gpio = gk104_gpio_new, .ibus = gm200_ibus_new, .pci = gp100_pci_new, .top = gk104_top_new, From d2e3b57d81992442221f00938d137568ee895953 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 142/165] drm/nouveau/i2c/gv100: initial support Appears to be compatible with GM200. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 5fbc0867cd2c2..92290de0e6bf5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2400,6 +2400,7 @@ nv140_chipset = { .bios = nvkm_bios_new, .devinit = gv100_devinit_new, .gpio = gk104_gpio_new, + .i2c = gm200_i2c_new, .ibus = gm200_ibus_new, .pci = gp100_pci_new, .top = gk104_top_new, From 292550499af0117c7137071d8a0aee93fab81f44 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 143/165] drm/nouveau/fuse/gv100: initial support Appears to be compatible with GM107. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 92290de0e6bf5..a9a087a5b94b4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2399,6 +2399,7 @@ nv140_chipset = { .name = "GV100", .bios = nvkm_bios_new, .devinit = gv100_devinit_new, + .fuse = gm107_fuse_new, .gpio = gk104_gpio_new, .i2c = gm200_i2c_new, .ibus = gm200_ibus_new, From 41af75bd3569eeb105635455cc7a99a930dc35ff Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 144/165] drm/nouveau/mc/gv100: initial support Appears to be compatible with GP100. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index a9a087a5b94b4..d3306753d4f84 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2403,6 +2403,7 @@ nv140_chipset = { .gpio = gk104_gpio_new, .i2c = gm200_i2c_new, .ibus = gm200_ibus_new, + .mc = gp100_mc_new, .pci = gp100_pci_new, .top = gk104_top_new, }; From 9506bd24072af64dae998ac5b62c16b3492fc8e8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 145/165] drm/nouveau/bus/gv100: initial support Appears to be compatible with GF100. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index d3306753d4f84..9b2b3b8aa5d99 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2398,6 +2398,7 @@ static const struct nvkm_device_chip nv140_chipset = { .name = "GV100", .bios = nvkm_bios_new, + .bus = gf100_bus_new, .devinit = gv100_devinit_new, .fuse = gm107_fuse_new, .gpio = gk104_gpio_new, From 936240c9bbb2f10fe11b8fbd4aca79f8f5b1b1da Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 146/165] drm/nouveau/tmr/gv100: initial support Appears to be compatible with GK20A. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 9b2b3b8aa5d99..87d50bd4866a1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2406,6 +2406,7 @@ nv140_chipset = { .ibus = gm200_ibus_new, .mc = gp100_mc_new, .pci = gp100_pci_new, + .timer = gk20a_timer_new, .top = gk104_top_new, }; From a4a0cfb6420152de2725e1e407fd86301aceccd1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 147/165] drm/nouveau/imem/gv100: initial support Can't imagine this will be any different. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 87d50bd4866a1..8528e83668429 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2404,6 +2404,7 @@ nv140_chipset = { .gpio = gk104_gpio_new, .i2c = gm200_i2c_new, .ibus = gm200_ibus_new, + .imem = nv50_instmem_new, .mc = gp100_mc_new, .pci = gp100_pci_new, .timer = gk20a_timer_new, From 3582942c2820a4dfcd64585140bc6e1ad72c1130 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 148/165] drm/nouveau/fb/gv100: initial support Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/include/nvkm/subdev/fb.h | 1 + .../gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/fb/gp100.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/fb/gv100.c | 46 +++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h | 2 + 6 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gv100.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index 92be0e5269c63..96ccc624ee814 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h @@ -83,6 +83,7 @@ int gm20b_fb_new(struct nvkm_device *, int, struct nvkm_fb **); int gp100_fb_new(struct nvkm_device *, int, struct nvkm_fb **); int gp102_fb_new(struct nvkm_device *, int, struct nvkm_fb **); int gp10b_fb_new(struct nvkm_device *, int, struct nvkm_fb **); +int gv100_fb_new(struct nvkm_device *, int, struct nvkm_fb **); #include #include diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 8528e83668429..170a7c5224dbb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2400,6 +2400,7 @@ nv140_chipset = { .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gv100_devinit_new, + .fb = gv100_fb_new, .fuse = gm107_fuse_new, .gpio = gk104_gpio_new, .i2c = gm200_i2c_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild index b4f22cce5d433..969610951263d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild @@ -30,6 +30,7 @@ nvkm-y += nvkm/subdev/fb/gm20b.o 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/ram.o nvkm-y += nvkm/subdev/fb/ramnv04.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c index d0a47b9a8cd85..dffe1f5e10712 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c @@ -26,7 +26,7 @@ #include -static void +void gp100_fb_init_unkn(struct nvkm_fb *base) { struct nvkm_device *device = gf100_fb(base)->base.subdev.device; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gv100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gv100.c new file mode 100644 index 0000000000000..3c5e02e9794ae --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gv100.c @@ -0,0 +1,46 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "gf100.h" +#include "ram.h" + +static int +gv100_fb_init_page(struct nvkm_fb *fb) +{ + return (fb->page == 16) ? 0 : -EINVAL; +} + +static const struct nvkm_fb_func +gv100_fb = { + .dtor = gf100_fb_dtor, + .oneinit = gf100_fb_oneinit, + .init = gp100_fb_init, + .init_page = gv100_fb_init_page, + .init_unkn = gp100_fb_init_unkn, + .ram_new = gp100_ram_new, + .default_bigpage = 16, +}; + +int +gv100_fb_new(struct nvkm_device *device, int index, struct nvkm_fb **pfb) +{ + return gf100_fb_new_(&gv100_fb, device, index, pfb); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h index 414a423e0e55f..2857f31466bff 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h @@ -68,4 +68,6 @@ int gf100_fb_oneinit(struct nvkm_fb *); int gf100_fb_init_page(struct nvkm_fb *); int gm200_fb_init_page(struct nvkm_fb *); + +void gp100_fb_init_unkn(struct nvkm_fb *); #endif From 1bce57250ad226e410f9a1a55c0722f075b01652 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 149/165] drm/nouveau/ltc/gv100: initial support Appears to be compatible with GP102. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 170a7c5224dbb..8da7b44697c4c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2406,6 +2406,7 @@ nv140_chipset = { .i2c = gm200_i2c_new, .ibus = gm200_ibus_new, .imem = nv50_instmem_new, + .ltc = gp102_ltc_new, .mc = gp100_mc_new, .pci = gp100_pci_new, .timer = gk20a_timer_new, From edf50395c7c5e8563843eb586aae57c7ac1214ed Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 150/165] drm/nouveau/mmu/gv100: initial support VEID support hacked in here, as it's the most convenient place for now. Will be refined once it's better understood. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 1 + .../gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + .../gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 2 + .../gpu/drm/nouveau/nvkm/subdev/mmu/gv100.c | 43 +++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 3 + .../drm/nouveau/nvkm/subdev/mmu/vmmgv100.c | 87 +++++++++++++++++++ 6 files changed, 137 insertions(+) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gv100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgv100.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index baab93398e54a..688595545e21e 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -129,4 +129,5 @@ int gm200_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gm20b_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gp100_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gp10b_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); +int gv100_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 8da7b44697c4c..46dff27a234be 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2408,6 +2408,7 @@ nv140_chipset = { .imem = nv50_instmem_new, .ltc = gp102_ltc_new, .mc = gp100_mc_new, + .mmu = gv100_mmu_new, .pci = gp100_pci_new, .timer = gk20a_timer_new, .top = gk104_top_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 67ee983bb026a..58a24e3a05985 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -12,6 +12,7 @@ nvkm-y += nvkm/subdev/mmu/gm200.o nvkm-y += nvkm/subdev/mmu/gm20b.o nvkm-y += nvkm/subdev/mmu/gp100.o nvkm-y += nvkm/subdev/mmu/gp10b.o +nvkm-y += nvkm/subdev/mmu/gv100.o nvkm-y += nvkm/subdev/mmu/mem.o nvkm-y += nvkm/subdev/mmu/memnv04.o @@ -31,6 +32,7 @@ nvkm-y += nvkm/subdev/mmu/vmmgm200.o nvkm-y += nvkm/subdev/mmu/vmmgm20b.o nvkm-y += nvkm/subdev/mmu/vmmgp100.o nvkm-y += nvkm/subdev/mmu/vmmgp10b.o +nvkm-y += nvkm/subdev/mmu/vmmgv100.o nvkm-y += nvkm/subdev/mmu/umem.o nvkm-y += nvkm/subdev/mmu/ummu.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gv100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gv100.c new file mode 100644 index 0000000000000..f666cb57f69e2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gv100.c @@ -0,0 +1,43 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "mem.h" +#include "vmm.h" + +#include + +#include + +static const struct nvkm_mmu_func +gv100_mmu = { + .dma_bits = 47, + .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, + .mem = {{ -1, 0, NVIF_CLASS_MEM_GF100}, gf100_mem_new, gf100_mem_map }, + .vmm = {{ -1, -1, NVIF_CLASS_VMM_GP100}, gv100_vmm_new }, + .kind = gm200_mmu_kind, + .kind_sys = true, +}; + +int +gv100_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) +{ + return nvkm_mmu_new_(&gv100_mmu, device, index, pmmu); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index da06e64d8a7d1..1a3b0a3724ca7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -236,6 +236,9 @@ int gp100_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, int gp10b_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); +int gv100_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, + struct lock_class_key *, const char *, + struct nvkm_vmm **); #define VMM_PRINT(l,v,p,f,a...) do { \ struct nvkm_vmm *_vmm = (v); \ diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgv100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgv100.c new file mode 100644 index 0000000000000..2fa40c16e6d2e --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgv100.c @@ -0,0 +1,87 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "vmm.h" + +#include +#include + +#include +#include + +int +gv100_vmm_join(struct nvkm_vmm *vmm, struct nvkm_memory *inst) +{ + u64 data[2], mask; + int ret = gp100_vmm_join(vmm, inst), i; + if (ret) + return ret; + + nvkm_kmap(inst); + data[0] = nvkm_ro32(inst, 0x200); + data[1] = nvkm_ro32(inst, 0x204); + mask = BIT_ULL(0); + + nvkm_wo32(inst, 0x21c, 0x00000000); + + for (i = 0; i < 64; i++) { + if (mask & BIT_ULL(i)) { + nvkm_wo32(inst, 0x2a4 + (i * 0x10), data[1]); + nvkm_wo32(inst, 0x2a0 + (i * 0x10), data[0]); + } else { + nvkm_wo32(inst, 0x2a4 + (i * 0x10), 0x00000001); + nvkm_wo32(inst, 0x2a0 + (i * 0x10), 0x00000001); + } + nvkm_wo32(inst, 0x2a8 + (i * 0x10), 0x00000000); + } + + nvkm_wo32(inst, 0x298, lower_32_bits(mask)); + nvkm_wo32(inst, 0x29c, upper_32_bits(mask)); + nvkm_done(inst); + return 0; +} + +static const struct nvkm_vmm_func +gv100_vmm = { + .join = gv100_vmm_join, + .part = gf100_vmm_part, + .aper = gf100_vmm_aper, + .valid = gp100_vmm_valid, + .flush = gp100_vmm_flush, + .page = { + { 47, &gp100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx }, + { 38, &gp100_vmm_desc_16[3], NVKM_VMM_PAGE_Sxxx }, + { 29, &gp100_vmm_desc_16[2], NVKM_VMM_PAGE_Sxxx }, + { 21, &gp100_vmm_desc_16[1], NVKM_VMM_PAGE_SVxC }, + { 16, &gp100_vmm_desc_16[0], NVKM_VMM_PAGE_SVxC }, + { 12, &gp100_vmm_desc_12[0], NVKM_VMM_PAGE_SVHx }, + {} + } +}; + +int +gv100_vmm_new(struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, const char *name, + struct nvkm_vmm **pvmm) +{ + return nv04_vmm_new_(&gv100_vmm, mmu, 0, addr, size, + argv, argc, key, name, pvmm); +} From 013b7b37739ca883b2dd5ef979e0e250ac3dafc1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 151/165] drm/nouveau/bar/gv100: initial support Appears to be compatible with GM107. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 46dff27a234be..6aaa3d9cb88cb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2397,6 +2397,7 @@ nv13b_chipset = { static const struct nvkm_device_chip nv140_chipset = { .name = "GV100", + .bar = gm107_bar_new, .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gv100_devinit_new, From 8b811951c604e417b4511e3d17a75bb8c84b8f08 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 152/165] drm/nouveau/fault/gv100: initial support Signed-off-by: Ben Skeggs --- .../drm/nouveau/include/nvkm/subdev/fault.h | 6 +- .../gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + .../gpu/drm/nouveau/nvkm/subdev/fault/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/fault/gv100.c | 206 ++++++++++++++++++ 4 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h index 8e9bc30fe65dc..5a77498fe6a09 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h @@ -1,15 +1,18 @@ #ifndef __NVKM_FAULT_H__ #define __NVKM_FAULT_H__ #include +#include struct nvkm_fault { const struct nvkm_fault_func *func; struct nvkm_subdev subdev; - struct nvkm_fault_buffer *buffer[1]; + struct nvkm_fault_buffer *buffer[2]; int buffer_nr; struct nvkm_event event; + + struct nvkm_notify nrpfb; }; struct nvkm_fault_data { @@ -26,4 +29,5 @@ struct nvkm_fault_data { }; int gp100_fault_new(struct nvkm_device *, int, struct nvkm_fault **); +int gv100_fault_new(struct nvkm_device *, int, struct nvkm_fault **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 6aaa3d9cb88cb..7f0385dbed06a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2401,6 +2401,7 @@ nv140_chipset = { .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gv100_devinit_new, + .fault = gv100_fault_new, .fb = gv100_fb_new, .fuse = gm107_fuse_new, .gpio = gk104_gpio_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild index 807ea402a162e..45bb46fb0929a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild @@ -1,2 +1,3 @@ nvkm-y += nvkm/subdev/fault/base.o nvkm-y += nvkm/subdev/fault/gp100.o +nvkm-y += nvkm/subdev/fault/gv100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c new file mode 100644 index 0000000000000..73c7728b59696 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c @@ -0,0 +1,206 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "priv.h" + +#include +#include +#include + +static void +gv100_fault_buffer_process(struct nvkm_fault_buffer *buffer) +{ + struct nvkm_device *device = buffer->fault->subdev.device; + struct nvkm_memory *mem = buffer->mem; + const u32 foff = buffer->id * 0x14; + u32 get = nvkm_rd32(device, 0x100e2c + foff); + u32 put = nvkm_rd32(device, 0x100e30 + foff); + if (put == get) + return; + + nvkm_kmap(mem); + while (get != put) { + const u32 base = get * buffer->fault->func->buffer.entry_size; + const u32 instlo = nvkm_ro32(mem, base + 0x00); + const u32 insthi = nvkm_ro32(mem, base + 0x04); + const u32 addrlo = nvkm_ro32(mem, base + 0x08); + const u32 addrhi = nvkm_ro32(mem, base + 0x0c); + const u32 timelo = nvkm_ro32(mem, base + 0x10); + const u32 timehi = nvkm_ro32(mem, base + 0x14); + const u32 info0 = nvkm_ro32(mem, base + 0x18); + const u32 info1 = nvkm_ro32(mem, base + 0x1c); + struct nvkm_fault_data info; + + if (++get == buffer->entries) + get = 0; + nvkm_wr32(device, 0x100e2c + foff, get); + + info.addr = ((u64)addrhi << 32) | addrlo; + info.inst = ((u64)insthi << 32) | instlo; + info.time = ((u64)timehi << 32) | timelo; + info.engine = (info0 & 0x000000ff); + info.valid = (info1 & 0x80000000) >> 31; + info.gpc = (info1 & 0x1f000000) >> 24; + info.hub = (info1 & 0x00100000) >> 20; + info.access = (info1 & 0x000f0000) >> 16; + info.client = (info1 & 0x00007f00) >> 8; + info.reason = (info1 & 0x0000001f); + + nvkm_fifo_fault(device->fifo, &info); + } + nvkm_done(mem); +} + +static void +gv100_fault_buffer_fini(struct nvkm_fault_buffer *buffer) +{ + struct nvkm_device *device = buffer->fault->subdev.device; + const u32 intr = buffer->id ? 0x08000000 : 0x20000000; + const u32 foff = buffer->id * 0x14; + + nvkm_mask(device, 0x100a34, intr, intr); + nvkm_mask(device, 0x100e34 + foff, 0x80000000, 0x00000000); +} + +static void +gv100_fault_buffer_init(struct nvkm_fault_buffer *buffer) +{ + struct nvkm_device *device = buffer->fault->subdev.device; + const u32 intr = buffer->id ? 0x08000000 : 0x20000000; + const u32 foff = buffer->id * 0x14; + + nvkm_mask(device, 0x100e34 + foff, 0xc0000000, 0x40000000); + nvkm_wr32(device, 0x100e28 + foff, upper_32_bits(buffer->vma->addr)); + nvkm_wr32(device, 0x100e24 + foff, lower_32_bits(buffer->vma->addr)); + nvkm_mask(device, 0x100e34 + foff, 0x80000000, 0x80000000); + nvkm_mask(device, 0x100a2c, intr, intr); +} + +static u32 +gv100_fault_buffer_entries(struct nvkm_fault_buffer *buffer) +{ + struct nvkm_device *device = buffer->fault->subdev.device; + const u32 foff = buffer->id * 0x14; + nvkm_mask(device, 0x100e34 + foff, 0x40000000, 0x40000000); + return nvkm_rd32(device, 0x100e34 + foff) & 0x000fffff; +} + +static int +gv100_fault_ntfy_nrpfb(struct nvkm_notify *notify) +{ + struct nvkm_fault *fault = container_of(notify, typeof(*fault), nrpfb); + gv100_fault_buffer_process(fault->buffer[0]); + return NVKM_NOTIFY_KEEP; +} + +static void +gv100_fault_intr_fault(struct nvkm_fault *fault) +{ + struct nvkm_subdev *subdev = &fault->subdev; + struct nvkm_device *device = subdev->device; + struct nvkm_fault_data info; + const u32 addrlo = nvkm_rd32(device, 0x100e4c); + const u32 addrhi = nvkm_rd32(device, 0x100e50); + const u32 info0 = nvkm_rd32(device, 0x100e54); + const u32 insthi = nvkm_rd32(device, 0x100e58); + const u32 info1 = nvkm_rd32(device, 0x100e5c); + + info.addr = ((u64)addrhi << 32) | addrlo; + info.inst = ((u64)insthi << 32) | (info0 & 0xfffff000); + info.time = 0; + info.engine = (info0 & 0x000000ff); + info.valid = (info1 & 0x80000000) >> 31; + info.gpc = (info1 & 0x1f000000) >> 24; + info.hub = (info1 & 0x00100000) >> 20; + info.access = (info1 & 0x000f0000) >> 16; + info.client = (info1 & 0x00007f00) >> 8; + info.reason = (info1 & 0x0000001f); + + nvkm_fifo_fault(device->fifo, &info); +} + +static void +gv100_fault_intr(struct nvkm_fault *fault) +{ + struct nvkm_subdev *subdev = &fault->subdev; + struct nvkm_device *device = subdev->device; + u32 stat = nvkm_rd32(device, 0x100a20); + + if (stat & 0x80000000) { + gv100_fault_intr_fault(fault); + nvkm_wr32(device, 0x100e60, 0x80000000); + stat &= ~0x80000000; + } + + if (stat & 0x20000000) { + if (fault->buffer[0]) { + nvkm_event_send(&fault->event, 1, 0, NULL, 0); + stat &= ~0x20000000; + } + } + + if (stat) { + nvkm_debug(subdev, "intr %08x\n", stat); + } +} + +static void +gv100_fault_fini(struct nvkm_fault *fault) +{ + nvkm_notify_put(&fault->nrpfb); + nvkm_mask(fault->subdev.device, 0x100a34, 0x80000000, 0x80000000); +} + +static void +gv100_fault_init(struct nvkm_fault *fault) +{ + nvkm_mask(fault->subdev.device, 0x100a2c, 0x80000000, 0x80000000); + nvkm_notify_get(&fault->nrpfb); +} + +static const struct nvkm_fault_func +gv100_fault = { + .init = gv100_fault_init, + .fini = gv100_fault_fini, + .intr = gv100_fault_intr, + .buffer.nr = 2, + .buffer.entry_size = 32, + .buffer.entries = gv100_fault_buffer_entries, + .buffer.init = gv100_fault_buffer_init, + .buffer.fini = gv100_fault_buffer_fini, +}; + +int +gv100_fault_new(struct nvkm_device *device, int index, + struct nvkm_fault **pfault) +{ + struct nvkm_fault *fault; + int ret; + + ret = nvkm_fault_new_(&gv100_fault, device, index, &fault); + *pfault = fault; + if (ret) + return ret; + + return nvkm_notify_init(&fault->buffer[0]->object, &fault->event, + gv100_fault_ntfy_nrpfb, false, NULL, 0, 0, + &fault->nrpfb); +} From ada0c562814ca466386d9bf1e61fd5ee46f2a72c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 153/165] drm/nouveau/pmu/gv100: initial support Appears to be compatible with GP102. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 7f0385dbed06a..12e24ebc85b2a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2412,6 +2412,7 @@ nv140_chipset = { .mc = gp100_mc_new, .mmu = gv100_mmu_new, .pci = gp100_pci_new, + .pmu = gp102_pmu_new, .timer = gk20a_timer_new, .top = gk104_top_new, }; From 24a7513c1026fb1b2d42df1c31ea2da56c1604e2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 154/165] drm/nouveau/therm/gv100: initial support Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 12e24ebc85b2a..965c4332380ff 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2413,6 +2413,7 @@ nv140_chipset = { .mmu = gv100_mmu_new, .pci = gp100_pci_new, .pmu = gp102_pmu_new, + .therm = gp100_therm_new, .timer = gk20a_timer_new, .top = gk104_top_new, }; From 6fb566b913728fe2dadc8271a568583b8854af93 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 155/165] drm/nouveau/dma/gv100: initial support Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/include/nvkm/engine/dma.h | 1 + .../gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + .../gpu/drm/nouveau/nvkm/engine/dma/Kbuild | 2 + .../gpu/drm/nouveau/nvkm/engine/dma/gv100.c | 34 +++++ .../gpu/drm/nouveau/nvkm/engine/dma/user.h | 2 + .../drm/nouveau/nvkm/engine/dma/usergv100.c | 119 ++++++++++++++++++ 6 files changed, 159 insertions(+) create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/dma/gv100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/dma/usergv100.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/dma.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/dma.h index 0f9c1c702ed61..f0c1b2c8c78c2 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/dma.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/dma.h @@ -27,4 +27,5 @@ int nv04_dma_new(struct nvkm_device *, int, struct nvkm_dma **); int nv50_dma_new(struct nvkm_device *, int, struct nvkm_dma **); int gf100_dma_new(struct nvkm_device *, int, struct nvkm_dma **); int gf119_dma_new(struct nvkm_device *, int, struct nvkm_dma **); +int gv100_dma_new(struct nvkm_device *, int, struct nvkm_dma **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 965c4332380ff..f2c3fe1cba2c6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2416,6 +2416,7 @@ nv140_chipset = { .therm = gp100_therm_new, .timer = gk20a_timer_new, .top = gk104_top_new, + .dma = gv100_dma_new, }; static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/dma/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/dma/Kbuild index c4a2ce9b0d71b..e96d1f57f9f9a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/dma/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/dma/Kbuild @@ -3,9 +3,11 @@ nvkm-y += nvkm/engine/dma/nv04.o nvkm-y += nvkm/engine/dma/nv50.o nvkm-y += nvkm/engine/dma/gf100.o nvkm-y += nvkm/engine/dma/gf119.o +nvkm-y += nvkm/engine/dma/gv100.o nvkm-y += nvkm/engine/dma/user.o nvkm-y += nvkm/engine/dma/usernv04.o nvkm-y += nvkm/engine/dma/usernv50.o nvkm-y += nvkm/engine/dma/usergf100.o nvkm-y += nvkm/engine/dma/usergf119.o +nvkm-y += nvkm/engine/dma/usergv100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/dma/gv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/dma/gv100.c new file mode 100644 index 0000000000000..c65a4c2ea93d4 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/dma/gv100.c @@ -0,0 +1,34 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "priv.h" +#include "user.h" + +static const struct nvkm_dma_func +gv100_dma = { + .class_new = gv100_dmaobj_new, +}; + +int +gv100_dma_new(struct nvkm_device *device, int index, struct nvkm_dma **pdma) +{ + return nvkm_dma_new_(&gv100_dma, device, index, pdma); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/dma/user.h b/drivers/gpu/drm/nouveau/nvkm/engine/dma/user.h index 4bbac8a21c713..9fe01fd754746 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/dma/user.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/dma/user.h @@ -16,4 +16,6 @@ int gf100_dmaobj_new(struct nvkm_dma *, const struct nvkm_oclass *, void *, u32, struct nvkm_dmaobj **); int gf119_dmaobj_new(struct nvkm_dma *, const struct nvkm_oclass *, void *, u32, struct nvkm_dmaobj **); +int gv100_dmaobj_new(struct nvkm_dma *, const struct nvkm_oclass *, void *, u32, + struct nvkm_dmaobj **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/dma/usergv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/dma/usergv100.c new file mode 100644 index 0000000000000..39eba9fc82bea --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/dma/usergv100.c @@ -0,0 +1,119 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + */ +#define gv100_dmaobj(p) container_of((p), struct gv100_dmaobj, base) +#include "user.h" + +#include +#include +#include + +#include +#include + +struct gv100_dmaobj { + struct nvkm_dmaobj base; + u32 flags0; +}; + +static int +gv100_dmaobj_bind(struct nvkm_dmaobj *base, struct nvkm_gpuobj *parent, + int align, struct nvkm_gpuobj **pgpuobj) +{ + struct gv100_dmaobj *dmaobj = gv100_dmaobj(base); + struct nvkm_device *device = dmaobj->base.dma->engine.subdev.device; + u64 start = dmaobj->base.start >> 8; + u64 limit = dmaobj->base.limit >> 8; + int ret; + + ret = nvkm_gpuobj_new(device, 24, align, false, parent, pgpuobj); + if (ret == 0) { + nvkm_kmap(*pgpuobj); + nvkm_wo32(*pgpuobj, 0x00, dmaobj->flags0); + nvkm_wo32(*pgpuobj, 0x04, lower_32_bits(start)); + nvkm_wo32(*pgpuobj, 0x08, upper_32_bits(start)); + nvkm_wo32(*pgpuobj, 0x0c, lower_32_bits(limit)); + nvkm_wo32(*pgpuobj, 0x10, upper_32_bits(limit)); + nvkm_done(*pgpuobj); + } + + return ret; +} + +static const struct nvkm_dmaobj_func +gv100_dmaobj_func = { + .bind = gv100_dmaobj_bind, +}; + +int +gv100_dmaobj_new(struct nvkm_dma *dma, const struct nvkm_oclass *oclass, + void *data, u32 size, struct nvkm_dmaobj **pdmaobj) +{ + union { + struct gf119_dma_v0 v0; + } *args; + struct nvkm_object *parent = oclass->parent; + struct gv100_dmaobj *dmaobj; + u32 kind, page; + int ret; + + if (!(dmaobj = kzalloc(sizeof(*dmaobj), GFP_KERNEL))) + return -ENOMEM; + *pdmaobj = &dmaobj->base; + + ret = nvkm_dmaobj_ctor(&gv100_dmaobj_func, dma, oclass, + &data, &size, &dmaobj->base); + if (ret) + return ret; + + ret = -ENOSYS; + args = data; + + nvif_ioctl(parent, "create gv100 dma size %d\n", size); + if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { + nvif_ioctl(parent, + "create gv100 dma vers %d page %d kind %02x\n", + args->v0.version, args->v0.page, args->v0.kind); + kind = args->v0.kind != 0; + page = args->v0.page != 0; + } else + if (size == 0) { + kind = 0; + page = GF119_DMA_V0_PAGE_SP; + } else + return ret; + + if (kind) + dmaobj->flags0 |= 0x00100000; + if (page) + dmaobj->flags0 |= 0x00000040; + dmaobj->flags0 |= 0x00000004; /* rw */ + + switch (dmaobj->base.target) { + case NV_MEM_TARGET_VRAM : dmaobj->flags0 |= 0x00000001; break; + case NV_MEM_TARGET_PCI : dmaobj->flags0 |= 0x00000002; break; + case NV_MEM_TARGET_PCI_NOSNOOP: dmaobj->flags0 |= 0x00000003; break; + default: + return -EINVAL; + } + + return 0; +} From 290ffeafcc1a953aa287c8a7bf7f6d9af25b7e77 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:47 +1000 Subject: [PATCH 156/165] drm/nouveau/disp/gv100: initial support Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/class.h | 7 + drivers/gpu/drm/nouveau/include/nvif/clc37b.h | 11 + drivers/gpu/drm/nouveau/include/nvif/clc37e.h | 13 + .../drm/nouveau/include/nvkm/engine/disp.h | 1 + drivers/gpu/drm/nouveau/nvif/disp.c | 1 + .../gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + .../gpu/drm/nouveau/nvkm/engine/disp/Kbuild | 13 + .../drm/nouveau/nvkm/engine/disp/changv100.c | 34 ++ .../drm/nouveau/nvkm/engine/disp/channv50.h | 14 + .../drm/nouveau/nvkm/engine/disp/coregv100.c | 204 +++++++++ .../drm/nouveau/nvkm/engine/disp/cursgv100.c | 81 ++++ .../drm/nouveau/nvkm/engine/disp/dmacgv100.c | 77 ++++ .../gpu/drm/nouveau/nvkm/engine/disp/gv100.c | 427 ++++++++++++++++++ .../drm/nouveau/nvkm/engine/disp/hdmigv100.c | 85 ++++ .../gpu/drm/nouveau/nvkm/engine/disp/head.h | 4 + .../drm/nouveau/nvkm/engine/disp/headgf119.c | 2 +- .../drm/nouveau/nvkm/engine/disp/headgv100.c | 105 +++++ .../gpu/drm/nouveau/nvkm/engine/disp/ior.h | 10 +- .../gpu/drm/nouveau/nvkm/engine/disp/nv50.c | 9 +- .../gpu/drm/nouveau/nvkm/engine/disp/nv50.h | 9 +- .../drm/nouveau/nvkm/engine/disp/rootgv100.c | 52 +++ .../drm/nouveau/nvkm/engine/disp/rootnv50.h | 1 + .../drm/nouveau/nvkm/engine/disp/sorgm200.c | 6 +- .../drm/nouveau/nvkm/engine/disp/sorgv100.c | 120 +++++ .../drm/nouveau/nvkm/engine/disp/wimmgv100.c | 82 ++++ .../drm/nouveau/nvkm/engine/disp/wndwgv100.c | 184 ++++++++ 26 files changed, 1544 insertions(+), 9 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/include/nvif/clc37b.h create mode 100644 drivers/gpu/drm/nouveau/include/nvif/clc37e.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/changv100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/coregv100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgv100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgv100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/headgv100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgv100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/wimmgv100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/wndwgv100.c diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index a7c5bf5727883..8c9aa556be0ee 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -79,6 +79,7 @@ #define GM200_DISP /* cl5070.h */ 0x00009570 #define GP100_DISP /* cl5070.h */ 0x00009770 #define GP102_DISP /* cl5070.h */ 0x00009870 +#define GV100_DISP /* cl5070.h */ 0x0000c370 #define NV31_MPEG 0x00003174 #define G82_MPEG 0x00008274 @@ -90,6 +91,7 @@ #define GT214_DISP_CURSOR /* cl507a.h */ 0x0000857a #define GF110_DISP_CURSOR /* cl507a.h */ 0x0000907a #define GK104_DISP_CURSOR /* cl507a.h */ 0x0000917a +#define GV100_DISP_CURSOR /* cl507a.h */ 0x0000c37a #define NV50_DISP_OVERLAY /* cl507b.h */ 0x0000507b #define G82_DISP_OVERLAY /* cl507b.h */ 0x0000827b @@ -97,6 +99,8 @@ #define GF110_DISP_OVERLAY /* cl507b.h */ 0x0000907b #define GK104_DISP_OVERLAY /* cl507b.h */ 0x0000917b +#define GV100_DISP_WINDOW_IMM_CHANNEL_DMA /* clc37b.h */ 0x0000c37b + #define NV50_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000507c #define G82_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000827c #define GT200_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000837c @@ -117,6 +121,7 @@ #define GM200_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000957d #define GP100_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000977d #define GP102_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000987d +#define GV100_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000c37d #define NV50_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000507e #define G82_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000827e @@ -125,6 +130,8 @@ #define GF110_DISP_OVERLAY_CONTROL_DMA /* cl507e.h */ 0x0000907e #define GK104_DISP_OVERLAY_CONTROL_DMA /* cl507e.h */ 0x0000917e +#define GV100_DISP_WINDOW_CHANNEL_DMA /* clc37e.h */ 0x0000c37e + #define NV50_TESLA 0x00005097 #define G82_TESLA 0x00008297 #define GT200_TESLA 0x00008397 diff --git a/drivers/gpu/drm/nouveau/include/nvif/clc37b.h b/drivers/gpu/drm/nouveau/include/nvif/clc37b.h new file mode 100644 index 0000000000000..89b18189d43b3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/clc37b.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __NVIF_CLC37B_H__ +#define __NVIF_CLC37B_H__ + +struct nvc37b_window_imm_channel_dma_v0 { + __u8 version; + __u8 index; + __u8 pad02[6]; + __u64 pushbuf; +}; +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/clc37e.h b/drivers/gpu/drm/nouveau/include/nvif/clc37e.h new file mode 100644 index 0000000000000..899db9e915efa --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/clc37e.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __NVIF_CLC37E_H__ +#define __NVIF_CLC37E_H__ + +struct nvc37e_window_channel_dma_v0 { + __u8 version; + __u8 index; + __u8 pad02[6]; + __u64 pushbuf; +}; + +#define NVC37E_WINDOW_CHANNEL_DMA_V0_NTFY_UEVENT 0x00 +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h index e83193d3ccab6..ef7dc0844d26e 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h @@ -35,4 +35,5 @@ int gm107_disp_new(struct nvkm_device *, int, struct nvkm_disp **); int gm200_disp_new(struct nvkm_device *, int, struct nvkm_disp **); int gp100_disp_new(struct nvkm_device *, int, struct nvkm_disp **); int gp102_disp_new(struct nvkm_device *, int, struct nvkm_disp **); +int gv100_disp_new(struct nvkm_device *, int, struct nvkm_disp **); #endif diff --git a/drivers/gpu/drm/nouveau/nvif/disp.c b/drivers/gpu/drm/nouveau/nvif/disp.c index 7006482e8e297..18c7d064f75c8 100644 --- a/drivers/gpu/drm/nouveau/nvif/disp.c +++ b/drivers/gpu/drm/nouveau/nvif/disp.c @@ -34,6 +34,7 @@ int nvif_disp_ctor(struct nvif_device *device, s32 oclass, struct nvif_disp *disp) { static const struct nvif_mclass disps[] = { + { GV100_DISP, -1 }, { GP102_DISP, -1 }, { GP100_DISP, -1 }, { GM200_DISP, -1 }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index f2c3fe1cba2c6..43f6b7afdb52d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2416,6 +2416,7 @@ nv140_chipset = { .therm = gp100_therm_new, .timer = gk20a_timer_new, .top = gk104_top_new, + .disp = gv100_disp_new, .dma = gv100_dma_new, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild index b580581ef5b83..3d485dbf310a3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild @@ -14,12 +14,14 @@ nvkm-y += nvkm/engine/disp/gm107.o nvkm-y += nvkm/engine/disp/gm200.o nvkm-y += nvkm/engine/disp/gp100.o nvkm-y += nvkm/engine/disp/gp102.o +nvkm-y += nvkm/engine/disp/gv100.o nvkm-y += nvkm/engine/disp/vga.o nvkm-y += nvkm/engine/disp/head.o nvkm-y += nvkm/engine/disp/headnv04.o nvkm-y += nvkm/engine/disp/headnv50.o nvkm-y += nvkm/engine/disp/headgf119.o +nvkm-y += nvkm/engine/disp/headgv100.o nvkm-y += nvkm/engine/disp/ior.o nvkm-y += nvkm/engine/disp/dacnv50.o @@ -35,6 +37,7 @@ nvkm-y += nvkm/engine/disp/sorgf119.o nvkm-y += nvkm/engine/disp/sorgk104.o nvkm-y += nvkm/engine/disp/sorgm107.o nvkm-y += nvkm/engine/disp/sorgm200.o +nvkm-y += nvkm/engine/disp/sorgv100.o nvkm-y += nvkm/engine/disp/outp.o nvkm-y += nvkm/engine/disp/dp.o @@ -47,6 +50,7 @@ nvkm-y += nvkm/engine/disp/hdmig84.o nvkm-y += nvkm/engine/disp/hdmigt215.o nvkm-y += nvkm/engine/disp/hdmigf119.o nvkm-y += nvkm/engine/disp/hdmigk104.o +nvkm-y += nvkm/engine/disp/hdmigv100.o nvkm-y += nvkm/engine/disp/conn.o @@ -63,13 +67,16 @@ nvkm-y += nvkm/engine/disp/rootgm107.o nvkm-y += nvkm/engine/disp/rootgm200.o nvkm-y += nvkm/engine/disp/rootgp100.o nvkm-y += nvkm/engine/disp/rootgp102.o +nvkm-y += nvkm/engine/disp/rootgv100.o nvkm-y += nvkm/engine/disp/channv50.o nvkm-y += nvkm/engine/disp/changf119.o +nvkm-y += nvkm/engine/disp/changv100.o nvkm-y += nvkm/engine/disp/dmacnv50.o nvkm-y += nvkm/engine/disp/dmacgf119.o nvkm-y += nvkm/engine/disp/dmacgp102.o +nvkm-y += nvkm/engine/disp/dmacgv100.o nvkm-y += nvkm/engine/disp/basenv50.o nvkm-y += nvkm/engine/disp/baseg84.o @@ -82,6 +89,7 @@ nvkm-y += nvkm/engine/disp/coreg94.o nvkm-y += nvkm/engine/disp/coregf119.o nvkm-y += nvkm/engine/disp/coregk104.o nvkm-y += nvkm/engine/disp/coregp102.o +nvkm-y += nvkm/engine/disp/coregv100.o nvkm-y += nvkm/engine/disp/ovlynv50.o nvkm-y += nvkm/engine/disp/ovlyg84.o @@ -90,12 +98,17 @@ nvkm-y += nvkm/engine/disp/ovlygf119.o nvkm-y += nvkm/engine/disp/ovlygk104.o nvkm-y += nvkm/engine/disp/ovlygp102.o +nvkm-y += nvkm/engine/disp/wimmgv100.o + +nvkm-y += nvkm/engine/disp/wndwgv100.o + nvkm-y += nvkm/engine/disp/piocnv50.o nvkm-y += nvkm/engine/disp/piocgf119.o nvkm-y += nvkm/engine/disp/cursnv50.o nvkm-y += nvkm/engine/disp/cursgf119.o nvkm-y += nvkm/engine/disp/cursgp102.o +nvkm-y += nvkm/engine/disp/cursgv100.o nvkm-y += nvkm/engine/disp/oimmnv50.o nvkm-y += nvkm/engine/disp/oimmgf119.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/changv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/changv100.c new file mode 100644 index 0000000000000..75247c9c7e104 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/changv100.c @@ -0,0 +1,34 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "channv50.h" + +const struct nvkm_event_func +gv100_disp_chan_uevent = { + .ctor = nv50_disp_chan_uevent_ctor, +}; + +u64 +gv100_disp_chan_user(struct nv50_disp_chan *chan, u64 *psize) +{ + *psize = 0x1000; + return 0x690000 + ((chan->chid.user - 1) * 0x1000); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h index 391b007a68243..adc9d76d09cc9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h @@ -57,6 +57,11 @@ void gf119_disp_core_fini(struct nv50_disp_chan *); extern const struct nv50_disp_chan_func gp102_disp_dmac_func; +u64 gv100_disp_chan_user(struct nv50_disp_chan *, u64 *); +int gv100_disp_dmac_init(struct nv50_disp_chan *); +void gv100_disp_dmac_fini(struct nv50_disp_chan *); +int gv100_disp_dmac_bind(struct nv50_disp_chan *, struct nvkm_object *, u32); + int nv50_disp_curs_new_(const struct nv50_disp_chan_func *, struct nv50_disp *, int ctrl, int user, const struct nvkm_oclass *, void *argv, u32 argc, @@ -132,6 +137,15 @@ int gp102_disp_core_new(const struct nvkm_oclass *, void *, u32, int gp102_disp_ovly_new(const struct nvkm_oclass *, void *, u32, struct nv50_disp *, struct nvkm_object **); +int gv100_disp_curs_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); +int gv100_disp_wimm_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); +int gv100_disp_core_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); +int gv100_disp_wndw_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); + struct nv50_disp_mthd_list { u32 mthd; u32 addr; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregv100.c new file mode 100644 index 0000000000000..4592d0e69fec0 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/coregv100.c @@ -0,0 +1,204 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "channv50.h" + +#include + +const struct nv50_disp_mthd_list +gv100_disp_core_mthd_base = { + .mthd = 0x0000, + .addr = 0x000000, + .data = { + { 0x0200, 0x680200 }, + { 0x0208, 0x680208 }, + { 0x020c, 0x68020c }, + { 0x0210, 0x680210 }, + { 0x0214, 0x680214 }, + { 0x0218, 0x680218 }, + { 0x021c, 0x68021c }, + {} + } +}; + +const struct nv50_disp_mthd_list +gv100_disp_core_mthd_sor = { + .mthd = 0x0020, + .addr = 0x000020, + .data = { + { 0x0300, 0x680300 }, + { 0x0304, 0x680304 }, + { 0x0308, 0x680308 }, + { 0x030c, 0x68030c }, + {} + } +}; + +static const struct nv50_disp_mthd_list +gv100_disp_core_mthd_wndw = { + .mthd = 0x0080, + .addr = 0x000080, + .data = { + { 0x1000, 0x681000 }, + { 0x1004, 0x681004 }, + { 0x1008, 0x681008 }, + { 0x100c, 0x68100c }, + { 0x1010, 0x681010 }, + {} + } +}; + +static const struct nv50_disp_mthd_list +gv100_disp_core_mthd_head = { + .mthd = 0x0400, + .addr = 0x000400, + .data = { + { 0x2000, 0x682000 }, + { 0x2004, 0x682004 }, + { 0x2008, 0x682008 }, + { 0x200c, 0x68200c }, + { 0x2014, 0x682014 }, + { 0x2018, 0x682018 }, + { 0x201c, 0x68201c }, + { 0x2020, 0x682020 }, + { 0x2028, 0x682028 }, + { 0x202c, 0x68202c }, + { 0x2030, 0x682030 }, + { 0x2038, 0x682038 }, + { 0x203c, 0x68203c }, + { 0x2048, 0x682048 }, + { 0x204c, 0x68204c }, + { 0x2050, 0x682050 }, + { 0x2054, 0x682054 }, + { 0x2058, 0x682058 }, + { 0x205c, 0x68205c }, + { 0x2060, 0x682060 }, + { 0x2064, 0x682064 }, + { 0x2068, 0x682068 }, + { 0x206c, 0x68206c }, + { 0x2070, 0x682070 }, + { 0x2074, 0x682074 }, + { 0x2078, 0x682078 }, + { 0x207c, 0x68207c }, + { 0x2080, 0x682080 }, + { 0x2088, 0x682088 }, + { 0x2090, 0x682090 }, + { 0x209c, 0x68209c }, + { 0x20a0, 0x6820a0 }, + { 0x20a4, 0x6820a4 }, + { 0x20a8, 0x6820a8 }, + { 0x20ac, 0x6820ac }, + { 0x218c, 0x68218c }, + { 0x2194, 0x682194 }, + { 0x2198, 0x682198 }, + { 0x219c, 0x68219c }, + { 0x21a0, 0x6821a0 }, + { 0x21a4, 0x6821a4 }, + { 0x2214, 0x682214 }, + { 0x2218, 0x682218 }, + {} + } +}; + +static const struct nv50_disp_chan_mthd +gv100_disp_core_mthd = { + .name = "Core", + .addr = 0x000000, + .prev = 0x008000, + .data = { + { "Global", 1, &gv100_disp_core_mthd_base }, + { "SOR", 4, &gv100_disp_core_mthd_sor }, + { "WINDOW", 8, &gv100_disp_core_mthd_wndw }, + { "HEAD", 4, &gv100_disp_core_mthd_head }, + {} + } +}; + +static int +gv100_disp_core_idle(struct nv50_disp_chan *chan) +{ + struct nvkm_device *device = chan->disp->base.engine.subdev.device; + nvkm_msec(device, 2000, + u32 stat = nvkm_rd32(device, 0x610630); + if ((stat & 0x001f0000) == 0x000b0000) + return 0; + ); + return -EBUSY; +} + +static u64 +gv100_disp_core_user(struct nv50_disp_chan *chan, u64 *psize) +{ + *psize = 0x10000; + return 0x680000; +} + +static void +gv100_disp_core_intr(struct nv50_disp_chan *chan, bool en) +{ + struct nvkm_device *device = chan->disp->base.engine.subdev.device; + const u32 mask = 0x00000001; + const u32 data = en ? mask : 0; + nvkm_mask(device, 0x611dac, mask, data); +} + +static void +gv100_disp_core_fini(struct nv50_disp_chan *chan) +{ + struct nvkm_device *device = chan->disp->base.engine.subdev.device; + nvkm_mask(device, 0x6104e0, 0x00000010, 0x00000000); + gv100_disp_core_idle(chan); + nvkm_mask(device, 0x6104e0, 0x00000002, 0x00000000); +} + +static int +gv100_disp_core_init(struct nv50_disp_chan *chan) +{ + struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; + struct nvkm_device *device = subdev->device; + + nvkm_wr32(device, 0x610b24, lower_32_bits(chan->push)); + nvkm_wr32(device, 0x610b20, upper_32_bits(chan->push)); + nvkm_wr32(device, 0x610b28, 0x00000001); + nvkm_wr32(device, 0x610b2c, 0x00000040); + + nvkm_mask(device, 0x6104e0, 0x00000010, 0x00000010); + nvkm_wr32(device, 0x680000, 0x00000000); + nvkm_wr32(device, 0x6104e0, 0x00000013); + return gv100_disp_core_idle(chan); +} + +static const struct nv50_disp_chan_func +gv100_disp_core = { + .init = gv100_disp_core_init, + .fini = gv100_disp_core_fini, + .intr = gv100_disp_core_intr, + .user = gv100_disp_core_user, + .bind = gv100_disp_dmac_bind, +}; + +int +gv100_disp_core_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_core_new_(&gv100_disp_core, &gv100_disp_core_mthd, + disp, 0, oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgv100.c new file mode 100644 index 0000000000000..a3e4f69002458 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgv100.c @@ -0,0 +1,81 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "channv50.h" + +#include + +static int +gv100_disp_curs_idle(struct nv50_disp_chan *chan) +{ + struct nvkm_device *device = chan->disp->base.engine.subdev.device; + const u32 soff = (chan->chid.ctrl - 1) * 0x04; + nvkm_msec(device, 2000, + u32 stat = nvkm_rd32(device, 0x610664 + soff); + if ((stat & 0x00070000) == 0x00040000) + return 0; + ); + return -EBUSY; +} + +static void +gv100_disp_curs_intr(struct nv50_disp_chan *chan, bool en) +{ + struct nvkm_device *device = chan->disp->base.engine.subdev.device; + const u32 mask = 0x00010000 << chan->head; + const u32 data = en ? mask : 0; + nvkm_mask(device, 0x611dac, mask, data); +} + +static void +gv100_disp_curs_fini(struct nv50_disp_chan *chan) +{ + struct nvkm_device *device = chan->disp->base.engine.subdev.device; + const u32 hoff = chan->chid.ctrl * 4; + nvkm_mask(device, 0x6104e0 + hoff, 0x00000010, 0x00000010); + gv100_disp_curs_idle(chan); + nvkm_mask(device, 0x6104e0 + hoff, 0x00000001, 0x00000000); +} + +static int +gv100_disp_curs_init(struct nv50_disp_chan *chan) +{ + struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; + struct nvkm_device *device = subdev->device; + nvkm_wr32(device, 0x6104e0 + chan->chid.ctrl * 4, 0x00000001); + return gv100_disp_curs_idle(chan); +} + +static const struct nv50_disp_chan_func +gv100_disp_curs = { + .init = gv100_disp_curs_init, + .fini = gv100_disp_curs_fini, + .intr = gv100_disp_curs_intr, + .user = gv100_disp_chan_user, +}; + +int +gv100_disp_curs_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return nv50_disp_curs_new_(&gv100_disp_curs, disp, 73, 73, + oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgv100.c new file mode 100644 index 0000000000000..eac0e42da3542 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgv100.c @@ -0,0 +1,77 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "channv50.h" + +#include +#include + +static int +gv100_disp_dmac_idle(struct nv50_disp_chan *chan) +{ + struct nvkm_device *device = chan->disp->base.engine.subdev.device; + const u32 soff = (chan->chid.ctrl - 1) * 0x04; + nvkm_msec(device, 2000, + u32 stat = nvkm_rd32(device, 0x610664 + soff); + if ((stat & 0x000f0000) == 0x00040000) + return 0; + ); + return -EBUSY; +} + +int +gv100_disp_dmac_bind(struct nv50_disp_chan *chan, + struct nvkm_object *object, u32 handle) +{ + return nvkm_ramht_insert(chan->disp->ramht, object, + chan->chid.user, -9, handle, + chan->chid.user << 25 | 0x00000040); +} + +void +gv100_disp_dmac_fini(struct nv50_disp_chan *chan) +{ + struct nvkm_device *device = chan->disp->base.engine.subdev.device; + const u32 coff = chan->chid.ctrl * 0x04; + nvkm_mask(device, 0x6104e0 + coff, 0x00000010, 0x00000000); + gv100_disp_dmac_idle(chan); + nvkm_mask(device, 0x6104e0 + coff, 0x00000002, 0x00000000); +} + +int +gv100_disp_dmac_init(struct nv50_disp_chan *chan) +{ + struct nvkm_subdev *subdev = &chan->disp->base.engine.subdev; + struct nvkm_device *device = subdev->device; + const u32 uoff = (chan->chid.ctrl - 1) * 0x1000; + const u32 poff = chan->chid.ctrl * 0x10; + const u32 coff = chan->chid.ctrl * 0x04; + + nvkm_wr32(device, 0x610b24 + poff, lower_32_bits(chan->push)); + nvkm_wr32(device, 0x610b20 + poff, upper_32_bits(chan->push)); + nvkm_wr32(device, 0x610b28 + poff, 0x00000001); + nvkm_wr32(device, 0x610b2c + poff, 0x00000040); + + nvkm_mask(device, 0x6104e0 + coff, 0x00000010, 0x00000010); + nvkm_wr32(device, 0x690000 + uoff, 0x00000000); + nvkm_wr32(device, 0x6104e0 + coff, 0x00000013); + return gv100_disp_dmac_idle(chan); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c new file mode 100644 index 0000000000000..d0a7e3456da16 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c @@ -0,0 +1,427 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "nv50.h" +#include "head.h" +#include "ior.h" +#include "channv50.h" +#include "rootnv50.h" + +#include +#include + +static int +gv100_disp_wndw_cnt(struct nvkm_disp *disp, unsigned long *pmask) +{ + struct nvkm_device *device = disp->engine.subdev.device; + *pmask = nvkm_rd32(device, 0x610064); + return (nvkm_rd32(device, 0x610074) & 0x03f00000) >> 20; +} + +static void +gv100_disp_super(struct work_struct *work) +{ + struct nv50_disp *disp = + container_of(work, struct nv50_disp, supervisor); + struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_device *device = subdev->device; + struct nvkm_head *head; + u32 stat = nvkm_rd32(device, 0x6107a8); + u32 mask[4]; + + nvkm_debug(subdev, "supervisor %d: %08x\n", ffs(disp->super), stat); + list_for_each_entry(head, &disp->base.head, head) { + mask[head->id] = nvkm_rd32(device, 0x6107ac + (head->id * 4)); + HEAD_DBG(head, "%08x", mask[head->id]); + } + + if (disp->super & 0x00000001) { + nv50_disp_chan_mthd(disp->chan[0], NV_DBG_DEBUG); + nv50_disp_super_1(disp); + list_for_each_entry(head, &disp->base.head, head) { + if (!(mask[head->id] & 0x00001000)) + continue; + nv50_disp_super_1_0(disp, head); + } + } else + if (disp->super & 0x00000002) { + list_for_each_entry(head, &disp->base.head, head) { + if (!(mask[head->id] & 0x00001000)) + continue; + nv50_disp_super_2_0(disp, head); + } + nvkm_outp_route(&disp->base); + list_for_each_entry(head, &disp->base.head, head) { + if (!(mask[head->id] & 0x00010000)) + continue; + nv50_disp_super_2_1(disp, head); + } + list_for_each_entry(head, &disp->base.head, head) { + if (!(mask[head->id] & 0x00001000)) + continue; + nv50_disp_super_2_2(disp, head); + } + } else + if (disp->super & 0x00000004) { + list_for_each_entry(head, &disp->base.head, head) { + if (!(mask[head->id] & 0x00001000)) + continue; + nv50_disp_super_3_0(disp, head); + } + } + + list_for_each_entry(head, &disp->base.head, head) + nvkm_wr32(device, 0x6107ac + (head->id * 4), 0x00000000); + nvkm_wr32(device, 0x6107a8, 0x80000000); +} + +static void +gv100_disp_exception(struct nv50_disp *disp, int chid) +{ + struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_device *device = subdev->device; + u32 stat = nvkm_rd32(device, 0x611020 + (chid * 12)); + u32 type = (stat & 0x00007000) >> 12; + u32 mthd = (stat & 0x00000fff) << 2; + u32 data = nvkm_rd32(device, 0x611024 + (chid * 12)); + u32 code = nvkm_rd32(device, 0x611028 + (chid * 12)); + + nvkm_error(subdev, "chid %d %08x [type %d mthd %04x] " + "data %08x code %08x\n", + chid, stat, type, mthd, data, code); + + if (chid < ARRAY_SIZE(disp->chan) && disp->chan[chid]) { + switch (mthd) { + case 0x0200: + nv50_disp_chan_mthd(disp->chan[chid], NV_DBG_ERROR); + break; + default: + break; + } + } + + nvkm_wr32(device, 0x611020 + (chid * 12), 0x90000000); +} + +static void +gv100_disp_intr_ctrl_disp(struct nv50_disp *disp) +{ + struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_device *device = subdev->device; + u32 stat = nvkm_rd32(device, 0x611c30); + + if (stat & 0x00000007) { + disp->super = (stat & 0x00000007); + queue_work(disp->wq, &disp->supervisor); + nvkm_wr32(device, 0x611860, disp->super); + stat &= ~0x00000007; + } + + /*TODO: I would guess this is VBIOS_RELEASE, however, NFI how to + * ACK it, nor does RM appear to bother. + */ + if (stat & 0x00000008) + stat &= ~0x00000008; + + if (stat & 0x00000100) { + unsigned long wndws = nvkm_rd32(device, 0x611858); + unsigned long other = nvkm_rd32(device, 0x61185c); + int wndw; + + nvkm_wr32(device, 0x611858, wndws); + nvkm_wr32(device, 0x61185c, other); + + /* AWAKEN_OTHER_CORE. */ + if (other & 0x00000001) + nv50_disp_chan_uevent_send(disp, 0); + + /* AWAKEN_WIN_CH(n). */ + for_each_set_bit(wndw, &wndws, disp->wndw.nr) { + nv50_disp_chan_uevent_send(disp, 1 + wndw); + } + } + + if (stat) + nvkm_warn(subdev, "ctrl %08x\n", stat); +} + +static void +gv100_disp_intr_exc_other(struct nv50_disp *disp) +{ + struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_device *device = subdev->device; + u32 stat = nvkm_rd32(device, 0x611854); + unsigned long mask; + int head; + + if (stat & 0x00000001) { + nvkm_wr32(device, 0x611854, 0x00000001); + gv100_disp_exception(disp, 0); + stat &= ~0x00000001; + } + + if ((mask = (stat & 0x00ff0000) >> 16)) { + for_each_set_bit(head, &mask, disp->wndw.nr) { + nvkm_wr32(device, 0x611854, 0x00010000 << head); + gv100_disp_exception(disp, 73 + head); + stat &= ~(0x00010000 << head); + } + } + + if (stat) { + nvkm_warn(subdev, "exception %08x\n", stat); + nvkm_wr32(device, 0x611854, stat); + } +} + +static void +gv100_disp_intr_exc_winim(struct nv50_disp *disp) +{ + struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_device *device = subdev->device; + unsigned long stat = nvkm_rd32(device, 0x611850); + int wndw; + + for_each_set_bit(wndw, &stat, disp->wndw.nr) { + nvkm_wr32(device, 0x611850, BIT(wndw)); + gv100_disp_exception(disp, 33 + wndw); + stat &= ~BIT(wndw); + } + + if (stat) { + nvkm_warn(subdev, "wimm %08x\n", (u32)stat); + nvkm_wr32(device, 0x611850, stat); + } +} + +static void +gv100_disp_intr_exc_win(struct nv50_disp *disp) +{ + struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_device *device = subdev->device; + unsigned long stat = nvkm_rd32(device, 0x61184c); + int wndw; + + for_each_set_bit(wndw, &stat, disp->wndw.nr) { + nvkm_wr32(device, 0x61184c, BIT(wndw)); + gv100_disp_exception(disp, 1 + wndw); + stat &= ~BIT(wndw); + } + + if (stat) { + nvkm_warn(subdev, "wndw %08x\n", (u32)stat); + nvkm_wr32(device, 0x61184c, stat); + } +} + +static void +gv100_disp_intr_head_timing(struct nv50_disp *disp, int head) +{ + struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_device *device = subdev->device; + u32 stat = nvkm_rd32(device, 0x611800 + (head * 0x04)); + + /* LAST_DATA, LOADV. */ + if (stat & 0x00000003) { + nvkm_wr32(device, 0x611800 + (head * 0x04), stat & 0x00000003); + stat &= ~0x00000003; + } + + if (stat & 0x00000004) { + nvkm_disp_vblank(&disp->base, head); + nvkm_wr32(device, 0x611800 + (head * 0x04), 0x00000004); + stat &= ~0x00000004; + } + + if (stat) { + nvkm_warn(subdev, "head %08x\n", stat); + nvkm_wr32(device, 0x611800 + (head * 0x04), stat); + } +} + +static void +gv100_disp_intr(struct nv50_disp *disp) +{ + struct nvkm_subdev *subdev = &disp->base.engine.subdev; + struct nvkm_device *device = subdev->device; + u32 stat = nvkm_rd32(device, 0x611ec0); + unsigned long mask; + int head; + + if ((mask = (stat & 0x000000ff))) { + for_each_set_bit(head, &mask, 8) { + gv100_disp_intr_head_timing(disp, head); + stat &= ~BIT(head); + } + } + + if (stat & 0x00000200) { + gv100_disp_intr_exc_win(disp); + stat &= ~0x00000200; + } + + if (stat & 0x00000400) { + gv100_disp_intr_exc_winim(disp); + stat &= ~0x00000400; + } + + if (stat & 0x00000800) { + gv100_disp_intr_exc_other(disp); + stat &= ~0x00000800; + } + + if (stat & 0x00001000) { + gv100_disp_intr_ctrl_disp(disp); + stat &= ~0x00001000; + } + + if (stat) + nvkm_warn(subdev, "intr %08x\n", stat); +} + +static void +gv100_disp_fini(struct nv50_disp *disp) +{ + struct nvkm_device *device = disp->base.engine.subdev.device; + nvkm_wr32(device, 0x611db0, 0x00000000); +} + +static int +gv100_disp_init(struct nv50_disp *disp) +{ + struct nvkm_device *device = disp->base.engine.subdev.device; + struct nvkm_head *head; + int i, j; + u32 tmp; + + /* Claim ownership of display. */ + if (nvkm_rd32(device, 0x6254e8) & 0x00000002) { + nvkm_mask(device, 0x6254e8, 0x00000001, 0x00000000); + if (nvkm_msec(device, 2000, + if (!(nvkm_rd32(device, 0x6254e8) & 0x00000002)) + break; + ) < 0) + return -EBUSY; + } + + /* Lock pin capabilities. */ + tmp = nvkm_rd32(device, 0x610068); + nvkm_wr32(device, 0x640008, tmp); + + /* SOR capabilities. */ + for (i = 0; i < disp->sor.nr; i++) { + tmp = nvkm_rd32(device, 0x61c000 + (i * 0x800)); + nvkm_mask(device, 0x640000, 0x00000100 << i, 0x00000100 << i); + nvkm_wr32(device, 0x640144 + (i * 0x08), tmp); + } + + /* Head capabilities. */ + list_for_each_entry(head, &disp->base.head, head) { + const int id = head->id; + + /* RG. */ + tmp = nvkm_rd32(device, 0x616300 + (id * 0x800)); + nvkm_wr32(device, 0x640048 + (id * 0x020), tmp); + + /* POSTCOMP. */ + for (j = 0; j < 6 * 4; j += 4) { + tmp = nvkm_rd32(device, 0x616100 + (id * 0x800) + j); + nvkm_wr32(device, 0x640030 + (id * 0x20) + j, tmp); + } + } + + /* Window capabilities. */ + for (i = 0; i < disp->wndw.nr; i++) { + nvkm_mask(device, 0x640004, 1 << i, 1 << i); + for (j = 0; j < 6 * 4; j += 4) { + tmp = nvkm_rd32(device, 0x630050 + (i * 0x800) + j); + nvkm_wr32(device, 0x6401e4 + (i * 0x20) + j, tmp); + } + } + + /* IHUB capabilities. */ + for (i = 0; i < 4; i++) { + tmp = nvkm_rd32(device, 0x62e000 + (i * 0x04)); + nvkm_wr32(device, 0x640010 + (i * 0x04), tmp); + } + + nvkm_mask(device, 0x610078, 0x00000001, 0x00000001); + + /* Setup instance memory. */ + switch (nvkm_memory_target(disp->inst->memory)) { + case NVKM_MEM_TARGET_VRAM: tmp = 0x00000001; break; + case NVKM_MEM_TARGET_NCOH: tmp = 0x00000002; break; + case NVKM_MEM_TARGET_HOST: tmp = 0x00000003; break; + default: + break; + } + nvkm_wr32(device, 0x610010, 0x00000008 | tmp); + nvkm_wr32(device, 0x610014, disp->inst->addr >> 16); + + /* CTRL_DISP: AWAKEN, ERROR, SUPERVISOR[1-3]. */ + nvkm_wr32(device, 0x611cf0, 0x00000187); /* MSK. */ + nvkm_wr32(device, 0x611db0, 0x00000187); /* EN. */ + + /* EXC_OTHER: CURSn, CORE. */ + nvkm_wr32(device, 0x611cec, disp->head.mask << 16 | + 0x00000001); /* MSK. */ + nvkm_wr32(device, 0x611dac, 0x00000000); /* EN. */ + + /* EXC_WINIM. */ + nvkm_wr32(device, 0x611ce8, disp->wndw.mask); /* MSK. */ + nvkm_wr32(device, 0x611da8, 0x00000000); /* EN. */ + + /* EXC_WIN. */ + nvkm_wr32(device, 0x611ce4, disp->wndw.mask); /* MSK. */ + nvkm_wr32(device, 0x611da4, 0x00000000); /* EN. */ + + /* HEAD_TIMING(n): VBLANK. */ + list_for_each_entry(head, &disp->base.head, head) { + const u32 hoff = head->id * 4; + nvkm_wr32(device, 0x611cc0 + hoff, 0x00000004); /* MSK. */ + nvkm_wr32(device, 0x611d80 + hoff, 0x00000000); /* EN. */ + } + + /* OR. */ + nvkm_wr32(device, 0x611cf4, 0x00000000); /* MSK. */ + nvkm_wr32(device, 0x611db4, 0x00000000); /* EN. */ + return 0; +} + +static const struct nv50_disp_func +gv100_disp = { + .init = gv100_disp_init, + .fini = gv100_disp_fini, + .intr = gv100_disp_intr, + .uevent = &gv100_disp_chan_uevent, + .super = gv100_disp_super, + .root = &gv100_disp_root_oclass, + .wndw = { .cnt = gv100_disp_wndw_cnt }, + .head = { .cnt = gv100_head_cnt, .new = gv100_head_new }, + .sor = { .cnt = gv100_sor_cnt, .new = gv100_sor_new }, + .ramht_size = 0x2000, +}; + +int +gv100_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) +{ + return nv50_disp_new_(&gv100_disp, device, index, pdisp); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c new file mode 100644 index 0000000000000..6e3c450eaacef --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c @@ -0,0 +1,85 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "hdmi.h" + +void +gv100_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet, + u8 rekey, u8 *avi, u8 avi_size, u8 *vendor, u8 vendor_size) +{ + struct nvkm_device *device = ior->disp->engine.subdev.device; + const u32 ctrl = 0x40000000 * enable | + max_ac_packet << 16 | + rekey; + const u32 hoff = head * 0x800; + const u32 hdmi = head * 0x400; + struct packed_hdmi_infoframe avi_infoframe; + struct packed_hdmi_infoframe vendor_infoframe; + + pack_hdmi_infoframe(&avi_infoframe, avi, avi_size); + pack_hdmi_infoframe(&vendor_infoframe, vendor, vendor_size); + + if (!(ctrl & 0x40000000)) { + nvkm_mask(device, 0x6165c0 + hoff, 0x40000000, 0x00000000); + nvkm_mask(device, 0x6f0100 + hdmi, 0x00000001, 0x00000000); + nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000000); + nvkm_mask(device, 0x6f0000 + hdmi, 0x00000001, 0x00000000); + return; + } + + /* AVI InfoFrame (AVI). */ + nvkm_mask(device, 0x6f0000 + hdmi, 0x00000001, 0x00000000); + if (avi_size) { + nvkm_wr32(device, 0x6f0008 + hdmi, avi_infoframe.header); + nvkm_wr32(device, 0x6f000c + hdmi, avi_infoframe.subpack0_low); + nvkm_wr32(device, 0x6f0010 + hdmi, avi_infoframe.subpack0_high); + nvkm_wr32(device, 0x6f0014 + hdmi, avi_infoframe.subpack1_low); + nvkm_wr32(device, 0x6f0018 + hdmi, avi_infoframe.subpack1_high); + nvkm_mask(device, 0x6f0000 + hdmi, 0x00000001, 0x00000001); + } + + /* Vendor-specific InfoFrame (VSI). */ + nvkm_mask(device, 0x6f0100 + hdmi, 0x00010001, 0x00000000); + if (vendor_size) { + 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, 0x00000000); + nvkm_wr32(device, 0x6f0114 + hdmi, 0x00000000); + nvkm_wr32(device, 0x6f0118 + hdmi, 0x00000000); + nvkm_wr32(device, 0x6f011c + hdmi, 0x00000000); + nvkm_wr32(device, 0x6f0120 + hdmi, 0x00000000); + nvkm_wr32(device, 0x6f0124 + hdmi, 0x00000000); + nvkm_mask(device, 0x6f0100 + hdmi, 0x00000001, 0x00000001); + } + + + /* General Control (GCP). */ + nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000000); + nvkm_wr32(device, 0x6f00cc + hdmi, 0x00000010); + nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000001); + + /* Audio Clock Regeneration (ACR). */ + nvkm_wr32(device, 0x6f0080 + hdmi, 0x82000000); + + /* NV_PDISP_SF_HDMI_CTRL. */ + nvkm_mask(device, 0x6165c0 + hoff, 0x401f007f, ctrl); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h index 4a5d7892ff549..7d55faf52fcb3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h @@ -58,4 +58,8 @@ int nv50_head_new(struct nvkm_disp *, int id); int gf119_head_cnt(struct nvkm_disp *, unsigned long *); int gf119_head_new(struct nvkm_disp *, int id); +void gf119_head_rgclk(struct nvkm_head *, int); + +int gv100_head_cnt(struct nvkm_disp *, unsigned long *); +int gv100_head_new(struct nvkm_disp *, int id); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c index bcbdaaf8ba202..e86298b359025 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c @@ -39,7 +39,7 @@ gf119_head_vblank_get(struct nvkm_head *head) nvkm_mask(device, 0x6100c0 + hoff, 0x00000001, 0x00000001); } -static void +void gf119_head_rgclk(struct nvkm_head *head, int div) { struct nvkm_device *device = head->disp->engine.subdev.device; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgv100.c new file mode 100644 index 0000000000000..1a061b42ae5c3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgv100.c @@ -0,0 +1,105 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "head.h" + +static void +gv100_head_vblank_put(struct nvkm_head *head) +{ + struct nvkm_device *device = head->disp->engine.subdev.device; + nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000004, 0x00000000); +} + +static void +gv100_head_vblank_get(struct nvkm_head *head) +{ + struct nvkm_device *device = head->disp->engine.subdev.device; + nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000004, 0x00000004); +} + +static void +gv100_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline) +{ + struct nvkm_device *device = head->disp->engine.subdev.device; + const u32 hoff = head->id * 0x800; + /* vline read locks hline. */ + *vline = nvkm_rd32(device, 0x616330 + hoff) & 0x0000ffff; + *hline = nvkm_rd32(device, 0x616334 + hoff) & 0x0000ffff; +} + +static void +gv100_head_state(struct nvkm_head *head, struct nvkm_head_state *state) +{ + struct nvkm_device *device = head->disp->engine.subdev.device; + const u32 hoff = (state == &head->arm) * 0x8000 + head->id * 0x400; + u32 data; + + data = nvkm_rd32(device, 0x682064 + hoff); + state->vtotal = (data & 0xffff0000) >> 16; + state->htotal = (data & 0x0000ffff); + data = nvkm_rd32(device, 0x682068 + hoff); + state->vsynce = (data & 0xffff0000) >> 16; + state->hsynce = (data & 0x0000ffff); + data = nvkm_rd32(device, 0x68206c + hoff); + state->vblanke = (data & 0xffff0000) >> 16; + state->hblanke = (data & 0x0000ffff); + data = nvkm_rd32(device, 0x682070 + hoff); + state->vblanks = (data & 0xffff0000) >> 16; + state->hblanks = (data & 0x0000ffff); + state->hz = nvkm_rd32(device, 0x68200c + hoff); + + data = nvkm_rd32(device, 0x682004 + hoff); + switch ((data & 0x000000f0) >> 4) { + case 5: state->or.depth = 30; break; + case 4: state->or.depth = 24; break; + case 1: state->or.depth = 18; break; + default: + state->or.depth = 18; + WARN_ON(1); + break; + } +} + +static const struct nvkm_head_func +gv100_head = { + .state = gv100_head_state, + .rgpos = gv100_head_rgpos, + .rgclk = gf119_head_rgclk, + .vblank_get = gv100_head_vblank_get, + .vblank_put = gv100_head_vblank_put, +}; + +int +gv100_head_new(struct nvkm_disp *disp, int id) +{ + struct nvkm_device *device = disp->engine.subdev.device; + if (!(nvkm_rd32(device, 0x610060) & (0x00000001 << id))) + return 0; + return nvkm_head_new_(&gv100_head, disp, id); +} + +int +gv100_head_cnt(struct nvkm_disp *disp, unsigned long *pmask) +{ + struct nvkm_device *device = disp->engine.subdev.device; + *pmask = nvkm_rd32(device, 0x610060) & 0x000000ff; + return nvkm_rd32(device, 0x610074) & 0x0000000f; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h index 9d43ab23f4d0f..e0b4e0c5704ee 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h @@ -30,7 +30,7 @@ struct nvkm_ior { UNKNOWN } proto:3; unsigned link:2; - unsigned head:4; + unsigned head:8; } arm, asy; /* Armed DP state. */ @@ -133,10 +133,15 @@ void gf119_sor_dp_watermark(struct nvkm_ior *, int, u8); void gm107_sor_dp_pattern(struct nvkm_ior *, int); +void gm200_sor_route_set(struct nvkm_outp *, struct nvkm_ior *); +int gm200_sor_route_get(struct nvkm_outp *, int *); +void gm200_sor_dp_drive(struct nvkm_ior *, int, int, int, int, int); + void g84_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8); void gt215_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8); void gf119_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8); void gk104_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8); +void gv100_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8); void gt215_hda_hpd(struct nvkm_ior *, int, bool); void gt215_hda_eld(struct nvkm_ior *, u8 *, u8); @@ -178,4 +183,7 @@ int gf119_sor_new(struct nvkm_disp *, int); int gk104_sor_new(struct nvkm_disp *, int); int gm107_sor_new(struct nvkm_disp *, int); int gm200_sor_new(struct nvkm_disp *, int); + +int gv100_sor_cnt(struct nvkm_disp *, unsigned long *); +int gv100_sor_new(struct nvkm_disp *, int); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c index 4a37c44fcbed6..f89c7b977aa5d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c @@ -88,6 +88,12 @@ nv50_disp_oneinit_(struct nvkm_disp *base) struct nvkm_device *device = subdev->device; int ret, i; + if (func->wndw.cnt) { + disp->wndw.nr = func->wndw.cnt(&disp->base, &disp->wndw.mask); + nvkm_debug(subdev, "Window(s): %d (%08lx)\n", + disp->wndw.nr, disp->wndw.mask); + } + disp->head.nr = func->head.cnt(&disp->base, &disp->head.mask); nvkm_debug(subdev, " Head(s): %d (%02lx)\n", disp->head.nr, disp->head.mask); @@ -133,7 +139,8 @@ nv50_disp_oneinit_(struct nvkm_disp *base) if (ret) return ret; - return nvkm_ramht_new(device, 0x1000, 0, disp->inst, &disp->ramht); + return nvkm_ramht_new(device, func->ramht_size ? func->ramht_size : + 0x1000, 0, disp->inst, &disp->ramht); } static const struct nvkm_disp_func diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h index 77aa2c8cfcd6a..8580382ab2489 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h @@ -18,7 +18,7 @@ struct nv50_disp { struct { unsigned long mask; int nr; - } head, dac; + } wndw, head, dac; struct { unsigned long mask; @@ -35,7 +35,7 @@ struct nv50_disp { struct nvkm_gpuobj *inst; struct nvkm_ramht *ramht; - struct nv50_disp_chan *chan[21]; + struct nv50_disp_chan *chan[81]; }; void nv50_disp_super_1(struct nv50_disp *); @@ -62,7 +62,9 @@ struct nv50_disp_func { struct { int (*cnt)(struct nvkm_disp *, unsigned long *mask); int (*new)(struct nvkm_disp *, int id); - } head, dac, sor, pior; + } wndw, head, dac, sor, pior; + + u16 ramht_size; }; int nv50_disp_init(struct nv50_disp *); @@ -86,4 +88,5 @@ int nv50_disp_chan_uevent_ctor(struct nvkm_object *, void *, u32, void nv50_disp_chan_uevent_send(struct nv50_disp *, int); extern const struct nvkm_event_func gf119_disp_chan_uevent; +extern const struct nvkm_event_func gv100_disp_chan_uevent; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgv100.c new file mode 100644 index 0000000000000..9c658d632d372 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgv100.c @@ -0,0 +1,52 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "rootnv50.h" +#include "channv50.h" + +#include + +static const struct nv50_disp_root_func +gv100_disp_root = { + .user = { + {{0,0,GV100_DISP_CURSOR }, gv100_disp_curs_new }, + {{0,0,GV100_DISP_WINDOW_IMM_CHANNEL_DMA}, gv100_disp_wimm_new }, + {{0,0,GV100_DISP_CORE_CHANNEL_DMA }, gv100_disp_core_new }, + {{0,0,GV100_DISP_WINDOW_CHANNEL_DMA }, gv100_disp_wndw_new }, + {} + }, +}; + +static int +gv100_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass, + void *data, u32 size, struct nvkm_object **pobject) +{ + return nv50_disp_root_new_(&gv100_disp_root, disp, oclass, + data, size, pobject); +} + +const struct nvkm_disp_oclass +gv100_disp_root_oclass = { + .base.oclass = GV100_DISP, + .base.minver = -1, + .base.maxver = -1, + .ctor = gv100_disp_root_new, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h index 9983a424d30db..6ca4f9184b515 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h @@ -36,4 +36,5 @@ extern const struct nvkm_disp_oclass gm107_disp_root_oclass; extern const struct nvkm_disp_oclass gm200_disp_root_oclass; extern const struct nvkm_disp_oclass gp100_disp_root_oclass; extern const struct nvkm_disp_oclass gp102_disp_root_oclass; +extern const struct nvkm_disp_oclass gv100_disp_root_oclass; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c index 8bc019b6ffaba..d892bdf040348 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c @@ -23,7 +23,7 @@ */ #include "ior.h" -static void +void gm200_sor_dp_drive(struct nvkm_ior *sor, int ln, int pc, int dc, int pe, int pu) { struct nvkm_device *device = sor->disp->engine.subdev.device; @@ -45,7 +45,7 @@ gm200_sor_dp_drive(struct nvkm_ior *sor, int ln, int pc, int dc, int pe, int pu) nvkm_wr32(device, 0x61c13c + loff, data[3] | (pc << shift)); } -static void +void gm200_sor_route_set(struct nvkm_outp *outp, struct nvkm_ior *ior) { struct nvkm_device *device = outp->disp->engine.subdev.device; @@ -62,7 +62,7 @@ gm200_sor_route_set(struct nvkm_outp *outp, struct nvkm_ior *ior) nvkm_mask(device, 0x612388 + moff, 0x0000001f, link << 4 | sor); } -static int +int gm200_sor_route_get(struct nvkm_outp *outp, int *link) { struct nvkm_device *device = outp->disp->engine.subdev.device; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c new file mode 100644 index 0000000000000..040db8a338de2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c @@ -0,0 +1,120 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "ior.h" + +#include + +static void +gv100_sor_dp_watermark(struct nvkm_ior *sor, int head, u8 watermark) +{ + struct nvkm_device *device = sor->disp->engine.subdev.device; + const u32 hoff = head * 0x800; + nvkm_mask(device, 0x616550 + hoff, 0x0c00003f, 0x08000000 | watermark); +} + +static void +gv100_sor_dp_audio_sym(struct nvkm_ior *sor, int head, u16 h, u32 v) +{ + struct nvkm_device *device = sor->disp->engine.subdev.device; + const u32 hoff = head * 0x800; + nvkm_mask(device, 0x616568 + hoff, 0x0000ffff, h); + nvkm_mask(device, 0x61656c + hoff, 0x00ffffff, v); +} + +static void +gv100_sor_dp_audio(struct nvkm_ior *sor, int head, bool enable) +{ + struct nvkm_device *device = sor->disp->engine.subdev.device; + const u32 hoff = 0x800 * head; + const u32 data = 0x80000000 | (0x00000001 * enable); + const u32 mask = 0x8000000d; + nvkm_mask(device, 0x616560 + hoff, mask, data); + nvkm_msec(device, 2000, + if (!(nvkm_rd32(device, 0x616560 + hoff) & 0x80000000)) + break; + ); +} + +static void +gv100_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state) +{ + struct nvkm_device *device = sor->disp->engine.subdev.device; + const u32 coff = (state == &sor->arm) * 0x8000 + sor->id * 0x20; + u32 ctrl = nvkm_rd32(device, 0x680300 + coff); + + state->proto_evo = (ctrl & 0x00000f00) >> 8; + switch (state->proto_evo) { + case 0: state->proto = LVDS; state->link = 1; break; + case 1: state->proto = TMDS; state->link = 1; break; + case 2: state->proto = TMDS; state->link = 2; break; + case 5: state->proto = TMDS; state->link = 3; break; + case 8: state->proto = DP; state->link = 1; break; + case 9: state->proto = DP; state->link = 2; break; + default: + state->proto = UNKNOWN; + break; + } + + state->head = ctrl & 0x000000ff; +} + +static const struct nvkm_ior_func +gv100_sor = { + .route = { + .get = gm200_sor_route_get, + .set = gm200_sor_route_set, + }, + .state = gv100_sor_state, + .power = nv50_sor_power, + .clock = gf119_sor_clock, + .hdmi = { + .ctrl = gv100_hdmi_ctrl, + }, + .dp = { + .lanes = { 0, 1, 2, 3 }, + .links = gf119_sor_dp_links, + .power = g94_sor_dp_power, + .pattern = gm107_sor_dp_pattern, + .drive = gm200_sor_dp_drive, + .audio = gv100_sor_dp_audio, + .audio_sym = gv100_sor_dp_audio_sym, + .watermark = gv100_sor_dp_watermark, + }, + .hda = { + .hpd = gf119_hda_hpd, + .eld = gf119_hda_eld, + }, +}; + +int +gv100_sor_new(struct nvkm_disp *disp, int id) +{ + return nvkm_ior_new_(&gv100_sor, disp, SOR, id); +} + +int +gv100_sor_cnt(struct nvkm_disp *disp, unsigned long *pmask) +{ + struct nvkm_device *device = disp->engine.subdev.device; + *pmask = (nvkm_rd32(device, 0x610060) & 0x0000ff00) >> 8; + return (nvkm_rd32(device, 0x610074) & 0x00000f00) >> 8; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/wimmgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/wimmgv100.c new file mode 100644 index 0000000000000..89d783368b4f2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/wimmgv100.c @@ -0,0 +1,82 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "channv50.h" + +#include + +#include +#include + +static void +gv100_disp_wimm_intr(struct nv50_disp_chan *chan, bool en) +{ + struct nvkm_device *device = chan->disp->base.engine.subdev.device; + const u32 mask = 0x00000001 << chan->head; + const u32 data = en ? mask : 0; + nvkm_mask(device, 0x611da8, mask, data); +} + +const struct nv50_disp_chan_func +gv100_disp_wimm = { + .init = gv100_disp_dmac_init, + .fini = gv100_disp_dmac_fini, + .intr = gv100_disp_wimm_intr, + .user = gv100_disp_chan_user, +}; + +static int +gv100_disp_wimm_new_(const struct nv50_disp_chan_func *func, + const struct nv50_disp_chan_mthd *mthd, + struct nv50_disp *disp, int chid, + const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nvkm_object **pobject) +{ + union { + struct nvc37b_window_imm_channel_dma_v0 v0; + } *args = argv; + struct nvkm_object *parent = oclass->parent; + int wndw, ret = -ENOSYS; + u64 push; + + nvif_ioctl(parent, "create window imm channel dma size %d\n", argc); + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { + nvif_ioctl(parent, "create window imm channel dma vers %d " + "pushbuf %016llx index %d\n", + args->v0.version, args->v0.pushbuf, args->v0.index); + if (!(disp->wndw.mask & BIT(args->v0.index))) + return -EINVAL; + push = args->v0.pushbuf; + wndw = args->v0.index; + } else + return ret; + + return nv50_disp_dmac_new_(func, mthd, disp, chid + wndw, + wndw, push, oclass, pobject); +} + +int +gv100_disp_wimm_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return gv100_disp_wimm_new_(&gv100_disp_wimm, NULL, disp, 33, + oclass, argv, argc, pobject); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/wndwgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/wndwgv100.c new file mode 100644 index 0000000000000..98911805aabf6 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/wndwgv100.c @@ -0,0 +1,184 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "channv50.h" + +#include + +#include +#include + +static const struct nv50_disp_mthd_list +gv100_disp_wndw_mthd_base = { + .mthd = 0x0000, + .addr = 0x000000, + .data = { + { 0x0200, 0x690200 }, + { 0x020c, 0x69020c }, + { 0x0210, 0x690210 }, + { 0x0214, 0x690214 }, + { 0x0218, 0x690218 }, + { 0x021c, 0x69021c }, + { 0x0220, 0x690220 }, + { 0x0224, 0x690224 }, + { 0x0228, 0x690228 }, + { 0x022c, 0x69022c }, + { 0x0230, 0x690230 }, + { 0x0234, 0x690234 }, + { 0x0238, 0x690238 }, + { 0x0240, 0x690240 }, + { 0x0244, 0x690244 }, + { 0x0248, 0x690248 }, + { 0x024c, 0x69024c }, + { 0x0250, 0x690250 }, + { 0x0254, 0x690254 }, + { 0x0260, 0x690260 }, + { 0x0264, 0x690264 }, + { 0x0268, 0x690268 }, + { 0x026c, 0x69026c }, + { 0x0270, 0x690270 }, + { 0x0274, 0x690274 }, + { 0x0280, 0x690280 }, + { 0x0284, 0x690284 }, + { 0x0288, 0x690288 }, + { 0x028c, 0x69028c }, + { 0x0290, 0x690290 }, + { 0x0298, 0x690298 }, + { 0x029c, 0x69029c }, + { 0x02a0, 0x6902a0 }, + { 0x02a4, 0x6902a4 }, + { 0x02a8, 0x6902a8 }, + { 0x02ac, 0x6902ac }, + { 0x02b0, 0x6902b0 }, + { 0x02b4, 0x6902b4 }, + { 0x02b8, 0x6902b8 }, + { 0x02bc, 0x6902bc }, + { 0x02c0, 0x6902c0 }, + { 0x02c4, 0x6902c4 }, + { 0x02c8, 0x6902c8 }, + { 0x02cc, 0x6902cc }, + { 0x02d0, 0x6902d0 }, + { 0x02d4, 0x6902d4 }, + { 0x02d8, 0x6902d8 }, + { 0x02dc, 0x6902dc }, + { 0x02e0, 0x6902e0 }, + { 0x02e4, 0x6902e4 }, + { 0x02e8, 0x6902e8 }, + { 0x02ec, 0x6902ec }, + { 0x02f0, 0x6902f0 }, + { 0x02f4, 0x6902f4 }, + { 0x02f8, 0x6902f8 }, + { 0x02fc, 0x6902fc }, + { 0x0300, 0x690300 }, + { 0x0304, 0x690304 }, + { 0x0308, 0x690308 }, + { 0x0310, 0x690310 }, + { 0x0314, 0x690314 }, + { 0x0318, 0x690318 }, + { 0x031c, 0x69031c }, + { 0x0320, 0x690320 }, + { 0x0324, 0x690324 }, + { 0x0328, 0x690328 }, + { 0x032c, 0x69032c }, + { 0x033c, 0x69033c }, + { 0x0340, 0x690340 }, + { 0x0344, 0x690344 }, + { 0x0348, 0x690348 }, + { 0x034c, 0x69034c }, + { 0x0350, 0x690350 }, + { 0x0354, 0x690354 }, + { 0x0358, 0x690358 }, + { 0x0364, 0x690364 }, + { 0x0368, 0x690368 }, + { 0x036c, 0x69036c }, + { 0x0370, 0x690370 }, + { 0x0374, 0x690374 }, + { 0x0380, 0x690380 }, + {} + } +}; + +const struct nv50_disp_chan_mthd +gv100_disp_wndw_mthd = { + .name = "Base", + .addr = 0x001000, + .prev = 0x000800, + .data = { + { "Global", 1, &gv100_disp_wndw_mthd_base }, + {} + } +}; + +static void +gv100_disp_wndw_intr(struct nv50_disp_chan *chan, bool en) +{ + struct nvkm_device *device = chan->disp->base.engine.subdev.device; + const u32 mask = 0x00000001 << chan->head; + const u32 data = en ? mask : 0; + nvkm_mask(device, 0x611da4, mask, data); +} + +const struct nv50_disp_chan_func +gv100_disp_wndw = { + .init = gv100_disp_dmac_init, + .fini = gv100_disp_dmac_fini, + .intr = gv100_disp_wndw_intr, + .user = gv100_disp_chan_user, + .bind = gv100_disp_dmac_bind, +}; + +static int +gv100_disp_wndw_new_(const struct nv50_disp_chan_func *func, + const struct nv50_disp_chan_mthd *mthd, + struct nv50_disp *disp, int chid, + const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nvkm_object **pobject) +{ + union { + struct nvc37e_window_channel_dma_v0 v0; + } *args = argv; + struct nvkm_object *parent = oclass->parent; + int wndw, ret = -ENOSYS; + u64 push; + + nvif_ioctl(parent, "create window channel dma size %d\n", argc); + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { + nvif_ioctl(parent, "create window channel dma vers %d " + "pushbuf %016llx index %d\n", + args->v0.version, args->v0.pushbuf, args->v0.index); + if (!(disp->wndw.mask & BIT(args->v0.index))) + return -EINVAL; + push = args->v0.pushbuf; + wndw = args->v0.index; + } else + return ret; + + return nv50_disp_dmac_new_(func, mthd, disp, chid + wndw, + wndw, push, oclass, pobject); +} + +int +gv100_disp_wndw_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + return gv100_disp_wndw_new_(&gv100_disp_wndw, &gv100_disp_wndw_mthd, + disp, 1, oclass, argv, argc, pobject); +} From facaed62b4cba3a6334fc1798fa8f51ea6a1962d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:48 +1000 Subject: [PATCH 157/165] drm/nouveau/kms/gv100: initial support Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/dispnv50/Kbuild | 8 + drivers/gpu/drm/nouveau/dispnv50/atom.h | 8 +- drivers/gpu/drm/nouveau/dispnv50/core.c | 1 + drivers/gpu/drm/nouveau/dispnv50/core.h | 3 + drivers/gpu/drm/nouveau/dispnv50/corec37d.c | 110 ++++++++ drivers/gpu/drm/nouveau/dispnv50/curs.c | 1 + drivers/gpu/drm/nouveau/dispnv50/curs.h | 1 + drivers/gpu/drm/nouveau/dispnv50/cursc37a.c | 50 ++++ drivers/gpu/drm/nouveau/dispnv50/disp.c | 6 + drivers/gpu/drm/nouveau/dispnv50/disp.h | 4 + drivers/gpu/drm/nouveau/dispnv50/head.c | 13 +- drivers/gpu/drm/nouveau/dispnv50/head.h | 4 + drivers/gpu/drm/nouveau/dispnv50/head917d.c | 2 +- drivers/gpu/drm/nouveau/dispnv50/headc37d.c | 212 +++++++++++++++ drivers/gpu/drm/nouveau/dispnv50/sorc37d.c | 39 +++ drivers/gpu/drm/nouveau/dispnv50/wimm.c | 47 ++++ drivers/gpu/drm/nouveau/dispnv50/wimm.h | 8 + drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c | 86 ++++++ drivers/gpu/drm/nouveau/dispnv50/wndw.c | 38 ++- drivers/gpu/drm/nouveau/dispnv50/wndw.h | 6 + drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c | 278 ++++++++++++++++++++ 21 files changed, 918 insertions(+), 7 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/dispnv50/corec37d.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/cursc37a.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/headc37d.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/sorc37d.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/wimm.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/wimm.h create mode 100644 drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c create mode 100644 drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c diff --git a/drivers/gpu/drm/nouveau/dispnv50/Kbuild b/drivers/gpu/drm/nouveau/dispnv50/Kbuild index ebd18cb9fedac..849b0f45afb86 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/Kbuild +++ b/drivers/gpu/drm/nouveau/dispnv50/Kbuild @@ -6,6 +6,7 @@ nouveau-y += dispnv50/core507d.o nouveau-y += dispnv50/core827d.o nouveau-y += dispnv50/core907d.o nouveau-y += dispnv50/core917d.o +nouveau-y += dispnv50/corec37d.o nouveau-y += dispnv50/dac507d.o nouveau-y += dispnv50/dac907d.o @@ -14,14 +15,20 @@ nouveau-y += dispnv50/pior507d.o nouveau-y += dispnv50/sor507d.o nouveau-y += dispnv50/sor907d.o +nouveau-y += dispnv50/sorc37d.o nouveau-y += dispnv50/head.o nouveau-y += dispnv50/head507d.o nouveau-y += dispnv50/head827d.o nouveau-y += dispnv50/head907d.o nouveau-y += dispnv50/head917d.o +nouveau-y += dispnv50/headc37d.o + +nouveau-y += dispnv50/wimm.o +nouveau-y += dispnv50/wimmc37b.o nouveau-y += dispnv50/wndw.o +nouveau-y += dispnv50/wndwc37e.o nouveau-y += dispnv50/base.o nouveau-y += dispnv50/base507c.o @@ -32,6 +39,7 @@ nouveau-y += dispnv50/base917c.o nouveau-y += dispnv50/curs.o nouveau-y += dispnv50/curs507a.o nouveau-y += dispnv50/curs907a.o +nouveau-y += dispnv50/cursc37a.o nouveau-y += dispnv50/oimm.o nouveau-y += dispnv50/oimm507b.o diff --git a/drivers/gpu/drm/nouveau/dispnv50/atom.h b/drivers/gpu/drm/nouveau/dispnv50/atom.h index d8337e7996e80..908feb1fc60f7 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/atom.h +++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h @@ -54,6 +54,9 @@ struct nv50_head_atom { u64 offset:40; u8 buffer:1; u8 mode:4; + u8 size:2; + u8 range:2; + u8 output_mode:2; } olut; struct { @@ -77,7 +80,7 @@ struct nv50_head_atom { u32 handle; u64 offset:40; u8 layout:2; - u8 format:1; + u8 format:8; } curs; struct { @@ -166,6 +169,9 @@ struct nv50_wndw_atom { u8 buffer:1; u8 enable:2; u8 mode:4; + u8 size:2; + u8 range:2; + u8 output_mode:2; } i; } xlut; diff --git a/drivers/gpu/drm/nouveau/dispnv50/core.c b/drivers/gpu/drm/nouveau/dispnv50/core.c index f87cbaa4f8eca..f3c49adb1bdb9 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core.c +++ b/drivers/gpu/drm/nouveau/dispnv50/core.c @@ -42,6 +42,7 @@ nv50_core_new(struct nouveau_drm *drm, struct nv50_core **pcore) int version; int (*new)(struct nouveau_drm *, s32, struct nv50_core **); } cores[] = { + { GV100_DISP_CORE_CHANNEL_DMA, 0, corec37d_new }, { GP102_DISP_CORE_CHANNEL_DMA, 0, core917d_new }, { GP100_DISP_CORE_CHANNEL_DMA, 0, core917d_new }, { GM200_DISP_CORE_CHANNEL_DMA, 0, core917d_new }, diff --git a/drivers/gpu/drm/nouveau/dispnv50/core.h b/drivers/gpu/drm/nouveau/dispnv50/core.h index c490d7d497b2e..8470df9dd13de 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core.h +++ b/drivers/gpu/drm/nouveau/dispnv50/core.h @@ -44,4 +44,7 @@ extern const struct nv50_outp_func dac907d; extern const struct nv50_outp_func sor907d; int core917d_new(struct nouveau_drm *, s32, struct nv50_core **); + +int corec37d_new(struct nouveau_drm *, s32, struct nv50_core **); +extern const struct nv50_outp_func sorc37d; #endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/corec37d.c b/drivers/gpu/drm/nouveau/dispnv50/corec37d.c new file mode 100644 index 0000000000000..b5c17c9489187 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/corec37d.c @@ -0,0 +1,110 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "core.h" +#include "head.h" + +#include + +static void +corec37d_update(struct nv50_core *core, u32 *interlock, bool ntfy) +{ + u32 *push; + if ((push = evo_wait(&core->chan, 9))) { + if (ntfy) { + evo_mthd(push, 0x020c, 1); + evo_data(push, 0x00001000 | NV50_DISP_CORE_NTFY); + } + + evo_mthd(push, 0x0218, 2); + evo_data(push, interlock[NV50_DISP_INTERLOCK_CURS]); + evo_data(push, interlock[NV50_DISP_INTERLOCK_WNDW]); + evo_mthd(push, 0x0200, 1); + evo_data(push, 0x00000001); + + if (ntfy) { + evo_mthd(push, 0x020c, 1); + evo_data(push, 0x00000000); + } + evo_kick(push, &core->chan); + } +} + +int +corec37d_ntfy_wait_done(struct nouveau_bo *bo, u32 offset, + struct nvif_device *device) +{ + u32 data; + s64 time = nvif_msec(device, 2000ULL, + data = nouveau_bo_rd32(bo, offset / 4 + 0); + if ((data & 0xc0000000) == 0x80000000) + break; + usleep_range(1, 2); + ); + return time < 0 ? time : 0; +} + +void +corec37d_ntfy_init(struct nouveau_bo *bo, u32 offset) +{ + nouveau_bo_wr32(bo, offset / 4 + 0, 0x00000000); + nouveau_bo_wr32(bo, offset / 4 + 1, 0x00000000); + nouveau_bo_wr32(bo, offset / 4 + 2, 0x00000000); + nouveau_bo_wr32(bo, offset / 4 + 3, 0x00000000); +} + +void +corec37d_init(struct nv50_core *core) +{ + const u32 windows = 8; /*XXX*/ + u32 *push, i; + if ((push = evo_wait(&core->chan, 2 + 6 * windows + 2))) { + evo_mthd(push, 0x0208, 1); + evo_data(push, core->chan.sync.handle); + for (i = 0; i < windows; i++) { + evo_mthd(push, 0x1000 + (i * 0x080), 3); + evo_data(push, i >> 1); + evo_data(push, 0x00000017); + evo_data(push, 0x00000000); + evo_mthd(push, 0x1010 + (i * 0x080), 1); + evo_data(push, 0x00127fff); + } + evo_mthd(push, 0x0200, 1); + evo_data(push, 0x00000001); + evo_kick(push, &core->chan); + } +} + +static const struct nv50_core_func +corec37d = { + .init = corec37d_init, + .ntfy_init = corec37d_ntfy_init, + .ntfy_wait_done = corec37d_ntfy_wait_done, + .update = corec37d_update, + .head = &headc37d, + .sor = &sorc37d, +}; + +int +corec37d_new(struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore) +{ + return core507d_new_(&corec37d, drm, oclass, pcore); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs.c b/drivers/gpu/drm/nouveau/dispnv50/curs.c index fb842ed2592f1..f592087338c46 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/curs.c +++ b/drivers/gpu/drm/nouveau/dispnv50/curs.c @@ -31,6 +31,7 @@ nv50_curs_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) int version; int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); } curses[] = { + { GV100_DISP_CURSOR, 0, cursc37a_new }, { GK104_DISP_CURSOR, 0, curs907a_new }, { GF110_DISP_CURSOR, 0, curs907a_new }, { GT214_DISP_CURSOR, 0, curs507a_new }, diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs.h b/drivers/gpu/drm/nouveau/dispnv50/curs.h index 8edac4507ec89..23aff5fd6747d 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/curs.h +++ b/drivers/gpu/drm/nouveau/dispnv50/curs.h @@ -8,6 +8,7 @@ int curs507a_new_(const struct nv50_wimm_func *, struct nouveau_drm *, struct nv50_wndw **); int curs907a_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); +int cursc37a_new(struct nouveau_drm *, int, s32, struct nv50_wndw **); int nv50_curs_new(struct nouveau_drm *, int head, struct nv50_wndw **); #endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/cursc37a.c b/drivers/gpu/drm/nouveau/dispnv50/cursc37a.c new file mode 100644 index 0000000000000..23fb29d41efef --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/cursc37a.c @@ -0,0 +1,50 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "curs.h" +#include "atom.h" + +static void +cursc37a_update(struct nv50_wndw *wndw, u32 *interlock) +{ + nvif_wr32(&wndw->wimm.base.user, 0x0200, 0x00000001); +} + +static void +cursc37a_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + nvif_wr32(&wndw->wimm.base.user, 0x0208, asyw->point.y << 16 | + asyw->point.x); +} + +static const struct nv50_wimm_func +cursc37a = { + .point = cursc37a_point, + .update = cursc37a_update, +}; + +int +cursc37a_new(struct nouveau_drm *drm, int head, s32 oclass, + struct nv50_wndw **pwndw) +{ + return curs507a_new_(&cursc37a, drm, head, oclass, + 0x00000001 << head, pwndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 6c860e8b1b16f..b83465ae7c1bc 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -154,6 +154,9 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, if (ret) return ret; + if (!syncbuf) + return 0; + ret = nvif_object_init(&dmac->base.user, 0xf0000000, NV_DMA_IN_MEMORY, &(struct nv_dma_v0) { .target = NV_DMA_V0_TARGET_VRAM, @@ -2170,6 +2173,9 @@ nv50_display_create(struct drm_device *dev) goto out; /* create crtc objects to represent the hw heads */ + if (disp->disp->object.oclass >= GV100_DISP) + crtcs = nvif_rd32(&device->object, 0x610060) & 0xff; + else if (disp->disp->object.oclass >= GF110_DISP) crtcs = nvif_rd32(&device->object, 0x612004) & 0xf; else diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.h b/drivers/gpu/drm/nouveau/dispnv50/disp.h index a89b83f95187e..e48c5eb35b498 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.h +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.h @@ -36,11 +36,15 @@ struct nv50_disp_interlock { NV50_DISP_INTERLOCK_CURS, NV50_DISP_INTERLOCK_BASE, NV50_DISP_INTERLOCK_OVLY, + NV50_DISP_INTERLOCK_WNDW, + NV50_DISP_INTERLOCK_WIMM, NV50_DISP_INTERLOCK__SIZE } type; u32 data; }; +void corec37d_ntfy_init(struct nouveau_bo *, u32); + struct nv50_chan { struct nvif_object user; struct nvif_device *device; diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c index ca83006510b7f..4f57e53797968 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head.c @@ -475,7 +475,16 @@ nv50_head_create(struct drm_device *dev, int index) head->func = disp->core->func->head; head->base.index = index; - ret = nv50_base_new(drm, head->base.index, &wndw); + + if (disp->disp->object.oclass < GV100_DISP) { + ret = nv50_ovly_new(drm, head->base.index, &wndw); + ret = nv50_base_new(drm, head->base.index, &wndw); + } else { + ret = nv50_wndw_new(drm, DRM_PLANE_TYPE_OVERLAY, + head->base.index * 2 + 1, &wndw); + ret = nv50_wndw_new(drm, DRM_PLANE_TYPE_PRIMARY, + head->base.index * 2 + 0, &wndw); + } if (ret == 0) ret = nv50_curs_new(drm, head->base.index, &curs); if (ret) { @@ -495,8 +504,6 @@ nv50_head_create(struct drm_device *dev, int index) goto out; } - /* allocate overlay resources */ - ret = nv50_ovly_new(drm, head->base.index, &wndw); out: if (ret) nv50_head_destroy(crtc); diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.h b/drivers/gpu/drm/nouveau/dispnv50/head.h index 8f2c3ffa4e610..37b3248c6dae4 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.h +++ b/drivers/gpu/drm/nouveau/dispnv50/head.h @@ -71,4 +71,8 @@ void head907d_procamp(struct nv50_head *, struct nv50_head_atom *); void head907d_or(struct nv50_head *, struct nv50_head_atom *); extern const struct nv50_head_func head917d; +int head917d_curs_layout(struct nv50_head *, struct nv50_wndw_atom *, + struct nv50_head_atom *); + +extern const struct nv50_head_func headc37d; #endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/head917d.c b/drivers/gpu/drm/nouveau/dispnv50/head917d.c index 4c019a4417ea1..303df8459ca83 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head917d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head917d.c @@ -63,7 +63,7 @@ head917d_base(struct nv50_head *head, struct nv50_head_atom *asyh) } } -static int +int head917d_curs_layout(struct nv50_head *head, struct nv50_wndw_atom *asyw, struct nv50_head_atom *asyh) { diff --git a/drivers/gpu/drm/nouveau/dispnv50/headc37d.c b/drivers/gpu/drm/nouveau/dispnv50/headc37d.c new file mode 100644 index 0000000000000..989c14083066d --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/headc37d.c @@ -0,0 +1,212 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "head.h" +#include "atom.h" +#include "core.h" + +static void +headc37d_or(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 2))) { + /*XXX: This is a dirty hack until OR depth handling is + * improved later for deep colour etc. + */ + switch (asyh->or.depth) { + case 6: asyh->or.depth = 5; break; + case 5: asyh->or.depth = 4; break; + case 2: asyh->or.depth = 1; break; + case 0: asyh->or.depth = 4; break; + default: + WARN_ON(1); + break; + } + + evo_mthd(push, 0x2004 + (head->base.index * 0x400), 1); + evo_data(push, 0x00000001 | + asyh->or.depth << 4 | + asyh->or.nvsync << 3 | + asyh->or.nhsync << 2); + evo_kick(push, core); + } +} + +static void +headc37d_procamp(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 2))) { + evo_mthd(push, 0x2000 + (head->base.index * 0x400), 1); + evo_data(push, 0x80000000 | + asyh->procamp.sat.sin << 16 | + asyh->procamp.sat.cos << 4); + evo_kick(push, core); + } +} + +static void +headc37d_dither(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 2))) { + evo_mthd(push, 0x2018 + (head->base.index * 0x0400), 1); + evo_data(push, asyh->dither.mode << 8 | + asyh->dither.bits << 4 | + asyh->dither.enable); + evo_kick(push, core); + } +} + +static void +headc37d_curs_clr(struct nv50_head *head) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 4))) { + evo_mthd(push, 0x209c + head->base.index * 0x400, 1); + evo_data(push, 0x000000cf); + evo_mthd(push, 0x2088 + head->base.index * 0x400, 1); + evo_data(push, 0x00000000); + evo_kick(push, core); + } +} + +static void +headc37d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 7))) { + evo_mthd(push, 0x209c + head->base.index * 0x400, 2); + evo_data(push, 0x80000000 | + asyh->curs.layout << 8 | + asyh->curs.format << 0); + evo_data(push, 0x000072ff); + evo_mthd(push, 0x2088 + head->base.index * 0x400, 1); + evo_data(push, asyh->curs.handle); + evo_mthd(push, 0x2090 + head->base.index * 0x400, 1); + evo_data(push, asyh->curs.offset >> 8); + evo_kick(push, core); + } +} + +static int +headc37d_curs_format(struct nv50_head *head, struct nv50_wndw_atom *asyw, + struct nv50_head_atom *asyh) +{ + asyh->curs.format = asyw->image.format; + return 0; +} + +static void +headc37d_olut_clr(struct nv50_head *head) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 2))) { + evo_mthd(push, 0x20ac + (head->base.index * 0x400), 1); + evo_data(push, 0x00000000); + evo_kick(push, core); + } +} + +static void +headc37d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 4))) { + evo_mthd(push, 0x20a4 + (head->base.index * 0x400), 3); + evo_data(push, asyh->olut.output_mode << 8 | + asyh->olut.range << 4 | + asyh->olut.size); + evo_data(push, asyh->olut.offset >> 8); + evo_data(push, asyh->olut.handle); + evo_kick(push, core); + } +} + +static void +headc37d_olut(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + asyh->olut.mode = 2; + asyh->olut.size = 0; + asyh->olut.range = 0; + asyh->olut.output_mode = 1; +} + +static void +headc37d_mode(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + struct nv50_head_mode *m = &asyh->mode; + u32 *push; + if ((push = evo_wait(core, 12))) { + evo_mthd(push, 0x2064 + (head->base.index * 0x400), 5); + evo_data(push, (m->v.active << 16) | m->h.active ); + evo_data(push, (m->v.synce << 16) | m->h.synce ); + evo_data(push, (m->v.blanke << 16) | m->h.blanke ); + evo_data(push, (m->v.blanks << 16) | m->h.blanks ); + evo_data(push, (m->v.blank2e << 16) | m->v.blank2s); + evo_mthd(push, 0x200c + (head->base.index * 0x400), 1); + evo_data(push, m->clock * 1000); + evo_mthd(push, 0x2028 + (head->base.index * 0x400), 1); + evo_data(push, m->clock * 1000); + /*XXX: HEAD_USAGE_BOUNDS, doesn't belong here. */ + evo_mthd(push, 0x2030 + (head->base.index * 0x400), 1); + evo_data(push, 0x00000124); + evo_kick(push, core); + } +} + +static void +headc37d_view(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->core->chan; + u32 *push; + if ((push = evo_wait(core, 4))) { + evo_mthd(push, 0x204c + (head->base.index * 0x400), 1); + evo_data(push, (asyh->view.iH << 16) | asyh->view.iW); + evo_mthd(push, 0x2058 + (head->base.index * 0x400), 1); + evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); + evo_kick(push, core); + } +} + +const struct nv50_head_func +headc37d = { + .view = headc37d_view, + .mode = headc37d_mode, + .olut = headc37d_olut, + .olut_set = headc37d_olut_set, + .olut_clr = headc37d_olut_clr, + .curs_layout = head917d_curs_layout, + .curs_format = headc37d_curs_format, + .curs_set = headc37d_curs_set, + .curs_clr = headc37d_curs_clr, + .dither = headc37d_dither, + .procamp = headc37d_procamp, + .or = headc37d_or, +}; diff --git a/drivers/gpu/drm/nouveau/dispnv50/sorc37d.c b/drivers/gpu/drm/nouveau/dispnv50/sorc37d.c new file mode 100644 index 0000000000000..dff059241c5dd --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/sorc37d.c @@ -0,0 +1,39 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "core.h" + +static void +sorc37d_ctrl(struct nv50_core *core, int or, u32 ctrl, + struct nv50_head_atom *asyh) +{ + u32 *push; + if ((push = evo_wait(&core->chan, 2))) { + evo_mthd(push, 0x0300 + (or * 0x20), 1); + evo_data(push, ctrl); + evo_kick(push, &core->chan); + } +} + +const struct nv50_outp_func +sorc37d = { + .ctrl = sorc37d_ctrl, +}; diff --git a/drivers/gpu/drm/nouveau/dispnv50/wimm.c b/drivers/gpu/drm/nouveau/dispnv50/wimm.c new file mode 100644 index 0000000000000..fc36e06964077 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/wimm.c @@ -0,0 +1,47 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "wimm.h" + +#include + +int +nv50_wimm_init(struct nouveau_drm *drm, struct nv50_wndw *wndw) +{ + struct { + s32 oclass; + int version; + int (*init)(struct nouveau_drm *, s32, struct nv50_wndw *); + } wimms[] = { + { GV100_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init }, + {} + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + int cid; + + cid = nvif_mclass(&disp->disp->object, wimms); + if (cid < 0) { + NV_ERROR(drm, "No supported window immediate class\n"); + return cid; + } + + return wimms[cid].init(drm, wimms[cid].oclass, wndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/wimm.h b/drivers/gpu/drm/nouveau/dispnv50/wimm.h new file mode 100644 index 0000000000000..363052309be96 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/wimm.h @@ -0,0 +1,8 @@ +#ifndef __NV50_KMS_WIMM_H__ +#define __NV50_KMS_WIMM_H__ +#include "wndw.h" + +int nv50_wimm_init(struct nouveau_drm *drm, struct nv50_wndw *); + +int wimmc37b_init(struct nouveau_drm *, s32, struct nv50_wndw *); +#endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c b/drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c new file mode 100644 index 0000000000000..9103b8494279c --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c @@ -0,0 +1,86 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "wimm.h" +#include "atom.h" +#include "wndw.h" + +#include + +static void +wimmc37b_update(struct nv50_wndw *wndw, u32 *interlock) +{ + u32 *push; + if ((push = evo_wait(&wndw->wimm, 2))) { + evo_mthd(push, 0x0200, 1); + if (interlock[NV50_DISP_INTERLOCK_WNDW] & wndw->interlock.data) + evo_data(push, 0x00000003); + else + evo_data(push, 0x00000001); + evo_kick(push, &wndw->wimm); + } +} + +static void +wimmc37b_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wimm, 2))) { + evo_mthd(push, 0x0208, 1); + evo_data(push, asyw->point.y << 16 | asyw->point.x); + evo_kick(push, &wndw->wimm); + } +} + +static const struct nv50_wimm_func +wimmc37b = { + .point = wimmc37b_point, + .update = wimmc37b_update, +}; + +static int +wimmc37b_init_(const struct nv50_wimm_func *func, struct nouveau_drm *drm, + s32 oclass, struct nv50_wndw *wndw) +{ + struct nvc37b_window_imm_channel_dma_v0 args = { + .pushbuf = 0xb0007b00 | wndw->id, + .index = wndw->id, + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + int ret; + + ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, + &oclass, 0, &args, sizeof(args), 0, + &wndw->wimm); + if (ret) { + NV_ERROR(drm, "wimm%04x allocation failed: %d\n", oclass, ret); + return ret; + } + + wndw->immd = func; + return 0; +} + +int +wimmc37b_init(struct nouveau_drm *drm, s32 oclass, struct nv50_wndw *wndw) +{ + return wimmc37b_init_(&wimmc37b, drm, oclass, wndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index c7c08fae383f3..224963b533a69 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -20,6 +20,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ #include "wndw.h" +#include "wimm.h" #include #include @@ -148,11 +149,15 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock, if (asyw->set.scale) wndw->func->scale_set(wndw, asyw); if (asyw->set.point) { + if (asyw->set.point = false, asyw->set.mask) + interlock[wndw->interlock.type] |= wndw->interlock.data; + interlock[NV50_DISP_INTERLOCK_WIMM] |= wndw->interlock.data; + wndw->immd->point(wndw, asyw); wndw->immd->update(wndw, interlock); + } else { + interlock[wndw->interlock.type] |= wndw->interlock.data; } - - interlock[wndw->interlock.type] |= wndw->interlock.data; } void @@ -605,3 +610,32 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, wndw->notify.func = nv50_wndw_notify; return 0; } + +int +nv50_wndw_new(struct nouveau_drm *drm, enum drm_plane_type type, int index, + struct nv50_wndw **pwndw) +{ + struct { + s32 oclass; + int version; + int (*new)(struct nouveau_drm *, enum drm_plane_type, + int, s32, struct nv50_wndw **); + } wndws[] = { + { GV100_DISP_WINDOW_CHANNEL_DMA, 0, wndwc37e_new }, + {} + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + int cid, ret; + + cid = nvif_mclass(&disp->disp->object, wndws); + if (cid < 0) { + NV_ERROR(drm, "No supported window class\n"); + return cid; + } + + ret = wndws[cid].new(drm, type, index, wndws[cid].oclass, pwndw); + if (ret) + return ret; + + return nv50_wimm_init(drm, *pwndw); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.h b/drivers/gpu/drm/nouveau/dispnv50/wndw.h index 745304d06af19..b0b6428034b07 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.h +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.h @@ -87,4 +87,10 @@ struct nv50_wimm_func { }; extern const struct nv50_wimm_func curs507a; + +int wndwc37e_new(struct nouveau_drm *, enum drm_plane_type, int, s32, + struct nv50_wndw **); + +int nv50_wndw_new(struct nouveau_drm *, enum drm_plane_type, int index, + struct nv50_wndw **); #endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c b/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c new file mode 100644 index 0000000000000..44afb0f069a55 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c @@ -0,0 +1,278 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "wndw.h" +#include "atom.h" + +#include +#include +#include + +#include + +static void +wndwc37e_ilut_clr(struct nv50_wndw *wndw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 2))) { + evo_mthd(push, 0x02b8, 1); + evo_data(push, 0x00000000); + evo_kick(push, &wndw->wndw); + } +} + +static void +wndwc37e_ilut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 4))) { + evo_mthd(push, 0x02b0, 3); + evo_data(push, asyw->xlut.i.output_mode << 8 | + asyw->xlut.i.range << 4 | + asyw->xlut.i.size); + evo_data(push, asyw->xlut.i.offset >> 8); + evo_data(push, asyw->xlut.handle); + evo_kick(push, &wndw->wndw); + } +} + +static void +wndwc37e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + asyw->xlut.i.mode = 2; + asyw->xlut.i.size = 0; + asyw->xlut.i.range = 0; + asyw->xlut.i.output_mode = 1; +} + +static void +wndwc37e_image_clr(struct nv50_wndw *wndw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 4))) { + evo_mthd(push, 0x0308, 1); + evo_data(push, 0x00000000); + evo_mthd(push, 0x0240, 1); + evo_data(push, 0x00000000); + evo_kick(push, &wndw->wndw); + } +} + +static void +wndwc37e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + u32 *push; + + if (!(push = evo_wait(&wndw->wndw, 25))) + return; + + evo_mthd(push, 0x0308, 1); + evo_data(push, asyw->image.mode << 4 | asyw->image.interval); + evo_mthd(push, 0x0224, 4); + evo_data(push, asyw->image.h << 16 | asyw->image.w); + evo_data(push, asyw->image.layout << 4 | asyw->image.blockh); + evo_data(push, asyw->image.colorspace << 8 | asyw->image.format); + evo_data(push, asyw->image.blocks[0] | (asyw->image.pitch[0] >> 6)); + evo_mthd(push, 0x0240, 1); + evo_data(push, asyw->image.handle[0]); + evo_mthd(push, 0x0260, 1); + evo_data(push, asyw->image.offset[0] >> 8); + evo_mthd(push, 0x0290, 1); + evo_data(push, (asyw->state.src_y >> 16) << 16 | + (asyw->state.src_x >> 16)); + evo_mthd(push, 0x0298, 1); + evo_data(push, (asyw->state.src_h >> 16) << 16 | + (asyw->state.src_w >> 16)); + evo_mthd(push, 0x02a4, 1); + evo_data(push, asyw->state.crtc_h << 16 | + asyw->state.crtc_w); + + /*XXX: Composition-related stuff. Need to implement properly. */ + evo_mthd(push, 0x02ec, 1); + evo_data(push, (2 - (wndw->id & 1)) << 4); + evo_mthd(push, 0x02f4, 5); + evo_data(push, 0x00000011); + evo_data(push, 0xffff0000); + evo_data(push, 0xffff0000); + evo_data(push, 0xffff0000); + evo_data(push, 0xffff0000); + evo_kick(push, &wndw->wndw); +} + +static void +wndwc37e_ntfy_clr(struct nv50_wndw *wndw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 2))) { + evo_mthd(push, 0x021c, 1); + evo_data(push, 0x00000000); + evo_kick(push, &wndw->wndw); + } +} + +static void +wndwc37e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 3))) { + evo_mthd(push, 0x021c, 2); + evo_data(push, asyw->ntfy.handle); + evo_data(push, asyw->ntfy.offset | asyw->ntfy.awaken); + evo_kick(push, &wndw->wndw); + } +} + +static void +wndwc37e_sema_clr(struct nv50_wndw *wndw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 2))) { + evo_mthd(push, 0x0218, 1); + evo_data(push, 0x00000000); + evo_kick(push, &wndw->wndw); + } +} + +static void +wndwc37e_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 5))) { + evo_mthd(push, 0x020c, 4); + evo_data(push, asyw->sema.offset); + evo_data(push, asyw->sema.acquire); + evo_data(push, asyw->sema.release); + evo_data(push, asyw->sema.handle); + evo_kick(push, &wndw->wndw); + } +} + +static void +wndwc37e_update(struct nv50_wndw *wndw, u32 *interlock) +{ + u32 *push; + if ((push = evo_wait(&wndw->wndw, 5))) { + evo_mthd(push, 0x0370, 2); + evo_data(push, interlock[NV50_DISP_INTERLOCK_CURS] << 1 | + interlock[NV50_DISP_INTERLOCK_CORE]); + evo_data(push, interlock[NV50_DISP_INTERLOCK_WNDW]); + evo_mthd(push, 0x0200, 1); + if (interlock[NV50_DISP_INTERLOCK_WIMM] & wndw->interlock.data) + evo_data(push, 0x00001001); + else + evo_data(push, 0x00000001); + evo_kick(push, &wndw->wndw); + } +} + +static void +wndwc37e_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, + struct nv50_head_atom *asyh) +{ +} + +static int +wndwc37e_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, + struct nv50_head_atom *asyh) +{ + return drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state, + DRM_PLANE_HELPER_NO_SCALING, + DRM_PLANE_HELPER_NO_SCALING, + true, true); +} + +static const u32 +wndwc37e_format[] = { + DRM_FORMAT_C8, + DRM_FORMAT_YUYV, + DRM_FORMAT_UYVY, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGB565, + DRM_FORMAT_XRGB1555, + DRM_FORMAT_ARGB1555, + DRM_FORMAT_XBGR2101010, + DRM_FORMAT_ABGR2101010, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_ABGR8888, + DRM_FORMAT_XRGB2101010, + DRM_FORMAT_ARGB2101010, + 0 +}; + +static const struct nv50_wndw_func +wndwc37e = { + .acquire = wndwc37e_acquire, + .release = wndwc37e_release, + .sema_set = wndwc37e_sema_set, + .sema_clr = wndwc37e_sema_clr, + .ntfy_set = wndwc37e_ntfy_set, + .ntfy_clr = wndwc37e_ntfy_clr, + .ntfy_reset = corec37d_ntfy_init, + .ntfy_wait_begun = base507c_ntfy_wait_begun, + .ilut = wndwc37e_ilut, + .xlut_set = wndwc37e_ilut_set, + .xlut_clr = wndwc37e_ilut_clr, + .image_set = wndwc37e_image_set, + .image_clr = wndwc37e_image_clr, + .update = wndwc37e_update, +}; + +static int +wndwc37e_new_(const struct nv50_wndw_func *func, struct nouveau_drm *drm, + enum drm_plane_type type, int index, s32 oclass, u32 heads, + struct nv50_wndw **pwndw) +{ + struct nvc37e_window_channel_dma_v0 args = { + .pushbuf = 0xb0007e00 | index, + .index = index, + }; + struct nv50_disp *disp = nv50_disp(drm->dev); + struct nv50_wndw *wndw; + int ret; + + ret = nv50_wndw_new_(func, drm->dev, type, "wndw", index, + wndwc37e_format, heads, NV50_DISP_INTERLOCK_WNDW, + BIT(index), &wndw); + if (*pwndw = wndw, ret) + return ret; + + ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, + &oclass, 0, &args, sizeof(args), + disp->sync->bo.offset, &wndw->wndw); + if (ret) { + NV_ERROR(drm, "qndw%04x allocation failed: %d\n", oclass, ret); + return ret; + } + + wndw->ntfy = NV50_DISP_WNDW_NTFY(wndw->id); + wndw->sema = NV50_DISP_WNDW_SEM0(wndw->id); + wndw->data = 0x00000000; + return 0; +} + +int +wndwc37e_new(struct nouveau_drm *drm, enum drm_plane_type type, int index, + s32 oclass, struct nv50_wndw **pwndw) +{ + return wndwc37e_new_(&wndwc37e, drm, type, index, oclass, + BIT(index >> 1), pwndw); +} From 37e1c45a58b5c1f699d583483f612462418dd2ee Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:48 +1000 Subject: [PATCH 158/165] drm/nouveau/fifo/gv100: initial support Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/class.h | 3 + drivers/gpu/drm/nouveau/include/nvif/device.h | 3 + drivers/gpu/drm/nouveau/include/nvif/user.h | 19 ++ .../drm/nouveau/include/nvkm/engine/fifo.h | 1 + drivers/gpu/drm/nouveau/nouveau_chan.c | 3 +- drivers/gpu/drm/nouveau/nouveau_dma.c | 5 + drivers/gpu/drm/nouveau/nouveau_drm.c | 8 + drivers/gpu/drm/nouveau/nvif/Kbuild | 4 + drivers/gpu/drm/nouveau/nvif/device.c | 2 + drivers/gpu/drm/nouveau/nvif/user.c | 64 ++++ drivers/gpu/drm/nouveau/nvif/userc361.c | 33 ++ .../gpu/drm/nouveau/nvkm/engine/device/base.c | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/Kbuild | 4 + .../drm/nouveau/nvkm/engine/fifo/changk104.h | 14 + .../gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 10 + .../gpu/drm/nouveau/nvkm/engine/fifo/gk104.h | 6 + .../nouveau/nvkm/engine/fifo/gpfifogk104.c | 28 +- .../nouveau/nvkm/engine/fifo/gpfifogv100.c | 225 +++++++++++++ .../gpu/drm/nouveau/nvkm/engine/fifo/gv100.c | 306 ++++++++++++++++++ .../gpu/drm/nouveau/nvkm/engine/fifo/user.h | 6 + .../drm/nouveau/nvkm/engine/fifo/usergv100.c | 45 +++ 21 files changed, 779 insertions(+), 11 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/include/nvif/user.h create mode 100644 drivers/gpu/drm/nouveau/nvif/user.c create mode 100644 drivers/gpu/drm/nouveau/nvif/userc361.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/user.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/usergv100.c diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index 8c9aa556be0ee..a2fdbc6377882 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -52,6 +52,8 @@ #define NV04_DISP /* cl0046.h */ 0x00000046 +#define VOLTA_USERMODE_A 0x0000c361 + #define NV03_CHANNEL_DMA /* cl506b.h */ 0x0000006b #define NV10_CHANNEL_DMA /* cl506b.h */ 0x0000006e #define NV17_CHANNEL_DMA /* cl506b.h */ 0x0000176e @@ -66,6 +68,7 @@ #define KEPLER_CHANNEL_GPFIFO_B /* cla06f.h */ 0x0000a16f #define MAXWELL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000b06f #define PASCAL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000c06f +#define VOLTA_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000c36f #define NV50_DISP /* cl5070.h */ 0x00005070 #define G82_DISP /* cl5070.h */ 0x00008270 diff --git a/drivers/gpu/drm/nouveau/include/nvif/device.h b/drivers/gpu/drm/nouveau/include/nvif/device.h index 76fe21e395de4..ef839bd1d37ee 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/device.h +++ b/drivers/gpu/drm/nouveau/include/nvif/device.h @@ -4,6 +4,7 @@ #include #include +#include struct nvif_device { struct nvif_object object; @@ -13,6 +14,8 @@ struct nvif_device { u64 engines; } *runlist; int runlists; + + struct nvif_user user; }; int nvif_device_init(struct nvif_object *, u32 handle, s32 oclass, void *, u32, diff --git a/drivers/gpu/drm/nouveau/include/nvif/user.h b/drivers/gpu/drm/nouveau/include/nvif/user.h new file mode 100644 index 0000000000000..03c11826b6938 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/user.h @@ -0,0 +1,19 @@ +#ifndef __NVIF_USER_H__ +#define __NVIF_USER_H__ +#include +struct nvif_device; + +struct nvif_user { + const struct nvif_user_func *func; + struct nvif_object object; +}; + +struct nvif_user_func { + void (*doorbell)(struct nvif_user *, u32 token); +}; + +int nvif_user_init(struct nvif_device *); +void nvif_user_fini(struct nvif_device *); + +extern const struct nvif_user_func nvif_userc361; +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h index 0d96edee1e6a4..7e39fbed2519c 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h @@ -73,4 +73,5 @@ int gm200_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **); int gm20b_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **); int gp100_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **); int gp10b_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **); +int gv100_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **); #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 97900e9cfe3f5..92d3115f96b50 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -220,7 +220,8 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, u64 runlist, struct nouveau_channel **pchan) { struct nouveau_cli *cli = (void *)device->object.client; - static const u16 oclasses[] = { PASCAL_CHANNEL_GPFIFO_A, + static const u16 oclasses[] = { VOLTA_CHANNEL_GPFIFO_A, + PASCAL_CHANNEL_GPFIFO_A, MAXWELL_CHANNEL_GPFIFO_A, KEPLER_CHANNEL_GPFIFO_B, KEPLER_CHANNEL_GPFIFO_A, diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index e0664d28802bf..945afd34138ed 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -28,6 +28,8 @@ #include "nouveau_dma.h" #include "nouveau_vmm.h" +#include + void OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords) { @@ -82,6 +84,7 @@ READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout) void nv50_dma_push(struct nouveau_channel *chan, u64 offset, int length) { + struct nvif_user *user = &chan->drm->client.device.user; struct nouveau_bo *pb = chan->push.buffer; int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base; @@ -97,6 +100,8 @@ nv50_dma_push(struct nouveau_channel *chan, u64 offset, int length) nouveau_bo_rd32(pb, 0); nvif_wr32(&chan->user, 0x8c, chan->dma.ib_put); + if (user->func && user->func->doorbell) + user->func->doorbell(user, chan->chid); chan->dma.ib_free--; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 8e506c5d5a731..775443c9af943 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 @@ -310,6 +311,12 @@ nouveau_accel_init(struct nouveau_drm *drm) if (ret) return; + if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_VOLTA) { + ret = nvif_user_init(device); + if (ret) + return; + } + /* initialise synchronisation routines */ /*XXX: this is crap, but the fence/channel stuff is a little * backwards in some places. this will be fixed. @@ -341,6 +348,7 @@ nouveau_accel_init(struct nouveau_drm *drm) case KEPLER_CHANNEL_GPFIFO_B: case MAXWELL_CHANNEL_GPFIFO_A: case PASCAL_CHANNEL_GPFIFO_A: + case VOLTA_CHANNEL_GPFIFO_A: ret = nvc0_fence_create(drm); break; default: diff --git a/drivers/gpu/drm/nouveau/nvif/Kbuild b/drivers/gpu/drm/nouveau/nvif/Kbuild index 3db12504140ff..42e8c85caa335 100644 --- a/drivers/gpu/drm/nouveau/nvif/Kbuild +++ b/drivers/gpu/drm/nouveau/nvif/Kbuild @@ -8,3 +8,7 @@ nvif-y += nvif/mem.o nvif-y += nvif/mmu.o nvif-y += nvif/notify.o nvif-y += nvif/vmm.o + +# Usermode classes +nvif-y += nvif/user.o +nvif-y += nvif/userc361.o diff --git a/drivers/gpu/drm/nouveau/nvif/device.c b/drivers/gpu/drm/nouveau/nvif/device.c index ca5eb3dde70a0..1ec101ba3b427 100644 --- a/drivers/gpu/drm/nouveau/nvif/device.c +++ b/drivers/gpu/drm/nouveau/nvif/device.c @@ -37,6 +37,7 @@ nvif_device_time(struct nvif_device *device) void nvif_device_fini(struct nvif_device *device) { + nvif_user_fini(device); kfree(device->runlist); device->runlist = NULL; nvif_object_fini(&device->object); @@ -49,6 +50,7 @@ nvif_device_init(struct nvif_object *parent, u32 handle, s32 oclass, int ret = nvif_object_init(parent, handle, oclass, data, size, &device->object); device->runlist = NULL; + device->user.func = NULL; if (ret == 0) { device->info.version = 0; ret = nvif_object_mthd(&device->object, NV_DEVICE_V0_INFO, diff --git a/drivers/gpu/drm/nouveau/nvif/user.c b/drivers/gpu/drm/nouveau/nvif/user.c new file mode 100644 index 0000000000000..10da3cdca6478 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvif/user.c @@ -0,0 +1,64 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 +#include + +#include + +void +nvif_user_fini(struct nvif_device *device) +{ + if (device->user.func) { + nvif_object_fini(&device->user.object); + device->user.func = NULL; + } +} + +int +nvif_user_init(struct nvif_device *device) +{ + struct { + s32 oclass; + int version; + const struct nvif_user_func *func; + } users[] = { + { VOLTA_USERMODE_A, -1, &nvif_userc361 }, + {} + }; + int cid, ret; + + if (device->user.func) + return 0; + + cid = nvif_mclass(&device->object, users); + if (cid < 0) + return cid; + + ret = nvif_object_init(&device->object, 0, users[cid].oclass, NULL, 0, + &device->user.object); + if (ret) + return ret; + + nvif_object_map(&device->user.object, NULL, 0); + device->user.func = users[cid].func; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvif/userc361.c b/drivers/gpu/drm/nouveau/nvif/userc361.c new file mode 100644 index 0000000000000..19f9958e7e015 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvif/userc361.c @@ -0,0 +1,33 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 + +static void +nvif_userc361_doorbell(struct nvif_user *user, u32 token) +{ + nvif_wr32(&user->object, 0x90, token); +} + +const struct nvif_user_func +nvif_userc361 = { + .doorbell = nvif_userc361_doorbell, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 43f6b7afdb52d..95a56d4ba339c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2418,6 +2418,7 @@ nv140_chipset = { .top = gk104_top_new, .disp = gv100_disp_new, .dma = gv100_dma_new, + .fifo = gv100_fifo_new, }; static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild index b888ea64df210..f00408577a6af 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild @@ -15,6 +15,7 @@ nvkm-y += nvkm/engine/fifo/gm200.o nvkm-y += nvkm/engine/fifo/gm20b.o nvkm-y += nvkm/engine/fifo/gp100.o nvkm-y += nvkm/engine/fifo/gp10b.o +nvkm-y += nvkm/engine/fifo/gv100.o nvkm-y += nvkm/engine/fifo/chan.o nvkm-y += nvkm/engine/fifo/channv50.o @@ -31,3 +32,6 @@ nvkm-y += nvkm/engine/fifo/gpfifonv50.o nvkm-y += nvkm/engine/fifo/gpfifog84.o nvkm-y += nvkm/engine/fifo/gpfifogf100.o nvkm-y += nvkm/engine/fifo/gpfifogk104.o +nvkm-y += nvkm/engine/fifo/gpfifogv100.o + +nvkm-y += nvkm/engine/fifo/usergv100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h index 391e864c2a4a9..8e28ba6b23074 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h @@ -20,6 +20,20 @@ struct gk104_fifo_chan { } engn[NVKM_SUBDEV_NR]; }; +extern const struct nvkm_fifo_chan_func gk104_fifo_gpfifo_func; + int gk104_fifo_gpfifo_new(struct gk104_fifo *, const struct nvkm_oclass *, void *data, u32 size, struct nvkm_object **); +void *gk104_fifo_gpfifo_dtor(struct nvkm_fifo_chan *); +void gk104_fifo_gpfifo_init(struct nvkm_fifo_chan *); +void gk104_fifo_gpfifo_fini(struct nvkm_fifo_chan *); +int gk104_fifo_gpfifo_engine_ctor(struct nvkm_fifo_chan *, struct nvkm_engine *, + struct nvkm_object *); +void gk104_fifo_gpfifo_engine_dtor(struct nvkm_fifo_chan *, + struct nvkm_engine *); +int gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *); +int gk104_fifo_gpfifo_kick_locked(struct gk104_fifo_chan *); + +int gv100_fifo_gpfifo_new(struct gk104_fifo *, const struct nvkm_oclass *, + void *data, u32 size, struct nvkm_object **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index 767e0ab44cb83..a99046414a18e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -103,6 +103,10 @@ gk104_fifo_class_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, if (oclass->engn == &fifo->func->chan) { const struct gk104_fifo_chan_user *user = oclass->engn; return user->ctor(fifo, oclass, argv, argc, pobject); + } else + if (oclass->engn == &fifo->func->user) { + const struct gk104_fifo_user_user *user = oclass->engn; + return user->ctor(oclass, argv, argc, pobject); } WARN_ON(1); return -EINVAL; @@ -115,6 +119,12 @@ gk104_fifo_class_get(struct nvkm_fifo *base, int index, struct gk104_fifo *fifo = gk104_fifo(base); int c = 0; + if (fifo->func->user.ctor && c++ == index) { + oclass->base = fifo->func->user.user; + oclass->engn = &fifo->func->user; + return 0; + } + if (fifo->func->chan.ctor && c++ == index) { oclass->base = fifo->func->chan.user; oclass->engn = &fifo->func->chan; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h index 1d182d8d2fcee..d295b81e18d6c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h @@ -63,6 +63,12 @@ struct gk104_fifo_func { struct nvkm_memory *, u32 offset); } *runlist; + struct gk104_fifo_user_user { + struct nvkm_sclass user; + int (*ctor)(const struct nvkm_oclass *, void *, u32, + struct nvkm_object **); + } user; + struct gk104_fifo_chan_user { struct nvkm_sclass user; int (*ctor)(struct gk104_fifo *, const struct nvkm_oclass *, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c index 60e7d72d6e461..118b37aea318f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c @@ -34,8 +34,8 @@ #include #include -static int -gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan) +int +gk104_fifo_gpfifo_kick_locked(struct gk104_fifo_chan *chan) { struct gk104_fifo *fifo = chan->fifo; struct nvkm_subdev *subdev = &fifo->base.engine.subdev; @@ -44,7 +44,6 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan) struct nvkm_fifo_cgrp *cgrp = chan->cgrp; int ret = 0; - mutex_lock(&subdev->mutex); if (cgrp) nvkm_wr32(device, 0x002634, cgrp->id | 0x01000000); else @@ -59,7 +58,16 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan) nvkm_fifo_recover_chan(&fifo->base, chan->base.chid); ret = -ETIMEDOUT; } - mutex_unlock(&subdev->mutex); + return ret; +} + +int +gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan) +{ + int ret; + mutex_lock(&chan->base.fifo->engine.subdev.mutex); + ret = gk104_fifo_gpfifo_kick_locked(chan); + mutex_unlock(&chan->base.fifo->engine.subdev.mutex); return ret; } @@ -138,7 +146,7 @@ gk104_fifo_gpfifo_engine_init(struct nvkm_fifo_chan *base, return 0; } -static void +void gk104_fifo_gpfifo_engine_dtor(struct nvkm_fifo_chan *base, struct nvkm_engine *engine) { @@ -147,7 +155,7 @@ gk104_fifo_gpfifo_engine_dtor(struct nvkm_fifo_chan *base, nvkm_gpuobj_del(&chan->engn[engine->subdev.index].inst); } -static int +int gk104_fifo_gpfifo_engine_ctor(struct nvkm_fifo_chan *base, struct nvkm_engine *engine, struct nvkm_object *object) @@ -172,7 +180,7 @@ gk104_fifo_gpfifo_engine_ctor(struct nvkm_fifo_chan *base, chan->engn[engn].vma, NULL, 0); } -static void +void gk104_fifo_gpfifo_fini(struct nvkm_fifo_chan *base) { struct gk104_fifo_chan *chan = gk104_fifo_chan(base); @@ -190,7 +198,7 @@ gk104_fifo_gpfifo_fini(struct nvkm_fifo_chan *base) nvkm_wr32(device, 0x800000 + coff, 0x00000000); } -static void +void gk104_fifo_gpfifo_init(struct nvkm_fifo_chan *base) { struct gk104_fifo_chan *chan = gk104_fifo_chan(base); @@ -210,7 +218,7 @@ gk104_fifo_gpfifo_init(struct nvkm_fifo_chan *base) } } -static void * +void * gk104_fifo_gpfifo_dtor(struct nvkm_fifo_chan *base) { struct gk104_fifo_chan *chan = gk104_fifo_chan(base); @@ -218,7 +226,7 @@ gk104_fifo_gpfifo_dtor(struct nvkm_fifo_chan *base) return chan; } -static const struct nvkm_fifo_chan_func +const struct nvkm_fifo_chan_func gk104_fifo_gpfifo_func = { .dtor = gk104_fifo_gpfifo_dtor, .init = gk104_fifo_gpfifo_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c new file mode 100644 index 0000000000000..9598853ced562 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c @@ -0,0 +1,225 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "changk104.h" +#include "cgrp.h" + +#include +#include + +#include +#include + +static int +gv100_fifo_gpfifo_engine_valid(struct gk104_fifo_chan *chan, bool ce, bool valid) +{ + struct nvkm_subdev *subdev = &chan->base.fifo->engine.subdev; + struct nvkm_device *device = subdev->device; + const u32 mask = ce ? 0x00020000 : 0x00010000; + const u32 data = valid ? mask : 0x00000000; + int ret; + + /* Block runlist to prevent the channel from being rescheduled. */ + mutex_lock(&subdev->mutex); + nvkm_mask(device, 0x002630, BIT(chan->runl), BIT(chan->runl)); + + /* Preempt the channel. */ + ret = gk104_fifo_gpfifo_kick_locked(chan); + if (ret == 0) { + /* Update engine context validity. */ + nvkm_kmap(chan->base.inst); + nvkm_mo32(chan->base.inst, 0x0ac, mask, data); + nvkm_done(chan->base.inst); + } + + /* Resume runlist. */ + nvkm_mask(device, 0x002630, BIT(chan->runl), 0); + mutex_unlock(&subdev->mutex); + return ret; +} + +static int +gv100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base, + struct nvkm_engine *engine, bool suspend) +{ + struct gk104_fifo_chan *chan = gk104_fifo_chan(base); + struct nvkm_gpuobj *inst = chan->base.inst; + int ret; + + if (engine->subdev.index >= NVKM_ENGINE_CE0 && + engine->subdev.index <= NVKM_ENGINE_CE_LAST) + return gk104_fifo_gpfifo_kick(chan); + + ret = gv100_fifo_gpfifo_engine_valid(chan, false, false); + if (ret && suspend) + return ret; + + nvkm_kmap(inst); + nvkm_wo32(inst, 0x0210, 0x00000000); + nvkm_wo32(inst, 0x0214, 0x00000000); + nvkm_done(inst); + return ret; +} + +static int +gv100_fifo_gpfifo_engine_init(struct nvkm_fifo_chan *base, + struct nvkm_engine *engine) +{ + struct gk104_fifo_chan *chan = gk104_fifo_chan(base); + struct nvkm_gpuobj *inst = chan->base.inst; + u64 addr; + + if (engine->subdev.index >= NVKM_ENGINE_CE0 && + engine->subdev.index <= NVKM_ENGINE_CE_LAST) + return 0; + + addr = chan->engn[engine->subdev.index].vma->addr; + nvkm_kmap(inst); + nvkm_wo32(inst, 0x210, lower_32_bits(addr) | 0x00000004); + nvkm_wo32(inst, 0x214, upper_32_bits(addr)); + nvkm_done(inst); + + return gv100_fifo_gpfifo_engine_valid(chan, false, true); +} + +const struct nvkm_fifo_chan_func +gv100_fifo_gpfifo_func = { + .dtor = gk104_fifo_gpfifo_dtor, + .init = gk104_fifo_gpfifo_init, + .fini = gk104_fifo_gpfifo_fini, + .ntfy = gf100_fifo_chan_ntfy, + .engine_ctor = gk104_fifo_gpfifo_engine_ctor, + .engine_dtor = gk104_fifo_gpfifo_engine_dtor, + .engine_init = gv100_fifo_gpfifo_engine_init, + .engine_fini = gv100_fifo_gpfifo_engine_fini, +}; + +static int +gv100_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid, + u64 vmm, u64 ioffset, u64 ilength, + const struct nvkm_oclass *oclass, + struct nvkm_object **pobject) +{ + struct gk104_fifo_chan *chan; + int runlist = ffs(*runlists) -1, ret, i; + unsigned long engm; + u64 subdevs = 0; + u64 usermem; + + if (!vmm || runlist < 0 || runlist >= fifo->runlist_nr) + return -EINVAL; + *runlists = BIT_ULL(runlist); + + engm = fifo->runlist[runlist].engm; + for_each_set_bit(i, &engm, fifo->engine_nr) { + if (fifo->engine[i].engine) + subdevs |= BIT_ULL(fifo->engine[i].engine->subdev.index); + } + + /* Allocate the channel. */ + if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + return -ENOMEM; + *pobject = &chan->base.object; + chan->fifo = fifo; + chan->runl = runlist; + INIT_LIST_HEAD(&chan->head); + + ret = nvkm_fifo_chan_ctor(&gv100_fifo_gpfifo_func, &fifo->base, + 0x1000, 0x1000, true, vmm, 0, subdevs, + 1, fifo->user.bar->addr, 0x200, + oclass, &chan->base); + if (ret) + return ret; + + *chid = chan->base.chid; + + /* Hack to support GPUs where even individual channels should be + * part of a channel group. + */ + if (fifo->func->cgrp_force) { + if (!(chan->cgrp = kmalloc(sizeof(*chan->cgrp), GFP_KERNEL))) + return -ENOMEM; + chan->cgrp->id = chan->base.chid; + INIT_LIST_HEAD(&chan->cgrp->head); + INIT_LIST_HEAD(&chan->cgrp->chan); + chan->cgrp->chan_nr = 0; + } + + /* Clear channel control registers. */ + usermem = chan->base.chid * 0x200; + ilength = order_base_2(ilength / 8); + + nvkm_kmap(fifo->user.mem); + for (i = 0; i < 0x200; i += 4) + nvkm_wo32(fifo->user.mem, usermem + i, 0x00000000); + nvkm_done(fifo->user.mem); + usermem = nvkm_memory_addr(fifo->user.mem) + usermem; + + /* RAMFC */ + nvkm_kmap(chan->base.inst); + nvkm_wo32(chan->base.inst, 0x008, lower_32_bits(usermem)); + nvkm_wo32(chan->base.inst, 0x00c, upper_32_bits(usermem)); + nvkm_wo32(chan->base.inst, 0x010, 0x0000face); + nvkm_wo32(chan->base.inst, 0x030, 0x7ffff902); + nvkm_wo32(chan->base.inst, 0x048, lower_32_bits(ioffset)); + nvkm_wo32(chan->base.inst, 0x04c, upper_32_bits(ioffset) | + (ilength << 16)); + nvkm_wo32(chan->base.inst, 0x084, 0x20400000); + nvkm_wo32(chan->base.inst, 0x094, 0x30000001); + nvkm_wo32(chan->base.inst, 0x0e4, 0x00000020); + nvkm_wo32(chan->base.inst, 0x0e8, chan->base.chid); + nvkm_wo32(chan->base.inst, 0x0f4, 0x00001100); + nvkm_wo32(chan->base.inst, 0x0f8, 0x10003080); + nvkm_mo32(chan->base.inst, 0x218, 0x00000000, 0x00000000); + nvkm_wo32(chan->base.inst, 0x220, 0x020a1000); + nvkm_wo32(chan->base.inst, 0x224, 0x00000000); + nvkm_done(chan->base.inst); + return gv100_fifo_gpfifo_engine_valid(chan, true, true); +} + +int +gv100_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass, + void *data, u32 size, struct nvkm_object **pobject) +{ + struct nvkm_object *parent = oclass->parent; + union { + struct kepler_channel_gpfifo_a_v0 v0; + } *args = data; + int ret = -ENOSYS; + + nvif_ioctl(parent, "create channel gpfifo size %d\n", size); + if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { + nvif_ioctl(parent, "create channel gpfifo vers %d vmm %llx " + "ioffset %016llx ilength %08x " + "runlist %016llx\n", + args->v0.version, args->v0.vmm, args->v0.ioffset, + args->v0.ilength, args->v0.runlist); + return gv100_fifo_gpfifo_new_(fifo, + &args->v0.runlist, + &args->v0.chid, + args->v0.vmm, + args->v0.ioffset, + args->v0.ilength, + oclass, pobject); + } + + return ret; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c new file mode 100644 index 0000000000000..4e1d159c0ae7b --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c @@ -0,0 +1,306 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "gk104.h" +#include "cgrp.h" +#include "changk104.h" +#include "user.h" + +#include + +#include + +static void +gv100_fifo_runlist_chan(struct gk104_fifo_chan *chan, + struct nvkm_memory *memory, u32 offset) +{ + struct nvkm_memory *usermem = chan->fifo->user.mem; + const u64 user = nvkm_memory_addr(usermem) + (chan->base.chid * 0x200); + const u64 inst = chan->base.inst->addr; + + nvkm_wo32(memory, offset + 0x0, lower_32_bits(user)); + nvkm_wo32(memory, offset + 0x4, upper_32_bits(user)); + nvkm_wo32(memory, offset + 0x8, lower_32_bits(inst) | chan->base.chid); + nvkm_wo32(memory, offset + 0xc, upper_32_bits(inst)); +} + +static void +gv100_fifo_runlist_cgrp(struct nvkm_fifo_cgrp *cgrp, + struct nvkm_memory *memory, u32 offset) +{ + nvkm_wo32(memory, offset + 0x0, (128 << 24) | (3 << 16) | 0x00000001); + nvkm_wo32(memory, offset + 0x4, cgrp->chan_nr); + nvkm_wo32(memory, offset + 0x8, cgrp->id); + nvkm_wo32(memory, offset + 0xc, 0x00000000); +} + +const struct gk104_fifo_runlist_func +gv100_fifo_runlist = { + .size = 16, + .cgrp = gv100_fifo_runlist_cgrp, + .chan = gv100_fifo_runlist_chan, +}; + +static const struct nvkm_enum +gv100_fifo_fault_gpcclient[] = { + { 0x00, "T1_0" }, + { 0x01, "T1_1" }, + { 0x02, "T1_2" }, + { 0x03, "T1_3" }, + { 0x04, "T1_4" }, + { 0x05, "T1_5" }, + { 0x06, "T1_6" }, + { 0x07, "T1_7" }, + { 0x08, "PE_0" }, + { 0x09, "PE_1" }, + { 0x0a, "PE_2" }, + { 0x0b, "PE_3" }, + { 0x0c, "PE_4" }, + { 0x0d, "PE_5" }, + { 0x0e, "PE_6" }, + { 0x0f, "PE_7" }, + { 0x10, "RAST" }, + { 0x11, "GCC" }, + { 0x12, "GPCCS" }, + { 0x13, "PROP_0" }, + { 0x14, "PROP_1" }, + { 0x15, "PROP_2" }, + { 0x16, "PROP_3" }, + { 0x17, "GPM" }, + { 0x18, "LTP_UTLB_0" }, + { 0x19, "LTP_UTLB_1" }, + { 0x1a, "LTP_UTLB_2" }, + { 0x1b, "LTP_UTLB_3" }, + { 0x1c, "LTP_UTLB_4" }, + { 0x1d, "LTP_UTLB_5" }, + { 0x1e, "LTP_UTLB_6" }, + { 0x1f, "LTP_UTLB_7" }, + { 0x20, "RGG_UTLB" }, + { 0x21, "T1_8" }, + { 0x22, "T1_9" }, + { 0x23, "T1_10" }, + { 0x24, "T1_11" }, + { 0x25, "T1_12" }, + { 0x26, "T1_13" }, + { 0x27, "T1_14" }, + { 0x28, "T1_15" }, + { 0x29, "TPCCS_0" }, + { 0x2a, "TPCCS_1" }, + { 0x2b, "TPCCS_2" }, + { 0x2c, "TPCCS_3" }, + { 0x2d, "TPCCS_4" }, + { 0x2e, "TPCCS_5" }, + { 0x2f, "TPCCS_6" }, + { 0x30, "TPCCS_7" }, + { 0x31, "PE_8" }, + { 0x32, "PE_9" }, + { 0x33, "TPCCS_8" }, + { 0x34, "TPCCS_9" }, + { 0x35, "T1_16" }, + { 0x36, "T1_17" }, + { 0x37, "T1_18" }, + { 0x38, "T1_19" }, + { 0x39, "PE_10" }, + { 0x3a, "PE_11" }, + { 0x3b, "TPCCS_10" }, + { 0x3c, "TPCCS_11" }, + { 0x3d, "T1_20" }, + { 0x3e, "T1_21" }, + { 0x3f, "T1_22" }, + { 0x40, "T1_23" }, + { 0x41, "PE_12" }, + { 0x42, "PE_13" }, + { 0x43, "TPCCS_12" }, + { 0x44, "TPCCS_13" }, + { 0x45, "T1_24" }, + { 0x46, "T1_25" }, + { 0x47, "T1_26" }, + { 0x48, "T1_27" }, + { 0x49, "PE_14" }, + { 0x4a, "PE_15" }, + { 0x4b, "TPCCS_14" }, + { 0x4c, "TPCCS_15" }, + { 0x4d, "T1_28" }, + { 0x4e, "T1_29" }, + { 0x4f, "T1_30" }, + { 0x50, "T1_31" }, + { 0x51, "PE_16" }, + { 0x52, "PE_17" }, + { 0x53, "TPCCS_16" }, + { 0x54, "TPCCS_17" }, + { 0x55, "T1_32" }, + { 0x56, "T1_33" }, + { 0x57, "T1_34" }, + { 0x58, "T1_35" }, + { 0x59, "PE_18" }, + { 0x5a, "PE_19" }, + { 0x5b, "TPCCS_18" }, + { 0x5c, "TPCCS_19" }, + { 0x5d, "T1_36" }, + { 0x5e, "T1_37" }, + { 0x5f, "T1_38" }, + { 0x60, "T1_39" }, + {} +}; + +static const struct nvkm_enum +gv100_fifo_fault_hubclient[] = { + { 0x00, "VIP" }, + { 0x01, "CE0" }, + { 0x02, "CE1" }, + { 0x03, "DNISO" }, + { 0x04, "FE" }, + { 0x05, "FECS" }, + { 0x06, "HOST" }, + { 0x07, "HOST_CPU" }, + { 0x08, "HOST_CPU_NB" }, + { 0x09, "ISO" }, + { 0x0a, "MMU" }, + { 0x0b, "NVDEC" }, + { 0x0d, "NVENC1" }, + { 0x0e, "NISO" }, + { 0x0f, "P2P" }, + { 0x10, "PD" }, + { 0x11, "PERF" }, + { 0x12, "PMU" }, + { 0x13, "RASTERTWOD" }, + { 0x14, "SCC" }, + { 0x15, "SCC_NB" }, + { 0x16, "SEC" }, + { 0x17, "SSYNC" }, + { 0x18, "CE2" }, + { 0x19, "XV" }, + { 0x1a, "MMU_NB" }, + { 0x1b, "NVENC0" }, + { 0x1c, "DFALCON" }, + { 0x1d, "SKED" }, + { 0x1e, "AFALCON" }, + { 0x1f, "DONT_CARE" }, + { 0x20, "HSCE0" }, + { 0x21, "HSCE1" }, + { 0x22, "HSCE2" }, + { 0x23, "HSCE3" }, + { 0x24, "HSCE4" }, + { 0x25, "HSCE5" }, + { 0x26, "HSCE6" }, + { 0x27, "HSCE7" }, + { 0x28, "HSCE8" }, + { 0x29, "HSCE9" }, + { 0x2a, "HSHUB" }, + { 0x2b, "PTP_X0" }, + { 0x2c, "PTP_X1" }, + { 0x2d, "PTP_X2" }, + { 0x2e, "PTP_X3" }, + { 0x2f, "PTP_X4" }, + { 0x30, "PTP_X5" }, + { 0x31, "PTP_X6" }, + { 0x32, "PTP_X7" }, + { 0x33, "NVENC2" }, + { 0x34, "VPR_SCRUBBER0" }, + { 0x35, "VPR_SCRUBBER1" }, + { 0x36, "DWBIF" }, + { 0x37, "FBFALCON" }, + { 0x38, "CE_SHIM" }, + { 0x39, "GSP" }, + {} +}; + +static const struct nvkm_enum +gv100_fifo_fault_reason[] = { + { 0x00, "PDE" }, + { 0x01, "PDE_SIZE" }, + { 0x02, "PTE" }, + { 0x03, "VA_LIMIT_VIOLATION" }, + { 0x04, "UNBOUND_INST_BLOCK" }, + { 0x05, "PRIV_VIOLATION" }, + { 0x06, "RO_VIOLATION" }, + { 0x07, "WO_VIOLATION" }, + { 0x08, "PITCH_MASK_VIOLATION" }, + { 0x09, "WORK_CREATION" }, + { 0x0a, "UNSUPPORTED_APERTURE" }, + { 0x0b, "COMPRESSION_FAILURE" }, + { 0x0c, "UNSUPPORTED_KIND" }, + { 0x0d, "REGION_VIOLATION" }, + { 0x0e, "POISONED" }, + { 0x0f, "ATOMIC_VIOLATION" }, + {} +}; + +static const struct nvkm_enum +gv100_fifo_fault_engine[] = { + { 0x01, "DISPLAY" }, + { 0x03, "PTP" }, + { 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR }, + { 0x05, "BAR2", NULL, NVKM_SUBDEV_INSTMEM }, + { 0x06, "PWR_PMU" }, + { 0x08, "IFB", NULL, NVKM_ENGINE_IFB }, + { 0x09, "PERF" }, + { 0x1f, "PHYSICAL" }, + { 0x20, "HOST0" }, + { 0x21, "HOST1" }, + { 0x22, "HOST2" }, + { 0x23, "HOST3" }, + { 0x24, "HOST4" }, + { 0x25, "HOST5" }, + { 0x26, "HOST6" }, + { 0x27, "HOST7" }, + { 0x28, "HOST8" }, + { 0x29, "HOST9" }, + { 0x2a, "HOST10" }, + { 0x2b, "HOST11" }, + { 0x2c, "HOST12" }, + { 0x2d, "HOST13" }, + {} +}; + +static const struct nvkm_enum +gv100_fifo_fault_access[] = { + { 0x0, "VIRT_READ" }, + { 0x1, "VIRT_WRITE" }, + { 0x2, "VIRT_ATOMIC" }, + { 0x3, "VIRT_PREFETCH" }, + { 0x4, "VIRT_ATOMIC_WEAK" }, + { 0x8, "PHYS_READ" }, + { 0x9, "PHYS_WRITE" }, + { 0xa, "PHYS_ATOMIC" }, + { 0xb, "PHYS_PREFETCH" }, + {} +}; + +static const struct gk104_fifo_func +gv100_fifo = { + .init_pbdma_timeout = gk208_fifo_init_pbdma_timeout, + .fault.access = gv100_fifo_fault_access, + .fault.engine = gv100_fifo_fault_engine, + .fault.reason = gv100_fifo_fault_reason, + .fault.hubclient = gv100_fifo_fault_hubclient, + .fault.gpcclient = gv100_fifo_fault_gpcclient, + .runlist = &gv100_fifo_runlist, + .user = {{-1,-1,VOLTA_USERMODE_A }, gv100_fifo_user_new }, + .chan = {{ 0, 0,VOLTA_CHANNEL_GPFIFO_A}, gv100_fifo_gpfifo_new }, + .cgrp_force = true, +}; + +int +gv100_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo) +{ + return gk104_fifo_new_(&gv100_fifo, device, index, 4096, pfifo); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/user.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/user.h new file mode 100644 index 0000000000000..ed840921ebe8c --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/user.h @@ -0,0 +1,6 @@ +#ifndef __NVKM_FIFO_USER_H__ +#define __NVKM_FIFO_USER_H__ +#include "priv.h" +int gv100_fifo_user_new(const struct nvkm_oclass *, void *, u32, + struct nvkm_object **); +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/usergv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/usergv100.c new file mode 100644 index 0000000000000..3dc3b8b312de3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/usergv100.c @@ -0,0 +1,45 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "user.h" + +static int +gv100_fifo_user_map(struct nvkm_object *object, void *argv, u32 argc, + enum nvkm_object_map *type, u64 *addr, u64 *size) +{ + struct nvkm_device *device = object->engine->subdev.device; + *addr = 0x810000 + device->func->resource_addr(device, 0); + *size = 0x010000; + *type = NVKM_OBJECT_MAP_IO; + return 0; +} + +static const struct nvkm_object_func +gv100_fifo_user = { + .map = gv100_fifo_user_map, +}; + +int +gv100_fifo_user_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nvkm_object **pobject) +{ + return nvkm_object_new_(&gv100_fifo_user, oclass, argv, argc, pobject); +} From 6e1f34e33c17f633ebbd383cab429c820ec0c7b0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:48 +1000 Subject: [PATCH 159/165] drm/nouveau/ce/gv100: initial support Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/class.h | 1 + .../gpu/drm/nouveau/include/nvkm/engine/ce.h | 1 + drivers/gpu/drm/nouveau/nouveau_bo.c | 2 + drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/engine/ce/gv100.c | 40 +++++++++++++++++++ .../gpu/drm/nouveau/nvkm/engine/device/base.c | 9 +++++ 6 files changed, 54 insertions(+) create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/ce/gv100.c diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index a2fdbc6377882..8688342aca617 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -180,6 +180,7 @@ #define MAXWELL_DMA_COPY_A 0x0000b0b5 #define PASCAL_DMA_COPY_A 0x0000c0b5 #define PASCAL_DMA_COPY_B 0x0000c1b5 +#define VOLTA_DMA_COPY_A 0x0000c3b5 #define FERMI_DECOMPRESS 0x000090b8 diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h index 5532459944504..fc295e1faa198 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h @@ -10,4 +10,5 @@ int gm107_ce_new(struct nvkm_device *, int, struct nvkm_engine **); int gm200_ce_new(struct nvkm_device *, int, struct nvkm_engine **); int gp100_ce_new(struct nvkm_device *, int, struct nvkm_engine **); int gp102_ce_new(struct nvkm_device *, int, struct nvkm_engine **); +int gv100_ce_new(struct nvkm_device *, int, struct nvkm_engine **); #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index ab61c038f42c9..7214022dfb911 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1141,6 +1141,8 @@ nouveau_bo_move_init(struct nouveau_drm *drm) struct ttm_mem_reg *, struct ttm_mem_reg *); int (*init)(struct nouveau_channel *, u32 handle); } _methods[] = { + { "COPY", 4, 0xc3b5, nve0_bo_move_copy, nve0_bo_move_init }, + { "GRCE", 0, 0xc3b5, nve0_bo_move_copy, nvc0_bo_move_init }, { "COPY", 4, 0xc1b5, nve0_bo_move_copy, nve0_bo_move_init }, { "GRCE", 0, 0xc1b5, nve0_bo_move_copy, nvc0_bo_move_init }, { "COPY", 4, 0xc0b5, nve0_bo_move_copy, nve0_bo_move_init }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild index 255d81ccf9166..80d7844419044 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild @@ -5,3 +5,4 @@ nvkm-y += nvkm/engine/ce/gm107.o nvkm-y += nvkm/engine/ce/gm200.o nvkm-y += nvkm/engine/ce/gp100.o nvkm-y += nvkm/engine/ce/gp102.o +nvkm-y += nvkm/engine/ce/gv100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gv100.c new file mode 100644 index 0000000000000..fcda3de458575 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gv100.c @@ -0,0 +1,40 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "priv.h" + +#include + +static const struct nvkm_engine_func +gv100_ce = { + .intr = gp100_ce_intr, + .sclass = { + { -1, -1, VOLTA_DMA_COPY_A }, + {} + } +}; + +int +gv100_ce_new(struct nvkm_device *device, int index, + struct nvkm_engine **pengine) +{ + return nvkm_engine_new_(&gv100_ce, device, index, true, pengine); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 95a56d4ba339c..5fa30613da1e5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2417,6 +2417,15 @@ nv140_chipset = { .timer = gk20a_timer_new, .top = gk104_top_new, .disp = gv100_disp_new, + .ce[0] = gv100_ce_new, + .ce[1] = gv100_ce_new, + .ce[2] = gv100_ce_new, + .ce[3] = gv100_ce_new, + .ce[4] = gv100_ce_new, + .ce[5] = gv100_ce_new, + .ce[6] = gv100_ce_new, + .ce[7] = gv100_ce_new, + .ce[8] = gv100_ce_new, .dma = gv100_dma_new, .fifo = gv100_fifo_new, }; From d521097f58bdfdc9966b8d10754074c8524133dd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 May 2018 20:39:48 +1000 Subject: [PATCH 160/165] drm/nouveau/gr/gv100: initial support Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvif/class.h | 3 + .../gpu/drm/nouveau/include/nvkm/engine/gr.h | 1 + .../gpu/drm/nouveau/nvkm/engine/device/base.c | 4 + drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild | 2 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 10 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h | 5 + .../gpu/drm/nouveau/nvkm/engine/gr/ctxgv100.c | 215 ++++++++++++++++++ .../gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 10 +- .../gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 6 +- .../gpu/drm/nouveau/nvkm/engine/gr/gv100.c | 120 ++++++++++ .../gpu/drm/nouveau/nvkm/falcon/msgqueue.c | 1 + .../drm/nouveau/nvkm/subdev/secboot/gp108.c | 21 ++ 12 files changed, 395 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgv100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/gr/gv100.c diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index 8688342aca617..6db56bd7d67eb 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -155,6 +155,8 @@ #define PASCAL_A /* cl9097.h */ 0x0000c097 #define PASCAL_B /* cl9097.h */ 0x0000c197 +#define VOLTA_A /* cl9097.h */ 0x0000c397 + #define NV74_BSP 0x000074b0 #define GT212_MSVLD 0x000085b1 @@ -194,6 +196,7 @@ #define MAXWELL_COMPUTE_B 0x0000b1c0 #define PASCAL_COMPUTE_A 0x0000c0c0 #define PASCAL_COMPUTE_B 0x0000c1c0 +#define VOLTA_COMPUTE_A 0x0000c3c0 #define NV74_CIPHER 0x000074c1 #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h index 33b2f2e543eee..ba1518ff8b66a 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h @@ -48,4 +48,5 @@ int gp102_gr_new(struct nvkm_device *, int, struct nvkm_gr **); int gp104_gr_new(struct nvkm_device *, int, struct nvkm_gr **); int gp107_gr_new(struct nvkm_device *, int, struct nvkm_gr **); int gp10b_gr_new(struct nvkm_device *, int, struct nvkm_gr **); +int gv100_gr_new(struct nvkm_device *, int, struct nvkm_gr **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 5fa30613da1e5..e294013426ced 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2413,6 +2413,7 @@ nv140_chipset = { .mmu = gv100_mmu_new, .pci = gp100_pci_new, .pmu = gp102_pmu_new, + .secboot = gp108_secboot_new, .therm = gp100_therm_new, .timer = gk20a_timer_new, .top = gk104_top_new, @@ -2428,6 +2429,9 @@ nv140_chipset = { .ce[8] = gv100_ce_new, .dma = gv100_dma_new, .fifo = gv100_fifo_new, + .gr = gv100_gr_new, + .nvdec = gp102_nvdec_new, + .sec2 = gp102_sec2_new, }; static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild index 42342b4a9abe0..93e3733f54e28 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild @@ -36,6 +36,7 @@ nvkm-y += nvkm/engine/gr/gp102.o nvkm-y += nvkm/engine/gr/gp104.o nvkm-y += nvkm/engine/gr/gp107.o nvkm-y += nvkm/engine/gr/gp10b.o +nvkm-y += nvkm/engine/gr/gv100.o nvkm-y += nvkm/engine/gr/ctxnv40.o nvkm-y += nvkm/engine/gr/ctxnv50.o @@ -57,3 +58,4 @@ nvkm-y += nvkm/engine/gr/ctxgp100.o nvkm-y += nvkm/engine/gr/ctxgp102.o nvkm-y += nvkm/engine/gr/ctxgp104.o nvkm-y += nvkm/engine/gr/ctxgp107.o +nvkm-y += nvkm/engine/gr/ctxgv100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index 1ed63ed1a2835..f0f5a518e52a2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1396,10 +1396,14 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_floorsweep(gr); + if (grctx->r400088) grctx->r400088(gr, false); if (gr->fuc_bundle) gf100_gr_icmd(gr, gr->fuc_bundle); else gf100_gr_icmd(gr, grctx->icmd); + if (grctx->sw_veid_bundle_init) + gf100_gr_icmd(gr, grctx->sw_veid_bundle_init); + if (grctx->r400088) grctx->r400088(gr, true); nvkm_wr32(device, 0x404154, idle_timeout); @@ -1448,6 +1452,9 @@ gf100_grctx_generate(struct gf100_gr *gr) break; ); + if (grctx->unkn88c) + grctx->unkn88c(gr, true); + /* Reset FECS. */ nvkm_wr32(device, 0x409614, 0x00000070); nvkm_usec(device, 10, NVKM_DELAY); @@ -1455,6 +1462,9 @@ gf100_grctx_generate(struct gf100_gr *gr) nvkm_usec(device, 10, NVKM_DELAY); nvkm_rd32(device, 0x409614); + if (grctx->unkn88c) + grctx->unkn88c(gr, false); + /* NV_PGRAPH_FE_PWR_MODE_AUTO. */ nvkm_wr32(device, 0x404170, 0x00000010); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index 9ce3d00755735..33e932bd73b16 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -21,6 +21,7 @@ void gf100_grctx_mmio_item(struct gf100_grctx *, u32 addr, u32 data, int s, int) #define mmio_wr32(a,b,c) mmio_refn((a), (b), (c), 0, -1) struct gf100_grctx_func { + void (*unkn88c)(struct gf100_gr *, bool on); /* main context generation function */ void (*main)(struct gf100_gr *, struct gf100_grctx *); /* context-specific modify-on-first-load list generation function */ @@ -35,6 +36,7 @@ struct gf100_grctx_func { /* indirect context data, generated with icmds/mthds */ const struct gf100_gr_pack *icmd; const struct gf100_gr_pack *mthd; + const struct gf100_gr_pack *sw_veid_bundle_init; /* bundle circular buffer */ void (*bundle)(struct gf100_grctx *); u32 bundle_size; @@ -66,6 +68,7 @@ struct gf100_grctx_func { void (*tpc_mask)(struct gf100_gr *); void (*smid_config)(struct gf100_gr *); /* misc other things */ + void (*r400088)(struct gf100_gr *, bool); void (*r419cb8)(struct gf100_gr *); void (*r418800)(struct gf100_gr *); void (*r419eb0)(struct gf100_gr *); @@ -148,6 +151,8 @@ extern const struct gf100_grctx_func gp104_grctx; extern const struct gf100_grctx_func gp107_grctx; +extern const struct gf100_grctx_func gv100_grctx; + /* context init value lists */ extern const struct gf100_gr_pack gf100_grctx_pack_icmd[]; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgv100.c new file mode 100644 index 0000000000000..0990765ef1916 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgv100.c @@ -0,0 +1,215 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "ctxgf100.h" + +/******************************************************************************* + * PGRAPH context implementation + ******************************************************************************/ + +static const struct gf100_gr_init +gv100_grctx_init_sw_veid_bundle_init_0[] = { + { 0x00001000, 64, 0x00100000, 0x00000008 }, + { 0x00000941, 64, 0x00100000, 0x00000000 }, + { 0x0000097e, 64, 0x00100000, 0x00000000 }, + { 0x0000097f, 64, 0x00100000, 0x00000100 }, + { 0x0000035c, 64, 0x00100000, 0x00000000 }, + { 0x0000035d, 64, 0x00100000, 0x00000000 }, + { 0x00000a08, 64, 0x00100000, 0x00000000 }, + { 0x00000a09, 64, 0x00100000, 0x00000000 }, + { 0x00000a0a, 64, 0x00100000, 0x00000000 }, + { 0x00000352, 64, 0x00100000, 0x00000000 }, + { 0x00000353, 64, 0x00100000, 0x00000000 }, + { 0x00000358, 64, 0x00100000, 0x00000000 }, + { 0x00000359, 64, 0x00100000, 0x00000000 }, + { 0x00000370, 64, 0x00100000, 0x00000000 }, + { 0x00000371, 64, 0x00100000, 0x00000000 }, + { 0x00000372, 64, 0x00100000, 0x000fffff }, + { 0x00000366, 64, 0x00100000, 0x00000000 }, + { 0x00000367, 64, 0x00100000, 0x00000000 }, + { 0x00000368, 64, 0x00100000, 0x00000fff }, + { 0x00000623, 64, 0x00100000, 0x00000000 }, + { 0x00000624, 64, 0x00100000, 0x00000000 }, + { 0x0001e100, 1, 0x00000001, 0x02000001 }, + {} +}; + +static const struct gf100_gr_pack +gv100_grctx_pack_sw_veid_bundle_init[] = { + { gv100_grctx_init_sw_veid_bundle_init_0 }, + {} +}; + +static void +gv100_grctx_generate_attrib(struct gf100_grctx *info) +{ + struct gf100_gr *gr = info->gr; + const struct gf100_grctx_func *grctx = gr->func->grctx; + const u32 alpha = grctx->alpha_nr; + const u32 attrib = grctx->attrib_nr; + const u32 gfxp = grctx->gfxp_nr; + const int s = 12; + const int max_batches = 0xffff; + u32 size = grctx->alpha_nr_max * gr->tpc_total; + u32 ao = 0; + u32 bo = ao + size; + int gpc, ppc, b, n = 0; + + size += grctx->gfxp_nr * gr->tpc_total; + size = ((size * 0x20) + 128) & ~127; + b = mmio_vram(info, size, (1 << s), false); + + mmio_refn(info, 0x418810, 0x80000000, s, b); + mmio_refn(info, 0x419848, 0x10000000, s, b); + mmio_refn(info, 0x419c2c, 0x10000000, s, b); + mmio_refn(info, 0x419e00, 0x00000000, s, b); + mmio_wr32(info, 0x419e04, 0x80000000 | size >> 7); + mmio_wr32(info, 0x405830, attrib); + mmio_wr32(info, 0x40585c, alpha); + mmio_wr32(info, 0x4064c4, ((alpha / 4) << 16) | max_batches); + + for (gpc = 0; gpc < gr->gpc_nr; gpc++) { + for (ppc = 0; ppc < gr->ppc_nr[gpc]; ppc++, n++) { + const u32 as = alpha * gr->ppc_tpc_nr[gpc][ppc]; + const u32 bs = attrib * gr->ppc_tpc_nr[gpc][ppc]; + const u32 gs = gfxp * gr->ppc_tpc_nr[gpc][ppc]; + const u32 u = 0x418ea0 + (n * 0x04); + const u32 o = PPC_UNIT(gpc, ppc, 0); + if (!(gr->ppc_mask[gpc] & (1 << ppc))) + continue; + mmio_wr32(info, o + 0xc0, gs); + mmio_wr32(info, o + 0xf4, bo); + mmio_wr32(info, o + 0xf0, bs); + bo += gs; + mmio_wr32(info, o + 0xe4, as); + mmio_wr32(info, o + 0xf8, ao); + ao += grctx->alpha_nr_max * gr->ppc_tpc_nr[gpc][ppc]; + mmio_wr32(info, u, bs); + } + } + + mmio_wr32(info, 0x4181e4, 0x00000100); + mmio_wr32(info, 0x41befc, 0x00000100); +} + +static void +gv100_grctx_generate_rop_mapping(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + u32 data; + int i, j; + + /* Pack tile map into register format. */ + nvkm_wr32(device, 0x418bb8, (gr->tpc_total << 8) | + gr->screen_tile_row_offset); + for (i = 0; i < 11; i++) { + for (data = 0, j = 0; j < 6; j++) + data |= (gr->tile[i * 6 + j] & 0x1f) << (j * 5); + nvkm_wr32(device, 0x418b08 + (i * 4), data); + nvkm_wr32(device, 0x41bf00 + (i * 4), data); + nvkm_wr32(device, 0x40780c + (i * 4), data); + } + + /* GPC_BROADCAST.TP_BROADCAST */ + nvkm_wr32(device, 0x41bfd0, (gr->tpc_total << 8) | + gr->screen_tile_row_offset); + for (i = 0, j = 1; i < 5; i++, j += 4) { + u8 v19 = (1 << (j + 0)) % gr->tpc_total; + u8 v20 = (1 << (j + 1)) % gr->tpc_total; + u8 v21 = (1 << (j + 2)) % gr->tpc_total; + u8 v22 = (1 << (j + 3)) % gr->tpc_total; + nvkm_wr32(device, 0x41bfb0 + (i * 4), (v22 << 24) | + (v21 << 16) | + (v20 << 8) | + v19); + } + + /* UNK78xx */ + nvkm_wr32(device, 0x4078bc, (gr->tpc_total << 8) | + gr->screen_tile_row_offset); +} + +static void +gv100_grctx_generate_r400088(struct gf100_gr *gr, bool on) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_mask(device, 0x400088, 0x00060000, on ? 0x00060000 : 0x00000000); +} + +static void +gv100_grctx_generate_sm_id(struct gf100_gr *gr, int gpc, int tpc, int sm) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x608), sm); + nvkm_wr32(device, GPC_UNIT(gpc, 0x0c10 + tpc * 4), sm); + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x088), sm); +} + +static void +gv100_grctx_generate_unkn(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_mask(device, 0x41980c, 0x00000010, 0x00000010); + nvkm_mask(device, 0x41be08, 0x00000004, 0x00000004); + nvkm_mask(device, 0x4064c0, 0x80000000, 0x80000000); + nvkm_mask(device, 0x405800, 0x08000000, 0x08000000); + nvkm_mask(device, 0x419c00, 0x00000008, 0x00000008); +} + +static void +gv100_grctx_unkn88c(struct gf100_gr *gr, bool on) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + const u32 mask = 0x00000010, data = on ? mask : 0x00000000; + nvkm_mask(device, 0x40988c, mask, data); + nvkm_rd32(device, 0x40988c); + nvkm_mask(device, 0x41a88c, mask, data); + nvkm_rd32(device, 0x41a88c); + nvkm_mask(device, 0x408a14, mask, data); + nvkm_rd32(device, 0x408a14); +} + +const struct gf100_grctx_func +gv100_grctx = { + .unkn88c = gv100_grctx_unkn88c, + .main = gf100_grctx_generate_main, + .unkn = gv100_grctx_generate_unkn, + .sw_veid_bundle_init = gv100_grctx_pack_sw_veid_bundle_init, + .bundle = gm107_grctx_generate_bundle, + .bundle_size = 0x3000, + .bundle_min_gpm_fifo_depth = 0x180, + .bundle_token_limit = 0x1680, + .pagepool = gp100_grctx_generate_pagepool, + .pagepool_size = 0x20000, + .attrib = gv100_grctx_generate_attrib, + .attrib_nr_max = 0x6c0, + .attrib_nr = 0x480, + .alpha_nr_max = 0xc00, + .alpha_nr = 0x800, + .gfxp_nr = 0xd10, + .sm_id = gv100_grctx_generate_sm_id, + .rop_mapping = gv100_grctx_generate_rop_mapping, + .dist_skip_table = gm200_grctx_generate_dist_skip_table, + .r406500 = gm200_grctx_generate_r406500, + .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, + .smid_config = gp100_grctx_generate_smid_config, + .r400088 = gv100_grctx_generate_r400088, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 86ae5c706aa07..8dd4bd71b4fc3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -987,7 +987,7 @@ gf100_gr_trap_gpc_rop(struct gf100_gr *gr, int gpc) nvkm_wr32(device, GPC_UNIT(gpc, 0x0420), 0xc0000000); } -static const struct nvkm_enum gf100_mp_warp_error[] = { +const struct nvkm_enum gf100_mp_warp_error[] = { { 0x01, "STACK_ERROR" }, { 0x02, "API_STACK_ERROR" }, { 0x03, "RET_EMPTY_STACK_ERROR" }, @@ -1012,7 +1012,7 @@ static const struct nvkm_enum gf100_mp_warp_error[] = { {} }; -static const struct nvkm_bitfield gf100_mp_global_error[] = { +const struct nvkm_bitfield gf100_mp_global_error[] = { { 0x00000001, "SM_TO_SM_FAULT" }, { 0x00000002, "L1_ERROR" }, { 0x00000004, "MULTIPLE_WARP_ERRORS" }, @@ -2113,6 +2113,9 @@ gf100_gr_init(struct gf100_gr *gr) struct nvkm_device *device = gr->base.engine.subdev.device; int gpc, tpc, rop; + if (gr->func->init_419bd8) + gr->func->init_419bd8(gr); + gr->func->init_gpc_mmu(gr); if (gr->fuc_sw_nonctx) @@ -2213,6 +2216,9 @@ gf100_gr_init(struct gf100_gr *gr) gf100_gr_zbc_init(gr); + if (gr->func->init_4188a4) + gr->func->init_4188a4(gr); + return gf100_gr_init_ctxctl(gr); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index edf6edabf6dfb..dc46cf0131db3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -149,6 +149,7 @@ struct gf100_gr_func { void (*oneinit_tiles)(struct gf100_gr *); void (*oneinit_sm_id)(struct gf100_gr *); int (*init)(struct gf100_gr *); + void (*init_419bd8)(struct gf100_gr *); void (*init_gpc_mmu)(struct gf100_gr *); void (*init_r405a14)(struct gf100_gr *); void (*init_bios)(struct gf100_gr *); @@ -170,6 +171,7 @@ struct gf100_gr_func { void (*init_504430)(struct gf100_gr *, int gpc, int tpc); void (*init_shader_exceptions)(struct gf100_gr *, int gpc, int tpc); void (*init_400054)(struct gf100_gr *); + void (*init_4188a4)(struct gf100_gr *); void (*trap_mp)(struct gf100_gr *, int gpc, int tpc); void (*set_hww_esr_report_mask)(struct gf100_gr *); const struct gf100_gr_pack *mmio; @@ -266,7 +268,7 @@ extern const struct nvkm_object_func gf100_fermi; struct gf100_gr_init { u32 addr; u8 count; - u8 pitch; + u32 pitch; u32 data; }; @@ -337,6 +339,8 @@ extern const struct gf100_gr_init gf100_gr_init_fe_1[]; extern const struct gf100_gr_init gf100_gr_init_pe_1[]; void gf100_gr_init_gpc_mmu(struct gf100_gr *); void gf100_gr_trap_mp(struct gf100_gr *, int, int); +extern const struct nvkm_bitfield gf100_mp_global_error[]; +extern const struct nvkm_enum gf100_mp_warp_error[]; extern const struct gf100_gr_init gf104_gr_init_ds_0[]; extern const struct gf100_gr_init gf104_gr_init_tex_0[]; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gv100.c new file mode 100644 index 0000000000000..19173ea190962 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gv100.c @@ -0,0 +1,120 @@ +/* + * Copyright 2018 Red Hat Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "gf100.h" +#include "ctxgf100.h" + +#include + +static void +gv100_gr_trap_mp(struct gf100_gr *gr, int gpc, int tpc) +{ + struct nvkm_subdev *subdev = &gr->base.engine.subdev; + struct nvkm_device *device = subdev->device; + u32 werr = nvkm_rd32(device, TPC_UNIT(gpc, tpc, 0x730)); + u32 gerr = nvkm_rd32(device, TPC_UNIT(gpc, tpc, 0x734)); + const struct nvkm_enum *warp; + char glob[128]; + + nvkm_snprintbf(glob, sizeof(glob), gf100_mp_global_error, gerr); + warp = nvkm_enum_find(gf100_mp_warp_error, werr & 0xffff); + + nvkm_error(subdev, "GPC%i/TPC%i/MP trap: " + "global %08x [%s] warp %04x [%s]\n", + gpc, tpc, gerr, glob, werr, warp ? warp->name : ""); + + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x730), 0x00000000); + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x734), gerr); +} + +static void +gv100_gr_init_4188a4(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_mask(device, 0x4188a4, 0x03000000, 0x03000000); +} + +static void +gv100_gr_init_shader_exceptions(struct gf100_gr *gr, int gpc, int tpc) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + int sm; + for (sm = 0; sm < 0x100; sm += 0x80) { + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x728 + sm), 0x0085eb64); + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x610), 0x00000001); + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x72c + sm), 0x00000004); + } +} + +static void +gv100_gr_init_504430(struct gf100_gr *gr, int gpc, int tpc) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x430), 0x403f0000); +} + +static void +gv100_gr_init_419bd8(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + nvkm_mask(device, 0x419bd8, 0x00000700, 0x00000000); +} + +static const struct gf100_gr_func +gv100_gr = { + .oneinit_tiles = gm200_gr_oneinit_tiles, + .oneinit_sm_id = gm200_gr_oneinit_sm_id, + .init = gf100_gr_init, + .init_419bd8 = gv100_gr_init_419bd8, + .init_gpc_mmu = gm200_gr_init_gpc_mmu, + .init_vsc_stream_master = gk104_gr_init_vsc_stream_master, + .init_zcull = gf117_gr_init_zcull, + .init_num_active_ltcs = gm200_gr_init_num_active_ltcs, + .init_rop_active_fbps = gp100_gr_init_rop_active_fbps, + .init_swdx_pes_mask = gp102_gr_init_swdx_pes_mask, + .init_fecs_exceptions = gp100_gr_init_fecs_exceptions, + .init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2, + .init_sked_hww_esr = gk104_gr_init_sked_hww_esr, + .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, + .init_504430 = gv100_gr_init_504430, + .init_shader_exceptions = gv100_gr_init_shader_exceptions, + .init_4188a4 = gv100_gr_init_4188a4, + .trap_mp = gv100_gr_trap_mp, + .rops = gm200_gr_rops, + .gpc_nr = 6, + .tpc_nr = 5, + .ppc_nr = 3, + .grctx = &gv100_grctx, + .zbc = &gp102_gr_zbc, + .sclass = { + { -1, -1, FERMI_TWOD_A }, + { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, + { -1, -1, VOLTA_A, &gf100_fermi }, + { -1, -1, VOLTA_COMPUTE_A }, + {} + } +}; + +int +gv100_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr) +{ + return gm200_gr_new_(&gv100_gr, device, index, pgr); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c index 58a59b7db2e5f..771e16a16267e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c @@ -506,6 +506,7 @@ nvkm_msgqueue_new(u32 version, struct nvkm_falcon *falcon, break; case 0x0148cdec: case 0x015ccf3e: + case 0x0167d263: ret = msgqueue_0148cdec_new(falcon, sb, queue); break; default: diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp108.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp108.c index e8c27ec700de8..737a8d50a1f20 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp108.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp108.c @@ -65,3 +65,24 @@ MODULE_FIRMWARE("nvidia/gp108/nvdec/scrubber.bin"); MODULE_FIRMWARE("nvidia/gp108/sec2/desc.bin"); MODULE_FIRMWARE("nvidia/gp108/sec2/image.bin"); MODULE_FIRMWARE("nvidia/gp108/sec2/sig.bin"); + +MODULE_FIRMWARE("nvidia/gv100/acr/bl.bin"); +MODULE_FIRMWARE("nvidia/gv100/acr/unload_bl.bin"); +MODULE_FIRMWARE("nvidia/gv100/acr/ucode_load.bin"); +MODULE_FIRMWARE("nvidia/gv100/acr/ucode_unload.bin"); +MODULE_FIRMWARE("nvidia/gv100/gr/fecs_bl.bin"); +MODULE_FIRMWARE("nvidia/gv100/gr/fecs_inst.bin"); +MODULE_FIRMWARE("nvidia/gv100/gr/fecs_data.bin"); +MODULE_FIRMWARE("nvidia/gv100/gr/fecs_sig.bin"); +MODULE_FIRMWARE("nvidia/gv100/gr/gpccs_bl.bin"); +MODULE_FIRMWARE("nvidia/gv100/gr/gpccs_inst.bin"); +MODULE_FIRMWARE("nvidia/gv100/gr/gpccs_data.bin"); +MODULE_FIRMWARE("nvidia/gv100/gr/gpccs_sig.bin"); +MODULE_FIRMWARE("nvidia/gv100/gr/sw_ctx.bin"); +MODULE_FIRMWARE("nvidia/gv100/gr/sw_nonctx.bin"); +MODULE_FIRMWARE("nvidia/gv100/gr/sw_bundle_init.bin"); +MODULE_FIRMWARE("nvidia/gv100/gr/sw_method_init.bin"); +MODULE_FIRMWARE("nvidia/gv100/nvdec/scrubber.bin"); +MODULE_FIRMWARE("nvidia/gv100/sec2/desc.bin"); +MODULE_FIRMWARE("nvidia/gv100/sec2/image.bin"); +MODULE_FIRMWARE("nvidia/gv100/sec2/sig.bin"); From 54b202f1d83074074562f645e9d1ba4e7b6f1cca Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Tue, 24 Apr 2018 15:15:10 +0200 Subject: [PATCH 161/165] drm/nouveau: fix mode_valid's return type The method struct drm_connector_helper_funcs::mode_valid is defined as returning an 'enum drm_mode_status' but the driver implementation for this method uses an 'int' for it. Fix this by using 'enum drm_mode_status' in the driver too. Signed-off-by: Luc Van Oostenryck Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_connector.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 18e3239f76584..7b557c3543079 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -1005,7 +1005,7 @@ get_tmds_link_bandwidth(struct drm_connector *connector, bool hdmi) return 112000; } -static int +static enum drm_mode_status nouveau_connector_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { From f43cda5c76922777f4fe5026ee5984364ae5a918 Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Tue, 24 Apr 2018 15:15:38 +0200 Subject: [PATCH 162/165] drm/nouveau: fix nouveau_dsm_get_client_id()'s return type The method struct vga_switcheroo_handler::get_client_id() is defined as returning an 'enum vga_switcheroo_client_id' but the implementation in this driver, nouveau_dsm_get_client_id(), returns an 'int'. Fix this by returning 'enum vga_switcheroo_client_id' in this driver too. Signed-off-by: Luc Van Oostenryck Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 5ffcb66837761..ffb195850314d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -193,7 +193,7 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id, return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state); } -static int nouveau_dsm_get_client_id(struct pci_dev *pdev) +static enum vga_switcheroo_client_id nouveau_dsm_get_client_id(struct pci_dev *pdev) { /* easy option one - intel vendor ID means Integrated */ if (pdev->vendor == PCI_VENDOR_ID_INTEL) From 7a22c737faef99d6f75d7049c1a2f6f0fdefb1ec Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 22 Apr 2018 17:47:12 -0400 Subject: [PATCH 163/165] drm/nouveau: fix temp/pwm visibility, skip hwmon when no sensors exist A NV34 GPU was seeing temp and pwm entries in hwmon, which would error out when read. These should not have been visible, but also the whole hwmon object should just not have been registered in the first place. Signed-off-by: Ilia Mirkin Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_hwmon.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c b/drivers/gpu/drm/nouveau/nouveau_hwmon.c index 7c965648df804..44178b4c35998 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c +++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c @@ -327,7 +327,7 @@ nouveau_temp_is_visible(const void *data, u32 attr, int channel) struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data); struct nvkm_therm *therm = nvxx_therm(&drm->client.device); - if (therm && therm->attr_get && nvkm_therm_temp_get(therm) < 0) + if (!therm || !therm->attr_get || nvkm_therm_temp_get(therm) < 0) return 0; switch (attr) { @@ -351,8 +351,8 @@ nouveau_pwm_is_visible(const void *data, u32 attr, int channel) struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data); struct nvkm_therm *therm = nvxx_therm(&drm->client.device); - if (therm && therm->attr_get && therm->fan_get && - therm->fan_get(therm) < 0) + if (!therm || !therm->attr_get || !therm->fan_get || + therm->fan_get(therm) < 0) return 0; switch (attr) { @@ -707,13 +707,20 @@ nouveau_hwmon_init(struct drm_device *dev) { #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) struct nouveau_drm *drm = nouveau_drm(dev); + struct nvkm_iccsense *iccsense = nvxx_iccsense(&drm->client.device); struct nvkm_therm *therm = nvxx_therm(&drm->client.device); + struct nvkm_volt *volt = nvxx_volt(&drm->client.device); const struct attribute_group *special_groups[N_ATTR_GROUPS]; struct nouveau_hwmon *hwmon; struct device *hwmon_dev; int ret = 0; int i = 0; + if (!iccsense && !therm && !volt) { + NV_DEBUG(drm, "Skipping hwmon registration\n"); + return 0; + } + hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL); if (!hwmon) return -ENOMEM; @@ -749,6 +756,9 @@ nouveau_hwmon_fini(struct drm_device *dev) #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) struct nouveau_hwmon *hwmon = nouveau_hwmon(dev); + if (!hwmon) + return; + if (hwmon->hwmon) hwmon_device_unregister(hwmon->hwmon); From dd3b89be3eafd1c9977e350e81c5556230319101 Mon Sep 17 00:00:00 2001 From: Arushi Singhal Date: Tue, 8 May 2018 23:13:09 +1000 Subject: [PATCH 164/165] drm/nouveau/clk: Use list_for_each_entry_from_reverse It's better to use "list_for_each_entry_from_reverse" for iterating list than "for loop" as it makes the code more clear to read. This patch replace "for loop" with "list_for_each_entry_from_reverse" and "start" variable with "cstate" which helps in refactoring the code and also "cstate" variable is more commonly used in the other functions. changes in v2: "start" variable is removed, before "cstate" variable was removed but "cstate" is more common so preferred "cstate" over "start". Signed-off-by: Arushi Singhal Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c index 81c3567d4e67c..ba6a868d4c956 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c @@ -109,18 +109,17 @@ nvkm_cstate_valid(struct nvkm_clk *clk, struct nvkm_cstate *cstate, static struct nvkm_cstate * nvkm_cstate_find_best(struct nvkm_clk *clk, struct nvkm_pstate *pstate, - struct nvkm_cstate *start) + struct nvkm_cstate *cstate) { struct nvkm_device *device = clk->subdev.device; struct nvkm_volt *volt = device->volt; - struct nvkm_cstate *cstate; int max_volt; - if (!pstate || !start) + if (!pstate || !cstate) return NULL; if (!volt) - return start; + return cstate; max_volt = volt->max_uv; if (volt->max0_id != 0xff) @@ -133,8 +132,7 @@ nvkm_cstate_find_best(struct nvkm_clk *clk, struct nvkm_pstate *pstate, max_volt = min(max_volt, nvkm_volt_map(volt, volt->max2_id, clk->temp)); - for (cstate = start; &cstate->head != &pstate->list; - cstate = list_prev_entry(cstate, head)) { + list_for_each_entry_from_reverse(cstate, &pstate->list, head) { if (nvkm_cstate_valid(clk, cstate, max_volt, clk->temp)) break; } From 6c46d01f25bcf74608d09645c27c35c3f3940ebe Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 16 May 2018 12:07:32 +1000 Subject: [PATCH 165/165] drm/nouveau/gr/gf100-: insert some WFIs during gr init Inserted wait-for-gr-idle in the places it seems that RM does it, seems to prevent some random mmio timeouts on Quadro GV100. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c | 4 ++++ drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index f0f5a518e52a2..e813a3f8ea93d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1385,6 +1385,8 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_gr_mmio(gr, gr->fuc_sw_ctx); } + gf100_gr_wait_idle(gr); + idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000); grctx->pagepool(info); @@ -1396,6 +1398,8 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_floorsweep(gr); + gf100_gr_wait_idle(gr); + if (grctx->r400088) grctx->r400088(gr, false); if (gr->fuc_bundle) gf100_gr_icmd(gr, gr->fuc_bundle); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 8dd4bd71b4fc3..70d3d41e616c5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -2123,6 +2123,8 @@ gf100_gr_init(struct gf100_gr *gr) else gf100_gr_mmio(gr, gr->func->mmio); + gf100_gr_wait_idle(gr); + if (gr->func->init_r405a14) gr->func->init_r405a14(gr);