diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm')
32 files changed, 264 insertions, 97 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/memory.c b/drivers/gpu/drm/nouveau/nvkm/core/memory.c index 4cc186262d34..38130ef272d6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/memory.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/memory.c @@ -140,7 +140,7 @@ nvkm_memory_new(struct nvkm_device *device, enum nvkm_memory_target target, { struct nvkm_instmem *imem = device->imem; struct nvkm_memory *memory; - int ret = -ENOSYS; + int ret; if (unlikely(target != NVKM_MEM_TARGET_INST || !imem)) return -ENOSYS; diff --git a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c index 79a8f9d305c5..49d468b45d3f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c @@ -221,3 +221,14 @@ nvkm_subdev_ctor(const struct nvkm_subdev_func *func, __mutex_init(&subdev->mutex, name, &nvkm_subdev_lock_class[index]); subdev->debug = nvkm_dbgopt(device->dbgopt, name); } + +int +nvkm_subdev_new_(const struct nvkm_subdev_func *func, + struct nvkm_device *device, int index, + struct nvkm_subdev **psubdev) +{ + if (!(*psubdev = kzalloc(sizeof(**psubdev), GFP_KERNEL))) + return -ENOMEM; + nvkm_subdev_ctor(func, device, index, *psubdev); + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 8ebbe1656008..5b90c2a1bf3d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2924,6 +2924,20 @@ nvkm_device_del(struct nvkm_device **pdevice) } } +static inline bool +nvkm_device_endianness(struct nvkm_device *device) +{ + u32 boot1 = nvkm_rd32(device, 0x000004) & 0x01000001; +#ifdef __BIG_ENDIAN + if (!boot1) + return false; +#else + if (boot1) + return false; +#endif + return true; +} + int nvkm_device_ctor(const struct nvkm_device_func *func, const struct nvkm_device_quirk *quirk, @@ -2934,8 +2948,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, { struct nvkm_subdev *subdev; u64 mmio_base, mmio_size; - u32 boot0, strap; - void __iomem *map; + u32 boot0, boot1, strap; int ret = -EEXIST, i; unsigned chipset; @@ -2961,26 +2974,30 @@ nvkm_device_ctor(const struct nvkm_device_func *func, mmio_base = device->func->resource_addr(device, 0); mmio_size = device->func->resource_size(device, 0); - /* identify the chipset, and determine classes of subdev/engines */ - if (detect) { - map = ioremap(mmio_base, 0x102000); - if (ret = -ENOMEM, map == NULL) + if (detect || mmio) { + device->pri = ioremap(mmio_base, mmio_size); + if (device->pri == NULL) { + nvdev_error(device, "unable to map PRI\n"); + ret = -ENOMEM; goto done; + } + } + /* identify the chipset, and determine classes of subdev/engines */ + if (detect) { /* switch mmio to cpu's native endianness */ -#ifndef __BIG_ENDIAN - if (ioread32_native(map + 0x000004) != 0x00000000) { -#else - if (ioread32_native(map + 0x000004) == 0x00000000) { -#endif - iowrite32_native(0x01000001, map + 0x000004); - ioread32_native(map); + if (!nvkm_device_endianness(device)) { + nvkm_wr32(device, 0x000004, 0x01000001); + nvkm_rd32(device, 0x000000); + if (!nvkm_device_endianness(device)) { + nvdev_error(device, + "GPU not supported on big-endian\n"); + ret = -ENOSYS; + goto done; + } } - /* read boot0 and strapping information */ - boot0 = ioread32_native(map + 0x000000); - strap = ioread32_native(map + 0x101000); - iounmap(map); + boot0 = nvkm_rd32(device, 0x000000); /* chipset can be overridden for devel/testing purposes */ chipset = nvkm_longopt(device->cfgopt, "NvChipset", 0); @@ -3138,6 +3155,17 @@ nvkm_device_ctor(const struct nvkm_device_func *func, nvdev_info(device, "NVIDIA %s (%08x)\n", device->chip->name, boot0); + /* vGPU detection */ + boot1 = nvkm_rd32(device, 0x0000004); + if (device->card_type >= TU100 && (boot1 & 0x00030000)) { + nvdev_info(device, "vGPUs are not supported\n"); + ret = -ENODEV; + goto done; + } + + /* read strapping information */ + strap = nvkm_rd32(device, 0x101000); + /* determine frequency of timing crystal */ if ( device->card_type <= NV_10 || device->chipset < 0x17 || (device->chipset >= 0x20 && device->chipset < 0x25)) @@ -3158,15 +3186,6 @@ nvkm_device_ctor(const struct nvkm_device_func *func, if (!device->name) device->name = device->chip->name; - if (mmio) { - device->pri = ioremap(mmio_base, mmio_size); - if (!device->pri) { - nvdev_error(device, "unable to map PRI\n"); - ret = -ENOMEM; - goto done; - } - } - mutex_init(&device->mutex); for (i = 0; i < NVKM_SUBDEV_NR; i++) { @@ -3254,6 +3273,10 @@ nvkm_device_ctor(const struct nvkm_device_func *func, ret = 0; done: + if (device->pri && (!mmio || ret)) { + iounmap(device->pri); + device->pri = NULL; + } mutex_unlock(&nv_devices_mutex); return ret; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild index 0d584d0da59c..571687ba85b8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild @@ -47,6 +47,7 @@ nvkm-y += nvkm/engine/disp/dp.o nvkm-y += nvkm/engine/disp/hdagt215.o nvkm-y += nvkm/engine/disp/hdagf119.o +nvkm-y += nvkm/engine/disp/hdagv100.o nvkm-y += nvkm/engine/disp/hdmi.o nvkm-y += nvkm/engine/disp/hdmig84.o @@ -74,6 +75,8 @@ nvkm-y += nvkm/engine/disp/rootgp102.o nvkm-y += nvkm/engine/disp/rootgv100.o nvkm-y += nvkm/engine/disp/roottu102.o +nvkm-y += nvkm/engine/disp/capsgv100.o + nvkm-y += nvkm/engine/disp/channv50.o nvkm-y += nvkm/engine/disp/changf119.o nvkm-y += nvkm/engine/disp/changv100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/capsgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/capsgv100.c new file mode 100644 index 000000000000..5026e530f4bb --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/capsgv100.c @@ -0,0 +1,60 @@ +/* + * Copyright 2020 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_disp_caps(p) container_of((p), struct gv100_disp_caps, object) +#include "rootnv50.h" + +struct gv100_disp_caps { + struct nvkm_object object; + struct nv50_disp *disp; +}; + +static int +gv100_disp_caps_map(struct nvkm_object *object, void *argv, u32 argc, + enum nvkm_object_map *type, u64 *addr, u64 *size) +{ + struct gv100_disp_caps *caps = gv100_disp_caps(object); + struct nvkm_device *device = caps->disp->base.engine.subdev.device; + *type = NVKM_OBJECT_MAP_IO; + *addr = 0x640000 + device->func->resource_addr(device, 0); + *size = 0x1000; + return 0; +} + +static const struct nvkm_object_func +gv100_disp_caps = { + .map = gv100_disp_caps_map, +}; + +int +gv100_disp_caps_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nv50_disp *disp, struct nvkm_object **pobject) +{ + struct gv100_disp_caps *caps; + + if (!(caps = kzalloc(sizeof(*caps), GFP_KERNEL))) + return -ENOMEM; + *pobject = &caps->object; + + nvkm_object_ctor(&gv100_disp_caps, oclass, &caps->object); + caps->disp = disp; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c index 0fa0ec0a1de0..19d2d58344e4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf119.c @@ -24,10 +24,18 @@ #include "ior.h" void -gf119_hda_eld(struct nvkm_ior *ior, u8 *data, u8 size) +gf119_hda_device_entry(struct nvkm_ior *ior, int head) { struct nvkm_device *device = ior->disp->engine.subdev.device; - const u32 soff = 0x030 * ior->id; + const u32 hoff = 0x800 * head; + nvkm_mask(device, 0x616548 + hoff, 0x00000070, head << 4); +} + +void +gf119_hda_eld(struct nvkm_ior *ior, int head, u8 *data, u8 size) +{ + struct nvkm_device *device = ior->disp->engine.subdev.device; + const u32 soff = 0x030 * ior->id + (head * 0x04); int i; for (i = 0; i < size; i++) @@ -41,14 +49,14 @@ void gf119_hda_hpd(struct nvkm_ior *ior, int head, bool present) { struct nvkm_device *device = ior->disp->engine.subdev.device; - const u32 hoff = 0x800 * head; + const u32 soff = 0x030 * ior->id + (head * 0x04); u32 data = 0x80000000; u32 mask = 0x80000001; if (present) { - nvkm_mask(device, 0x616548 + hoff, 0x00000070, 0x00000000); + ior->func->hda.device_entry(ior, head); data |= 0x00000001; } else { mask |= 0x00000002; } - nvkm_mask(device, 0x10ec10 + ior->id * 0x030, mask, data); + nvkm_mask(device, 0x10ec10 + soff, mask, data); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c index 4509d2ba880e..0d1b81fe1093 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c @@ -24,7 +24,7 @@ #include "ior.h" void -gt215_hda_eld(struct nvkm_ior *ior, u8 *data, u8 size) +gt215_hda_eld(struct nvkm_ior *ior, int head, u8 *data, u8 size) { struct nvkm_device *device = ior->disp->engine.subdev.device; const u32 soff = ior->id * 0x800; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagv100.c new file mode 100644 index 000000000000..57d374ecfeef --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagv100.c @@ -0,0 +1,30 @@ +/* + * Copyright 2020 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" + +void +gv100_hda_device_entry(struct nvkm_ior *ior, int head) +{ + struct nvkm_device *device = ior->disp->engine.subdev.device; + const u32 hoff = 0x800 * head; + nvkm_mask(device, 0x616528 + hoff, 0x00000070, head << 4); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h index 009d3a8b7a50..c1d7a36e4d3c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h @@ -87,7 +87,8 @@ struct nvkm_ior_func { struct { void (*hpd)(struct nvkm_ior *, int head, bool present); - void (*eld)(struct nvkm_ior *, u8 *data, u8 size); + void (*eld)(struct nvkm_ior *, int head, u8 *data, u8 size); + void (*device_entry)(struct nvkm_ior *, int head); } hda; }; @@ -158,10 +159,13 @@ void gv100_hdmi_ctrl(struct nvkm_ior *, int, bool, u8, u8, u8 *, u8 , u8 *, u8); void gm200_hdmi_scdc(struct nvkm_ior *, int, u8); void gt215_hda_hpd(struct nvkm_ior *, int, bool); -void gt215_hda_eld(struct nvkm_ior *, u8 *, u8); +void gt215_hda_eld(struct nvkm_ior *, int, u8 *, u8); void gf119_hda_hpd(struct nvkm_ior *, int, bool); -void gf119_hda_eld(struct nvkm_ior *, u8 *, u8); +void gf119_hda_eld(struct nvkm_ior *, int, u8 *, u8); +void gf119_hda_device_entry(struct nvkm_ior *, int); + +void gv100_hda_device_entry(struct nvkm_ior *, int); #define IOR_MSG(i,l,f,a...) do { \ struct nvkm_ior *_ior = (i); \ diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgv100.c index 9c658d632d37..47efb48d769a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgv100.c @@ -27,6 +27,7 @@ static const struct nv50_disp_root_func gv100_disp_root = { .user = { + {{-1,-1,GV100_DISP_CAPS }, gv100_disp_caps_new }, {{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 }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c index 5f758948d6e1..a7672ef17d3b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c @@ -155,7 +155,7 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size) if (outp->info.type == DCB_OUTPUT_DP) ior->func->dp.audio(ior, hidx, true); ior->func->hda.hpd(ior, hidx, true); - ior->func->hda.eld(ior, data, size); + ior->func->hda.eld(ior, hidx, data, size); } else { if (outp->info.type == DCB_OUTPUT_DP) ior->func->dp.audio(ior, hidx, false); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h index a1f942793f98..7070f5408d92 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.h @@ -24,6 +24,9 @@ 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 gv100_disp_caps_new(const struct nvkm_oclass *, void *, u32, + struct nv50_disp *, struct nvkm_object **); + extern const struct nvkm_disp_oclass nv50_disp_root_oclass; extern const struct nvkm_disp_oclass g84_disp_root_oclass; extern const struct nvkm_disp_oclass g94_disp_root_oclass; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/roottu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/roottu102.c index 579a5d02308a..d8719d38b98a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/roottu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/roottu102.c @@ -27,6 +27,7 @@ static const struct nv50_disp_root_func tu102_disp_root = { .user = { + {{-1,-1,GV100_DISP_CAPS }, gv100_disp_caps_new }, {{0,0,TU102_DISP_CURSOR }, gv100_disp_curs_new }, {{0,0,TU102_DISP_WINDOW_IMM_CHANNEL_DMA}, gv100_disp_wimm_new }, {{0,0,TU102_DISP_CORE_CHANNEL_DMA }, gv100_disp_core_new }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c index 456a5a143522..3b3643fb1019 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c @@ -177,6 +177,7 @@ gf119_sor = { .hda = { .hpd = gf119_hda_hpd, .eld = gf119_hda_eld, + .device_entry = gf119_hda_device_entry, }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c index b94090edaebf..0c0925680790 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c @@ -43,6 +43,7 @@ gk104_sor = { .hda = { .hpd = gf119_hda_hpd, .eld = gf119_hda_eld, + .device_entry = gf119_hda_device_entry, }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c index e6965dec09c9..38045c92197f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c @@ -57,6 +57,7 @@ gm107_sor = { .hda = { .hpd = gf119_hda_hpd, .eld = gf119_hda_eld, + .device_entry = gf119_hda_device_entry, }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c index 384f82652bec..cf2075db742a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c @@ -115,6 +115,7 @@ gm200_sor = { .hda = { .hpd = gf119_hda_hpd, .eld = gf119_hda_eld, + .device_entry = gf119_hda_device_entry, }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c index b0597ff9a714..d11a0dff10c6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c @@ -103,6 +103,7 @@ gv100_sor = { .hda = { .hpd = gf119_hda_hpd, .eld = gf119_hda_eld, + .device_entry = gv100_hda_device_entry, }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c index 4d5f3791ea7b..fa6d74251237 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c @@ -88,6 +88,7 @@ tu102_sor = { .hda = { .hpd = gf119_hda_hpd, .eld = gf119_hda_eld, + .device_entry = gv100_hda_device_entry, }, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c index 4209b24a46d7..ec330d791d15 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c @@ -319,6 +319,17 @@ gk20a_gr_load_sw(struct gf100_gr *gr, const char *path, int ver) return 0; } +#if IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) || IS_ENABLED(CONFIG_ARCH_TEGRA_132_SOC) +MODULE_FIRMWARE("nvidia/gk20a/fecs_data.bin"); +MODULE_FIRMWARE("nvidia/gk20a/fecs_inst.bin"); +MODULE_FIRMWARE("nvidia/gk20a/gpccs_data.bin"); +MODULE_FIRMWARE("nvidia/gk20a/gpccs_inst.bin"); +MODULE_FIRMWARE("nvidia/gk20a/sw_bundle_init.bin"); +MODULE_FIRMWARE("nvidia/gk20a/sw_ctx.bin"); +MODULE_FIRMWARE("nvidia/gk20a/sw_method_init.bin"); +MODULE_FIRMWARE("nvidia/gk20a/sw_nonctx.bin"); +#endif + static int gk20a_gr_load(struct gf100_gr *gr, int ver, const struct gf100_gr_fwif *fwif) { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c index 8eb2a930a9b5..e4866a02e457 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c @@ -250,6 +250,11 @@ nvkm_acr_oneinit(struct nvkm_subdev *subdev) list_add_tail(&lsf->head, &acr->lsf); } + /* Ensure the falcon that'll provide ACR functions is booted first. */ + lsf = nvkm_acr_falcon(device); + if (lsf) + list_move(&lsf->head, &acr->lsf); + if (!acr->wpr_fw || acr->wpr_comp) wpr_size = acr->func->wpr_layout(acr); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/hsfw.c b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/hsfw.c index aecce2dac558..667fa016496e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/hsfw.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/hsfw.c @@ -100,25 +100,21 @@ nvkm_acr_hsfw_load_image(struct nvkm_acr *acr, const char *name, int ver, hsfw->data_size = lhdr->data_size; hsfw->sig.prod.size = fwhdr->sig_prod_size; - hsfw->sig.prod.data = kmalloc(hsfw->sig.prod.size, GFP_KERNEL); + hsfw->sig.prod.data = kmemdup(fw->data + fwhdr->sig_prod_offset + sig, + hsfw->sig.prod.size, GFP_KERNEL); if (!hsfw->sig.prod.data) { ret = -ENOMEM; goto done; } - memcpy(hsfw->sig.prod.data, fw->data + fwhdr->sig_prod_offset + sig, - hsfw->sig.prod.size); - hsfw->sig.dbg.size = fwhdr->sig_dbg_size; - hsfw->sig.dbg.data = kmalloc(hsfw->sig.dbg.size, GFP_KERNEL); + hsfw->sig.dbg.data = kmemdup(fw->data + fwhdr->sig_dbg_offset + sig, + hsfw->sig.dbg.size, GFP_KERNEL); if (!hsfw->sig.dbg.data) { ret = -ENOMEM; goto done; } - memcpy(hsfw->sig.dbg.data, fw->data + fwhdr->sig_dbg_offset + sig, - hsfw->sig.dbg.size); - hsfw->sig.patch_loc = loc; done: nvkm_firmware_put(fw); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c index 06572f8ce914..f9c427559538 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c @@ -22,22 +22,39 @@ */ #include "priv.h" -#if defined(CONFIG_ACPI) && defined(CONFIG_X86) -int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len); -bool nouveau_acpi_rom_supported(struct device *); -#else -static inline bool -nouveau_acpi_rom_supported(struct device *dev) +static int +acpi_read_bios(acpi_handle rom_handle, u8 *bios, u32 offset, u32 length) { - return false; -} +#if defined(CONFIG_ACPI) && defined(CONFIG_X86) + acpi_status status; + union acpi_object rom_arg_elements[2], *obj; + struct acpi_object_list rom_arg; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; -static inline int -nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) -{ + rom_arg.count = 2; + rom_arg.pointer = &rom_arg_elements[0]; + + rom_arg_elements[0].type = ACPI_TYPE_INTEGER; + rom_arg_elements[0].integer.value = offset; + + rom_arg_elements[1].type = ACPI_TYPE_INTEGER; + rom_arg_elements[1].integer.value = length; + + status = acpi_evaluate_object(rom_handle, NULL, &rom_arg, &buffer); + if (ACPI_FAILURE(status)) { + pr_info("failed to evaluate ROM got %s\n", + acpi_format_exception(status)); + return -ENODEV; + } + obj = (union acpi_object *)buffer.pointer; + length = min(length, obj->buffer.length); + memcpy(bios+offset, obj->buffer.pointer, length); + kfree(buffer.pointer); + return length; +#else return -EINVAL; -} #endif +} /* This version of the shadow function disobeys the ACPI spec and tries * to fetch in units of more than 4KiB at a time. This is a LOT faster @@ -51,7 +68,7 @@ acpi_read_fast(void *data, u32 offset, u32 length, struct nvkm_bios *bios) u32 fetch = limit - start; if (nvbios_extend(bios, limit) >= 0) { - int ret = nouveau_acpi_get_bios_chunk(bios->data, start, fetch); + int ret = acpi_read_bios(data, bios->data, start, fetch); if (ret == fetch) return fetch; } @@ -73,9 +90,8 @@ acpi_read_slow(void *data, u32 offset, u32 length, struct nvkm_bios *bios) if (nvbios_extend(bios, limit) >= 0) { while (start + fetch < limit) { - int ret = nouveau_acpi_get_bios_chunk(bios->data, - start + fetch, - 0x1000); + int ret = acpi_read_bios(data, bios->data, + start + fetch, 0x1000); if (ret != 0x1000) break; fetch += 0x1000; @@ -88,9 +104,22 @@ acpi_read_slow(void *data, u32 offset, u32 length, struct nvkm_bios *bios) static void * acpi_init(struct nvkm_bios *bios, const char *name) { - if (!nouveau_acpi_rom_supported(bios->subdev.device->dev)) +#if defined(CONFIG_ACPI) && defined(CONFIG_X86) + acpi_status status; + acpi_handle dhandle, rom_handle; + + dhandle = ACPI_HANDLE(bios->subdev.device->dev); + if (!dhandle) return ERR_PTR(-ENODEV); - return NULL; + + status = acpi_get_handle(dhandle, "_ROM", &rom_handle); + if (ACPI_FAILURE(status)) + return ERR_PTR(-ENODEV); + + return rom_handle; +#else + return ERR_PTR(-ENODEV); +#endif } const struct nvbios_source diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c index d80dbc8f09b2..2340040942c9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c @@ -114,9 +114,5 @@ int gf100_ibus_new(struct nvkm_device *device, int index, struct nvkm_subdev **pibus) { - struct nvkm_subdev *ibus; - if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL))) - return -ENOMEM; - nvkm_subdev_ctor(&gf100_ibus, device, index, ibus); - return 0; + return nvkm_subdev_new_(&gf100_ibus, device, index, pibus); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c index 3905a80da811..1124dadac145 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c @@ -43,9 +43,5 @@ int gf117_ibus_new(struct nvkm_device *device, int index, struct nvkm_subdev **pibus) { - struct nvkm_subdev *ibus; - if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL))) - return -ENOMEM; - nvkm_subdev_ctor(&gf117_ibus, device, index, ibus); - return 0; + return nvkm_subdev_new_(&gf117_ibus, device, index, pibus); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c index 9025ed1bd2a9..f3915f85838e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c @@ -117,9 +117,5 @@ int gk104_ibus_new(struct nvkm_device *device, int index, struct nvkm_subdev **pibus) { - struct nvkm_subdev *ibus; - if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL))) - return -ENOMEM; - nvkm_subdev_ctor(&gk104_ibus, device, index, ibus); - return 0; + return nvkm_subdev_new_(&gk104_ibus, device, index, pibus); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c index 1a4ab825852c..187d544378b0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c @@ -81,9 +81,5 @@ int gk20a_ibus_new(struct nvkm_device *device, int index, struct nvkm_subdev **pibus) { - struct nvkm_subdev *ibus; - if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL))) - return -ENOMEM; - nvkm_subdev_ctor(&gk20a_ibus, device, index, ibus); - return 0; + return nvkm_subdev_new_(&gk20a_ibus, device, index, pibus); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c index c63328152bfa..0f1f0ad6377e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c @@ -32,9 +32,5 @@ int gm200_ibus_new(struct nvkm_device *device, int index, struct nvkm_subdev **pibus) { - struct nvkm_subdev *ibus; - if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL))) - return -ENOMEM; - nvkm_subdev_ctor(&gm200_ibus, device, index, ibus); - return 0; + return nvkm_subdev_new_(&gm200_ibus, device, index, pibus); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gp10b.c index 39db90aa2c80..0347b367cefe 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gp10b.c @@ -51,9 +51,5 @@ int gp10b_ibus_new(struct nvkm_device *device, int index, struct nvkm_subdev **pibus) { - struct nvkm_subdev *ibus; - if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL))) - return -ENOMEM; - nvkm_subdev_ctor(&gp10b_ibus, device, index, ibus); - return 0; + return nvkm_subdev_new_(&gp10b_ibus, device, index, pibus); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c index 41640e0584ac..199f94e15c5f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c @@ -580,7 +580,7 @@ nvkm_vmm_iter(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, it.pte[it.lvl]++; } } - }; + } nvkm_vmm_flush(&it); return ~0ULL; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index 5e55ecbd8005..d3f8f916d0db 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -304,7 +304,7 @@ int tu102_vmm_new(struct nvkm_mmu *, bool, u64, u64, void *, u32, FILL(VMM, PT, PTEI, _ptes, MAP, _addr); \ PTEI += _ptes; \ PTEN -= _ptes; \ - }; \ + } \ nvkm_done((PT)->memory); \ } while(0) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/ic.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/ic.c index 03b355dabab3..abf3eda683f0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/ic.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/ic.c @@ -36,8 +36,8 @@ probe_monitoring_device(struct nvkm_i2c_bus *bus, request_module("%s%s", I2C_MODULE_PREFIX, info->type); - client = i2c_new_device(&bus->i2c, info); - if (!client) + client = i2c_new_client_device(&bus->i2c, info); + if (IS_ERR(client)) return false; if (!client->dev.driver || |