diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/core/engine.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/disp/changf119.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/gr/gv100.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/bios/vpstate.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b. | 0 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c | 25 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r367.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp10b.c | 2 |
14 files changed, 100 insertions, 30 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/engine.c b/drivers/gpu/drm/nouveau/nvkm/core/engine.c index d0322ce85172..1a47c40e171b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/engine.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/engine.c @@ -87,11 +87,12 @@ 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))) { + if (!IS_ERR((engine = nvkm_engine_ref(engine)))) { int ret = engine->func->info(engine, mthd, data); nvkm_engine_unref(&engine); return ret; } + return PTR_ERR(engine); } return -ENOSYS; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c index 78597da6313a..0e372a190d3f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c @@ -23,6 +23,10 @@ #ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER #include "priv.h" +#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) +#include <asm/dma-iommu.h> +#endif + static int nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev) { @@ -105,6 +109,15 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev) unsigned long pgsize_bitmap; int ret; +#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) + if (dev->archdata.mapping) { + struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); + + arm_iommu_detach_device(dev); + arm_iommu_release_mapping(mapping); + } +#endif + if (!tdev->func->iommu_bit) return; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/changf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/changf119.c index 29e6dd58ac48..525f95d06429 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/changf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/changf119.c @@ -52,7 +52,7 @@ 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; + const u32 mask = 0x00000001 << chan->chid.user; if (!en) { nvkm_mask(device, 0x610090, mask, 0x00000000); nvkm_mask(device, 0x6100a0, mask, 0x00000000); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c index 57719f675eec..bcf32d92ee5a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c @@ -166,8 +166,8 @@ 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; + const u32 mask = 0x00010001 << chan->chid.user; + const u32 data = en ? 0x00010000 << chan->chid.user : 0x00000000; nvkm_mask(device, 0x610028, mask, data); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gv100.c index 19173ea19096..3b3327789ae7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gv100.c @@ -25,24 +25,31 @@ #include <nvif/class.h> static void -gv100_gr_trap_mp(struct gf100_gr *gr, int gpc, int tpc) +gv100_gr_trap_sm(struct gf100_gr *gr, int gpc, int tpc, int sm) { 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)); + u32 werr = nvkm_rd32(device, TPC_UNIT(gpc, tpc, 0x730 + (sm * 0x80))); + u32 gerr = nvkm_rd32(device, TPC_UNIT(gpc, tpc, 0x734 + (sm * 0x80))); 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: " + nvkm_error(subdev, "GPC%i/TPC%i/SM%d trap: " "global %08x [%s] warp %04x [%s]\n", - gpc, tpc, gerr, glob, werr, warp ? warp->name : ""); + gpc, tpc, sm, gerr, glob, werr, warp ? warp->name : ""); + + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x730 + sm * 0x80), 0x00000000); + nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x734 + sm * 0x80), gerr); +} - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x730), 0x00000000); - nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x734), gerr); +static void +gv100_gr_trap_mp(struct gf100_gr *gr, int gpc, int tpc) +{ + gv100_gr_trap_sm(gr, gpc, tpc, 0); + gv100_gr_trap_sm(gr, gpc, tpc, 1); } static void 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/fault/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c index 007bf4af33b9..16ad91c91a7b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c @@ -133,8 +133,14 @@ nvkm_fault_oneinit(struct nvkm_subdev *subdev) } } - return nvkm_event_init(&nvkm_fault_ntfy, 1, fault->buffer_nr, - &fault->event); + 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 * diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c index 73c7728b5969..3cd610d7deb5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c @@ -176,8 +176,17 @@ gv100_fault_init(struct nvkm_fault *fault) 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, @@ -192,15 +201,5 @@ 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); + 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 index 44843ecf12b0..e4d2f5234fd1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h @@ -20,6 +20,7 @@ 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 *); 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/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/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 |