diff options
author | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2018-07-23 09:13:12 -0700 |
---|---|---|
committer | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2018-07-23 09:13:12 -0700 |
commit | c74a7469f97c0f40b46e82ee979f9fb1bb6e847c (patch) | |
tree | f2690a1a916b73ef94657fbf0e0141ae57701825 /drivers/gpu/drm/nouveau/nvkm/subdev | |
parent | 6f15a7de86c8cf2dc09fc9e6d07047efa40ef809 (diff) | |
parent | 500775074f88d9cf5416bed2ca19592812d62c41 (diff) |
Merge drm/drm-next into drm-intel-next-queued
We need a backmerge to get DP_DPCD_REV_14 before we push other
i915 changes to dinq that could break compilation.
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev')
45 files changed, 969 insertions, 37 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild index 3f5d38d74fba..cfdffef1afb9 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/bios/dp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c index 7c7efa4ea0d0..3133b28f849c 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 <subdev/bios/bit.h> #include <subdev/bios/dp.h> -static u16 +u16 nvbios_dp_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) { struct bit_entry d; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c index 73e463ed55c3..dea444d48f94 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c @@ -73,7 +73,8 @@ nvbios_iccsense_parse(struct nvkm_bios *bios, struct nvbios_iccsense *iccsense) } iccsense->nr_entry = cnt; - iccsense->rail = kmalloc(sizeof(struct pwr_rail_t) * cnt, GFP_KERNEL); + iccsense->rail = kmalloc_array(cnt, sizeof(struct pwr_rail_t), + GFP_KERNEL); if (!iccsense->rail) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c index 2ca23a9157ab..e6e804cee2bc 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; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c index 0f537c22804c..3634cd0630b8 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); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/vpstate.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/vpstate.c index 20b6fc8243e0..71524548de32 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/vpstate.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/vpstate.c @@ -58,8 +58,14 @@ nvbios_vpstate_parse(struct nvkm_bios *b, struct nvbios_vpstate_header *h) h->ecount = nvbios_rd08(b, h->offset + 0x5); h->base_id = nvbios_rd08(b, h->offset + 0x0f); - h->boost_id = nvbios_rd08(b, h->offset + 0x10); - h->tdp_id = nvbios_rd08(b, h->offset + 0x11); + if (h->hlen > 0x10) + h->boost_id = nvbios_rd08(b, h->offset + 0x10); + else + h->boost_id = 0xff; + if (h->hlen > 0x11) + h->tdp_id = nvbios_rd08(b, h->offset + 0x11); + else + h->tdp_id = 0xff; return 0; default: return -EINVAL; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c index 81c3567d4e67..ba6a868d4c95 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; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/Kbuild index eac88e3dc6e5..50a436926484 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 1730371933df..b80618e35491 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 000000000000..fbde6828bd38 --- /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 <subdev/bios.h> +#include <subdev/bios/pll.h> +#include <subdev/clk/pll.h> + +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 315ebaff1165..9b9f0dc1e192 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 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 000000000000..45bb46fb0929 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild @@ -0,0 +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/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c new file mode 100644 index 000000000000..16ad91c91a7b --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c @@ -0,0 +1,185 @@ +/* + * 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 <core/memory.h> +#include <core/notify.h> +#include <subdev/bar.h> +#include <subdev/mmu.h> + +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; + } + } + + ret = nvkm_event_init(&nvkm_fault_ntfy, 1, fault->buffer_nr, + &fault->event); + if (ret) + return ret; + + if (fault->func->oneinit) + ret = fault->func->oneinit(fault); + return ret; +} + +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/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp100.c new file mode 100644 index 000000000000..5e71db2e8d75 --- /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 <subdev/mmu.h> + +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); +} 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 000000000000..3cd610d7deb5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c @@ -0,0 +1,205 @@ +/* + * 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 <core/memory.h> +#include <subdev/mmu.h> +#include <engine/fifo.h> + +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 int +gv100_fault_oneinit(struct nvkm_fault *fault) +{ + return nvkm_notify_init(&fault->buffer[0]->object, &fault->event, + gv100_fault_ntfy_nrpfb, false, NULL, 0, 0, + &fault->nrpfb); +} + +static const struct nvkm_fault_func +gv100_fault = { + .oneinit = gv100_fault_oneinit, + .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) +{ + return nvkm_fault_new_(&gv100_fault, device, index, pfault); +} 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 000000000000..e4d2f5234fd1 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h @@ -0,0 +1,35 @@ +#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 <subdev/fault.h> + +#include <core/event.h> +#include <core/object.h> + +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 { + int (*oneinit)(struct nvkm_fault *); + 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 diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild index b4f22cce5d43..969610951263 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/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c index cdc4e0a2cc6b..e8dc4e913494 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/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c index 8137e19d3292..d3b8c3367152 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, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c index 147f69b30cd8..dffe1f5e1071 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 <core/memory.h> -static void +void gp100_fb_init_unkn(struct nvkm_fb *base) { struct nvkm_device *device = gf100_fb(base)->base.subdev.device; @@ -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 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 000000000000..3c5e02e9794a --- /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 414a423e0e55..2857f31466bf 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 diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c index 920b3d347803..bbfde1cb3a17 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c @@ -171,7 +171,7 @@ gt215_link_train(struct gt215_ram *ram) return -ENOSYS; /* XXX: Multiple partitions? */ - result = kmalloc(64 * sizeof(u32), GFP_KERNEL); + result = kmalloc_array(64, sizeof(u32), GFP_KERNEL); if (!result) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild index 12d6f4f102cb..290ff1c425a9 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 1f185274d3e6..23242179e600 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 e34d42108019..e923ed76d37a 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 000000000000..601747ada655 --- /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 e71cc25cc775..9dcde43c0f3c 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 diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gp100.c index 7321ad3758c3..43db245eec9a 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 2283e3b74277..ff8629de97d6 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 8869d79c2b59..d9e3691d45b7 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 diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 67ee983bb026..58a24e3a0598 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/gp10b. b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b. deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b. +++ /dev/null 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 000000000000..f666cb57f69e --- /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 <core/option.h> + +#include <nvif/class.h> + +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/mem.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.c index 39808489f21d..92e363dbbc5a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.c @@ -191,9 +191,9 @@ nvkm_mem_new_host(struct nvkm_mmu *mmu, int type, u8 page, u64 size, nvkm_memory_ctor(&nvkm_mem_dma, &mem->memory); size = ALIGN(size, PAGE_SIZE) >> PAGE_SHIFT; - if (!(mem->mem = kvmalloc(sizeof(*mem->mem) * size, GFP_KERNEL))) + if (!(mem->mem = kvmalloc_array(size, sizeof(*mem->mem), GFP_KERNEL))) return -ENOMEM; - if (!(mem->dma = kvmalloc(sizeof(*mem->dma) * size, GFP_KERNEL))) + if (!(mem->dma = kvmalloc_array(size, sizeof(*mem->dma), GFP_KERNEL))) return -ENOMEM; if (mmu->dma_bits > 32) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c index 1c12e58f44c2..de269eb482dd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c @@ -59,7 +59,7 @@ nvkm_vmm_pt_new(const struct nvkm_vmm_desc *desc, bool sparse, pgt->sparse = sparse; if (desc->type == PGD) { - pgt->pde = kvzalloc(sizeof(*pgt->pde) * pten, GFP_KERNEL); + pgt->pde = kvcalloc(pten, sizeof(*pgt->pde), GFP_KERNEL); if (!pgt->pde) { kfree(pgt); return NULL; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index da06e64d8a7d..1a3b0a3724ca 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 000000000000..2fa40c16e6d2 --- /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 <subdev/fb.h> +#include <subdev/ltc.h> + +#include <nvif/ifc00d.h> +#include <nvif/unpack.h> + +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); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c index a721354249ce..d02e183717dc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c @@ -414,6 +414,20 @@ acr_r352_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs, { struct ls_ucode_img *_img; u32 pos = 0; + u32 max_desc_size = 0; + u8 *gdesc; + + /* Figure out how large we need gdesc to be. */ + list_for_each_entry(_img, imgs, node) { + const struct acr_r352_ls_func *ls_func = + acr->func->ls_func[_img->falcon_id]; + + max_desc_size = max(max_desc_size, ls_func->bl_desc_size); + } + + gdesc = kmalloc(max_desc_size, GFP_KERNEL); + if (!gdesc) + return -ENOMEM; nvkm_kmap(wpr_blob); @@ -421,7 +435,6 @@ acr_r352_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs, struct ls_ucode_img_r352 *img = ls_ucode_img_r352(_img); const struct acr_r352_ls_func *ls_func = acr->func->ls_func[_img->falcon_id]; - u8 gdesc[ls_func->bl_desc_size]; nvkm_gpuobj_memcpy_to(wpr_blob, pos, &img->wpr_header, sizeof(img->wpr_header)); @@ -447,6 +460,8 @@ acr_r352_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs, nvkm_done(wpr_blob); + kfree(gdesc); + return 0; } @@ -771,7 +786,11 @@ acr_r352_load(struct nvkm_acr *_acr, struct nvkm_falcon *falcon, struct fw_bl_desc *hsbl_desc; void *bl, *blob_data, *hsbl_code, *hsbl_data; u32 code_size; - u8 bl_desc[bl_desc_size]; + u8 *bl_desc; + + bl_desc = kzalloc(bl_desc_size, GFP_KERNEL); + if (!bl_desc) + return -ENOMEM; /* Find the bootloader descriptor for our blob and copy it */ if (blob == acr->load_blob) { @@ -802,7 +821,6 @@ acr_r352_load(struct nvkm_acr *_acr, struct nvkm_falcon *falcon, code_size, hsbl_desc->start_tag, 0, false); /* Generate the BL header */ - memset(bl_desc, 0, bl_desc_size); acr->func->generate_hs_bl_desc(load_hdr, bl_desc, offset); /* @@ -811,6 +829,7 @@ acr_r352_load(struct nvkm_acr *_acr, struct nvkm_falcon *falcon, nvkm_falcon_load_dmem(falcon, bl_desc, hsbl_desc->dmem_load_off, bl_desc_size, 0); + kfree(bl_desc); return hsbl_desc->start_tag << 8; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r367.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r367.c index 866877b88797..978ad0790367 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r367.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r367.c @@ -265,6 +265,19 @@ acr_r367_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs, { struct ls_ucode_img *_img; u32 pos = 0; + u32 max_desc_size = 0; + u8 *gdesc; + + list_for_each_entry(_img, imgs, node) { + const struct acr_r352_ls_func *ls_func = + acr->func->ls_func[_img->falcon_id]; + + max_desc_size = max(max_desc_size, ls_func->bl_desc_size); + } + + gdesc = kmalloc(max_desc_size, GFP_KERNEL); + if (!gdesc) + return -ENOMEM; nvkm_kmap(wpr_blob); @@ -272,7 +285,6 @@ acr_r367_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs, struct ls_ucode_img_r367 *img = ls_ucode_img_r367(_img); const struct acr_r352_ls_func *ls_func = acr->func->ls_func[_img->falcon_id]; - u8 gdesc[ls_func->bl_desc_size]; nvkm_gpuobj_memcpy_to(wpr_blob, pos, &img->wpr_header, sizeof(img->wpr_header)); @@ -298,6 +310,8 @@ acr_r367_ls_write_wpr(struct acr_r352 *acr, struct list_head *imgs, nvkm_done(wpr_blob); + kfree(gdesc); + return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c index 30491d132d59..df8b919dcf09 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c @@ -129,6 +129,7 @@ gm20b_secboot_new(struct nvkm_device *device, int index, return 0; } +#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) MODULE_FIRMWARE("nvidia/gm20b/acr/bl.bin"); MODULE_FIRMWARE("nvidia/gm20b/acr/ucode_load.bin"); MODULE_FIRMWARE("nvidia/gm20b/gr/fecs_bl.bin"); @@ -144,3 +145,4 @@ MODULE_FIRMWARE("nvidia/gm20b/gr/sw_method_init.bin"); MODULE_FIRMWARE("nvidia/gm20b/pmu/desc.bin"); MODULE_FIRMWARE("nvidia/gm20b/pmu/image.bin"); MODULE_FIRMWARE("nvidia/gm20b/pmu/sig.bin"); +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp108.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp108.c index e8c27ec700de..737a8d50a1f2 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"); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp10b.c index 632e9545e292..28ca29d0eeee 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp10b.c @@ -74,6 +74,7 @@ gp10b_secboot_new(struct nvkm_device *device, int index, return 0; } +#if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) MODULE_FIRMWARE("nvidia/gp10b/acr/bl.bin"); MODULE_FIRMWARE("nvidia/gp10b/acr/ucode_load.bin"); MODULE_FIRMWARE("nvidia/gp10b/gr/fecs_bl.bin"); @@ -91,3 +92,4 @@ MODULE_FIRMWARE("nvidia/gp10b/gr/sw_method_init.bin"); MODULE_FIRMWARE("nvidia/gp10b/pmu/desc.bin"); MODULE_FIRMWARE("nvidia/gp10b/pmu/image.bin"); MODULE_FIRMWARE("nvidia/gp10b/pmu/sig.bin"); +#endif 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 6f10b098676c..1e1f1c635cab 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); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c index fea4957291da..4f1f3e890650 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) |