diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2022-06-01 13:47:52 +0300 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2022-11-09 03:44:58 +0300 |
commit | 2541626cfb794e57ba0575a6920826f591f7ced0 (patch) | |
tree | de53edee6959486a2ce6e8085820680cc14a41ba /drivers/gpu/drm/nouveau/nvkm/core | |
parent | e3f324956a32d08a9361ee1e3beca383f1b01eba (diff) | |
download | linux-2541626cfb794e57ba0575a6920826f591f7ced0.tar.xz |
drm/nouveau/acr: use common falcon HS FW code for ACR FWs
Adds context binding and support for FWs with a bootloader to the code
that was added to load VPR scrubber HS binaries, and ports ACR over to
using all of it.
- gv100 split from gp108 to handle FW exit status differences
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/core')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/core/firmware.c | 87 |
1 files changed, 86 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/firmware.c b/drivers/gpu/drm/nouveau/nvkm/core/firmware.c index aa1bf6b5a8cd..fcf2a002f6cb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/firmware.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/firmware.c @@ -22,6 +22,9 @@ #include <core/device.h> #include <core/firmware.h> +#include <subdev/fb.h> +#include <subdev/mmu.h> + int nvkm_firmware_load_name(const struct nvkm_subdev *subdev, const char *base, const char *name, int ver, const struct firmware **pfw) @@ -108,9 +111,70 @@ nvkm_firmware_put(const struct firmware *fw) release_firmware(fw); } +#define nvkm_firmware_mem(p) container_of((p), struct nvkm_firmware, mem.memory) + +static int +nvkm_firmware_mem_map(struct nvkm_memory *memory, u64 offset, struct nvkm_vmm *vmm, + struct nvkm_vma *vma, void *argv, u32 argc) +{ + struct nvkm_firmware *fw = nvkm_firmware_mem(memory); + struct nvkm_vmm_map map = { + .memory = &fw->mem.memory, + .offset = offset, + .sgl = &fw->mem.sgl, + }; + + if (WARN_ON(fw->func->type != NVKM_FIRMWARE_IMG_DMA)) + return -ENOSYS; + + return nvkm_vmm_map(vmm, vma, argv, argc, &map); +} + +static u64 +nvkm_firmware_mem_size(struct nvkm_memory *memory) +{ + return sg_dma_len(&nvkm_firmware_mem(memory)->mem.sgl); +} + +static u64 +nvkm_firmware_mem_addr(struct nvkm_memory *memory) +{ + return nvkm_firmware_mem(memory)->phys; +} + +static u8 +nvkm_firmware_mem_page(struct nvkm_memory *memory) +{ + return PAGE_SHIFT; +} + +static enum nvkm_memory_target +nvkm_firmware_mem_target(struct nvkm_memory *memory) +{ + return NVKM_MEM_TARGET_HOST; +} + +static void * +nvkm_firmware_mem_dtor(struct nvkm_memory *memory) +{ + return NULL; +} + +static const struct nvkm_memory_func +nvkm_firmware_mem = { + .dtor = nvkm_firmware_mem_dtor, + .target = nvkm_firmware_mem_target, + .page = nvkm_firmware_mem_page, + .addr = nvkm_firmware_mem_addr, + .size = nvkm_firmware_mem_size, + .map = nvkm_firmware_mem_map, +}; + void nvkm_firmware_dtor(struct nvkm_firmware *fw) { + struct nvkm_memory *memory = &fw->mem.memory; + if (!fw->img) return; @@ -118,6 +182,10 @@ nvkm_firmware_dtor(struct nvkm_firmware *fw) case NVKM_FIRMWARE_IMG_RAM: kfree(fw->img); break; + case NVKM_FIRMWARE_IMG_DMA: + nvkm_memory_unref(&memory); + dma_free_coherent(fw->device->dev, sg_dma_len(&fw->mem.sgl), fw->img, fw->phys); + break; default: WARN_ON(1); break; @@ -133,12 +201,28 @@ nvkm_firmware_ctor(const struct nvkm_firmware_func *func, const char *name, fw->func = func; fw->name = name; fw->device = device; + fw->len = len; switch (fw->func->type) { case NVKM_FIRMWARE_IMG_RAM: - fw->len = len; fw->img = kmemdup(src, fw->len, GFP_KERNEL); break; + case NVKM_FIRMWARE_IMG_DMA: { + dma_addr_t addr; + + len = ALIGN(fw->len, PAGE_SIZE); + + fw->img = dma_alloc_coherent(fw->device->dev, len, &addr, GFP_KERNEL); + if (fw->img) { + memcpy(fw->img, src, fw->len); + fw->phys = addr; + } + + sg_init_one(&fw->mem.sgl, fw->img, len); + sg_dma_address(&fw->mem.sgl) = fw->phys; + sg_dma_len(&fw->mem.sgl) = len; + } + break; default: WARN_ON(1); return -EINVAL; @@ -147,5 +231,6 @@ nvkm_firmware_ctor(const struct nvkm_firmware_func *func, const char *name, if (!fw->img) return -ENOMEM; + nvkm_memory_ctor(&nvkm_firmware_mem, &fw->mem.memory); return 0; } |