Loading drivers/gpu/drm/nouveau/include/nvif/if500d.h +13 −0 Original line number Diff line number Diff line Loading @@ -5,4 +5,17 @@ struct nv50_vmm_vn { /* nvif_vmm_vX ... */ }; struct nv50_vmm_map_vn { /* nvif_vmm_map_vX ... */ }; struct nv50_vmm_map_v0 { /* nvif_vmm_map_vX ... */ __u8 version; __u8 ro; __u8 priv; __u8 kind; __u8 comp; }; #endif drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +19 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ #include <core/gpuobj.h> #include <subdev/fb.h> #include <nvif/if500d.h> struct nvkm_mmu_ptp { struct nvkm_mmu_pt *pt; struct list_head head; Loading Loading @@ -218,6 +220,9 @@ nvkm_vm_map_(const struct nvkm_vmm_page *page, struct nvkm_vma *vma, u64 delta, struct nvkm_mem *mem, nvkm_vmm_pte_func fn, struct nvkm_vmm_map *map) { union { struct nv50_vmm_map_v0 nv50; } args; struct nvkm_vmm *vmm = vma->vm; void *argv = NULL; u32 argc = 0; Loading @@ -227,6 +232,20 @@ nvkm_vm_map_(const struct nvkm_vmm_page *page, struct nvkm_vma *vma, u64 delta, map->page = page; if (vmm->func->valid) { switch (vmm->mmu->subdev.device->card_type) { case NV_50: args.nv50.version = 0; args.nv50.ro = !(vma->access & NV_MEM_ACCESS_WO); args.nv50.priv = !!(vma->access & NV_MEM_ACCESS_SYS); args.nv50.kind = (mem->memtype & 0x07f); args.nv50.comp = (mem->memtype & 0x180) >> 7; argv = &args.nv50; argc = sizeof(args.nv50); break; default: break; } ret = vmm->func->valid(vmm, argv, argc, map); if (WARN_ON(ret)) return; Loading drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c +1 −5 Original line number Diff line number Diff line Loading @@ -30,12 +30,8 @@ g84_mmu = { .pgt_bits = 29 - 12, .spg_shift = 12, .lpg_shift = 16, .map_pgt = nv50_vm_map_pgt, .map = nv50_vm_map, .map_sg = nv50_vm_map_sg, .unmap = nv50_vm_unmap, .flush = nv50_vm_flush, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x0200 }, .kind = nv50_mmu_kind, }; int Loading drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c +32 −181 Original line number Diff line number Diff line Loading @@ -23,185 +23,40 @@ */ #include "vmm.h" #include <core/gpuobj.h> #include <subdev/fb.h> #include <subdev/timer.h> #include <engine/gr.h> #include <nvif/class.h> void nv50_vm_map_pgt(struct nvkm_vmm *vmm, u32 pde, struct nvkm_memory *pgt[2]) { struct nvkm_vmm_join *join; u32 pdeo = vmm->mmu->func->vmm.pd_offset + (pde * 8); u64 phys = 0xdeadcafe00000000ULL; u32 coverage = 0; if (pgt[0]) { /* present, 4KiB pages */ phys = 0x00000003 | nvkm_memory_addr(pgt[0]); coverage = (nvkm_memory_size(pgt[0]) >> 3) << 12; } else if (pgt[1]) { /* present, 64KiB pages */ phys = 0x00000001 | nvkm_memory_addr(pgt[1]); coverage = (nvkm_memory_size(pgt[1]) >> 3) << 16; } if (phys & 1) { if (coverage <= 32 * 1024 * 1024) phys |= 0x60; else if (coverage <= 64 * 1024 * 1024) phys |= 0x40; else if (coverage <= 128 * 1024 * 1024) phys |= 0x20; } list_for_each_entry(join, &vmm->join, head) { nvkm_kmap(join->inst); nvkm_wo32(join->inst, pdeo + 0, lower_32_bits(phys)); nvkm_wo32(join->inst, pdeo + 4, upper_32_bits(phys)); nvkm_done(join->inst); } } static inline u64 vm_addr(struct nvkm_vma *vma, u64 phys, u32 memtype, u32 target) const u8 * nv50_mmu_kind(struct nvkm_mmu *base, int *count) { phys |= 1; /* present */ phys |= (u64)memtype << 40; phys |= target << 4; if (vma->access & NV_MEM_ACCESS_SYS) phys |= (1 << 6); if (!(vma->access & NV_MEM_ACCESS_WO)) phys |= (1 << 3); return phys; } void nv50_vm_map(struct nvkm_vma *vma, struct nvkm_memory *pgt, struct nvkm_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta) { struct nvkm_ram *ram = vma->vm->mmu->subdev.device->fb->ram; u32 comp = (mem->memtype & 0x180) >> 7; u32 block, target; int i; /* IGPs don't have real VRAM, re-target to stolen system memory */ target = 0; if (ram->stolen) { phys += ram->stolen; target = 3; } phys = vm_addr(vma, phys, mem->memtype, target); pte <<= 3; cnt <<= 3; nvkm_kmap(pgt); while (cnt) { u32 offset_h = upper_32_bits(phys); u32 offset_l = lower_32_bits(phys); for (i = 7; i >= 0; i--) { block = 1 << (i + 3); if (cnt >= block && !(pte & (block - 1))) break; } offset_l |= (i << 7); phys += block << (vma->node->type - 3); cnt -= block; if (comp) { u32 tag = mem->tag->offset + ((delta >> 16) * comp); offset_h |= (tag << 17); delta += block << (vma->node->type - 3); } while (block) { nvkm_wo32(pgt, pte + 0, offset_l); nvkm_wo32(pgt, pte + 4, offset_h); pte += 8; block -= 8; } } nvkm_done(pgt); } void nv50_vm_map_sg(struct nvkm_vma *vma, struct nvkm_memory *pgt, struct nvkm_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) { u32 target = (vma->access & NV_MEM_ACCESS_NOSNOOP) ? 3 : 2; pte <<= 3; nvkm_kmap(pgt); while (cnt--) { u64 phys = vm_addr(vma, (u64)*list++, mem->memtype, target); nvkm_wo32(pgt, pte + 0, lower_32_bits(phys)); nvkm_wo32(pgt, pte + 4, upper_32_bits(phys)); pte += 8; } nvkm_done(pgt); } void nv50_vm_unmap(struct nvkm_vma *vma, struct nvkm_memory *pgt, u32 pte, u32 cnt) { pte <<= 3; nvkm_kmap(pgt); while (cnt--) { nvkm_wo32(pgt, pte + 0, 0x00000000); nvkm_wo32(pgt, pte + 4, 0x00000000); pte += 8; } nvkm_done(pgt); } void nv50_vm_flush(struct nvkm_vm *vm) { struct nvkm_mmu *mmu = vm->mmu; struct nvkm_subdev *subdev = &mmu->subdev; struct nvkm_device *device = subdev->device; int i, vme; mutex_lock(&subdev->mutex); for (i = 0; i < NVKM_SUBDEV_NR; i++) { if (!atomic_read(&vm->engref[i])) continue; /* unfortunate hw bug workaround... */ if (i == NVKM_ENGINE_GR && device->gr) { int ret = nvkm_gr_tlb_flush(device->gr); if (ret != -ENODEV) continue; } switch (i) { case NVKM_ENGINE_GR : vme = 0x00; break; case NVKM_ENGINE_VP : case NVKM_ENGINE_MSPDEC: vme = 0x01; break; case NVKM_SUBDEV_BAR : vme = 0x06; break; case NVKM_ENGINE_MSPPP : case NVKM_ENGINE_MPEG : vme = 0x08; break; case NVKM_ENGINE_BSP : case NVKM_ENGINE_MSVLD : vme = 0x09; break; case NVKM_ENGINE_CIPHER: case NVKM_ENGINE_SEC : vme = 0x0a; break; case NVKM_ENGINE_CE0 : vme = 0x0d; break; default: continue; } nvkm_wr32(device, 0x100c80, (vme << 16) | 1); if (nvkm_msec(device, 2000, if (!(nvkm_rd32(device, 0x100c80) & 0x00000001)) break; ) < 0) nvkm_error(subdev, "vm flush timeout: engine %d\n", vme); } mutex_unlock(&subdev->mutex); /* 0x01: no bank swizzle * 0x02: bank swizzled * 0x7f: invalid * * 0x01/0x02 are values understood by the VRAM allocator, * and are required to avoid mixing the two types within * a certain range. */ static const u8 kind[128] = { 0x01, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, /* 0x00 */ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x7f, 0x7f, 0x7f, 0x7f, /* 0x10 */ 0x02, 0x02, 0x02, 0x02, 0x7f, 0x7f, 0x7f, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, /* 0x20 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, /* 0x30 */ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, /* 0x40 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x01, 0x01, 0x01, 0x7f, /* 0x50 */ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, /* 0x60 */ 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x7f, 0x02, 0x7f, 0x01, 0x7f, 0x02, 0x7f, /* 0x70 */ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x7f, 0x7f }; *count = ARRAY_SIZE(kind); return kind; } static const struct nvkm_mmu_func Loading @@ -211,12 +66,8 @@ nv50_mmu = { .pgt_bits = 29 - 12, .spg_shift = 12, .lpg_shift = 16, .map_pgt = nv50_vm_map_pgt, .map = nv50_vm_map, .map_sg = nv50_vm_map_sg, .unmap = nv50_vm_unmap, .flush = nv50_vm_flush, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x1400 }, .kind = nv50_mmu_kind, }; int Loading drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +3 −7 Original line number Diff line number Diff line Loading @@ -37,17 +37,13 @@ struct nvkm_mmu_func { bool global; u32 pd_offset; } vmm; const u8 *(*kind)(struct nvkm_mmu *, int *count); }; extern const struct nvkm_mmu_func nv04_mmu; void nv50_vm_map_pgt(struct nvkm_vmm *, u32, struct nvkm_memory **); void nv50_vm_map(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, u32, u32, u64, u64); void nv50_vm_map_sg(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, u32, u32, dma_addr_t *); void nv50_vm_unmap(struct nvkm_vma *, struct nvkm_memory *, u32, u32); void nv50_vm_flush(struct nvkm_vm *); const u8 *nv50_mmu_kind(struct nvkm_mmu *, int *count); void gf100_vm_map_pgt(struct nvkm_vmm *, u32, struct nvkm_memory **); void gf100_vm_map(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, Loading Loading
drivers/gpu/drm/nouveau/include/nvif/if500d.h +13 −0 Original line number Diff line number Diff line Loading @@ -5,4 +5,17 @@ struct nv50_vmm_vn { /* nvif_vmm_vX ... */ }; struct nv50_vmm_map_vn { /* nvif_vmm_map_vX ... */ }; struct nv50_vmm_map_v0 { /* nvif_vmm_map_vX ... */ __u8 version; __u8 ro; __u8 priv; __u8 kind; __u8 comp; }; #endif
drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +19 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ #include <core/gpuobj.h> #include <subdev/fb.h> #include <nvif/if500d.h> struct nvkm_mmu_ptp { struct nvkm_mmu_pt *pt; struct list_head head; Loading Loading @@ -218,6 +220,9 @@ nvkm_vm_map_(const struct nvkm_vmm_page *page, struct nvkm_vma *vma, u64 delta, struct nvkm_mem *mem, nvkm_vmm_pte_func fn, struct nvkm_vmm_map *map) { union { struct nv50_vmm_map_v0 nv50; } args; struct nvkm_vmm *vmm = vma->vm; void *argv = NULL; u32 argc = 0; Loading @@ -227,6 +232,20 @@ nvkm_vm_map_(const struct nvkm_vmm_page *page, struct nvkm_vma *vma, u64 delta, map->page = page; if (vmm->func->valid) { switch (vmm->mmu->subdev.device->card_type) { case NV_50: args.nv50.version = 0; args.nv50.ro = !(vma->access & NV_MEM_ACCESS_WO); args.nv50.priv = !!(vma->access & NV_MEM_ACCESS_SYS); args.nv50.kind = (mem->memtype & 0x07f); args.nv50.comp = (mem->memtype & 0x180) >> 7; argv = &args.nv50; argc = sizeof(args.nv50); break; default: break; } ret = vmm->func->valid(vmm, argv, argc, map); if (WARN_ON(ret)) return; Loading
drivers/gpu/drm/nouveau/nvkm/subdev/mmu/g84.c +1 −5 Original line number Diff line number Diff line Loading @@ -30,12 +30,8 @@ g84_mmu = { .pgt_bits = 29 - 12, .spg_shift = 12, .lpg_shift = 16, .map_pgt = nv50_vm_map_pgt, .map = nv50_vm_map, .map_sg = nv50_vm_map_sg, .unmap = nv50_vm_unmap, .flush = nv50_vm_flush, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x0200 }, .kind = nv50_mmu_kind, }; int Loading
drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c +32 −181 Original line number Diff line number Diff line Loading @@ -23,185 +23,40 @@ */ #include "vmm.h" #include <core/gpuobj.h> #include <subdev/fb.h> #include <subdev/timer.h> #include <engine/gr.h> #include <nvif/class.h> void nv50_vm_map_pgt(struct nvkm_vmm *vmm, u32 pde, struct nvkm_memory *pgt[2]) { struct nvkm_vmm_join *join; u32 pdeo = vmm->mmu->func->vmm.pd_offset + (pde * 8); u64 phys = 0xdeadcafe00000000ULL; u32 coverage = 0; if (pgt[0]) { /* present, 4KiB pages */ phys = 0x00000003 | nvkm_memory_addr(pgt[0]); coverage = (nvkm_memory_size(pgt[0]) >> 3) << 12; } else if (pgt[1]) { /* present, 64KiB pages */ phys = 0x00000001 | nvkm_memory_addr(pgt[1]); coverage = (nvkm_memory_size(pgt[1]) >> 3) << 16; } if (phys & 1) { if (coverage <= 32 * 1024 * 1024) phys |= 0x60; else if (coverage <= 64 * 1024 * 1024) phys |= 0x40; else if (coverage <= 128 * 1024 * 1024) phys |= 0x20; } list_for_each_entry(join, &vmm->join, head) { nvkm_kmap(join->inst); nvkm_wo32(join->inst, pdeo + 0, lower_32_bits(phys)); nvkm_wo32(join->inst, pdeo + 4, upper_32_bits(phys)); nvkm_done(join->inst); } } static inline u64 vm_addr(struct nvkm_vma *vma, u64 phys, u32 memtype, u32 target) const u8 * nv50_mmu_kind(struct nvkm_mmu *base, int *count) { phys |= 1; /* present */ phys |= (u64)memtype << 40; phys |= target << 4; if (vma->access & NV_MEM_ACCESS_SYS) phys |= (1 << 6); if (!(vma->access & NV_MEM_ACCESS_WO)) phys |= (1 << 3); return phys; } void nv50_vm_map(struct nvkm_vma *vma, struct nvkm_memory *pgt, struct nvkm_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta) { struct nvkm_ram *ram = vma->vm->mmu->subdev.device->fb->ram; u32 comp = (mem->memtype & 0x180) >> 7; u32 block, target; int i; /* IGPs don't have real VRAM, re-target to stolen system memory */ target = 0; if (ram->stolen) { phys += ram->stolen; target = 3; } phys = vm_addr(vma, phys, mem->memtype, target); pte <<= 3; cnt <<= 3; nvkm_kmap(pgt); while (cnt) { u32 offset_h = upper_32_bits(phys); u32 offset_l = lower_32_bits(phys); for (i = 7; i >= 0; i--) { block = 1 << (i + 3); if (cnt >= block && !(pte & (block - 1))) break; } offset_l |= (i << 7); phys += block << (vma->node->type - 3); cnt -= block; if (comp) { u32 tag = mem->tag->offset + ((delta >> 16) * comp); offset_h |= (tag << 17); delta += block << (vma->node->type - 3); } while (block) { nvkm_wo32(pgt, pte + 0, offset_l); nvkm_wo32(pgt, pte + 4, offset_h); pte += 8; block -= 8; } } nvkm_done(pgt); } void nv50_vm_map_sg(struct nvkm_vma *vma, struct nvkm_memory *pgt, struct nvkm_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) { u32 target = (vma->access & NV_MEM_ACCESS_NOSNOOP) ? 3 : 2; pte <<= 3; nvkm_kmap(pgt); while (cnt--) { u64 phys = vm_addr(vma, (u64)*list++, mem->memtype, target); nvkm_wo32(pgt, pte + 0, lower_32_bits(phys)); nvkm_wo32(pgt, pte + 4, upper_32_bits(phys)); pte += 8; } nvkm_done(pgt); } void nv50_vm_unmap(struct nvkm_vma *vma, struct nvkm_memory *pgt, u32 pte, u32 cnt) { pte <<= 3; nvkm_kmap(pgt); while (cnt--) { nvkm_wo32(pgt, pte + 0, 0x00000000); nvkm_wo32(pgt, pte + 4, 0x00000000); pte += 8; } nvkm_done(pgt); } void nv50_vm_flush(struct nvkm_vm *vm) { struct nvkm_mmu *mmu = vm->mmu; struct nvkm_subdev *subdev = &mmu->subdev; struct nvkm_device *device = subdev->device; int i, vme; mutex_lock(&subdev->mutex); for (i = 0; i < NVKM_SUBDEV_NR; i++) { if (!atomic_read(&vm->engref[i])) continue; /* unfortunate hw bug workaround... */ if (i == NVKM_ENGINE_GR && device->gr) { int ret = nvkm_gr_tlb_flush(device->gr); if (ret != -ENODEV) continue; } switch (i) { case NVKM_ENGINE_GR : vme = 0x00; break; case NVKM_ENGINE_VP : case NVKM_ENGINE_MSPDEC: vme = 0x01; break; case NVKM_SUBDEV_BAR : vme = 0x06; break; case NVKM_ENGINE_MSPPP : case NVKM_ENGINE_MPEG : vme = 0x08; break; case NVKM_ENGINE_BSP : case NVKM_ENGINE_MSVLD : vme = 0x09; break; case NVKM_ENGINE_CIPHER: case NVKM_ENGINE_SEC : vme = 0x0a; break; case NVKM_ENGINE_CE0 : vme = 0x0d; break; default: continue; } nvkm_wr32(device, 0x100c80, (vme << 16) | 1); if (nvkm_msec(device, 2000, if (!(nvkm_rd32(device, 0x100c80) & 0x00000001)) break; ) < 0) nvkm_error(subdev, "vm flush timeout: engine %d\n", vme); } mutex_unlock(&subdev->mutex); /* 0x01: no bank swizzle * 0x02: bank swizzled * 0x7f: invalid * * 0x01/0x02 are values understood by the VRAM allocator, * and are required to avoid mixing the two types within * a certain range. */ static const u8 kind[128] = { 0x01, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, /* 0x00 */ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x7f, 0x7f, 0x7f, 0x7f, /* 0x10 */ 0x02, 0x02, 0x02, 0x02, 0x7f, 0x7f, 0x7f, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, /* 0x20 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, /* 0x30 */ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, /* 0x40 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x01, 0x01, 0x01, 0x7f, /* 0x50 */ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, /* 0x60 */ 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x7f, 0x02, 0x7f, 0x01, 0x7f, 0x02, 0x7f, /* 0x70 */ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x7f, 0x7f }; *count = ARRAY_SIZE(kind); return kind; } static const struct nvkm_mmu_func Loading @@ -211,12 +66,8 @@ nv50_mmu = { .pgt_bits = 29 - 12, .spg_shift = 12, .lpg_shift = 16, .map_pgt = nv50_vm_map_pgt, .map = nv50_vm_map, .map_sg = nv50_vm_map_sg, .unmap = nv50_vm_unmap, .flush = nv50_vm_flush, .vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x1400 }, .kind = nv50_mmu_kind, }; int Loading
drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +3 −7 Original line number Diff line number Diff line Loading @@ -37,17 +37,13 @@ struct nvkm_mmu_func { bool global; u32 pd_offset; } vmm; const u8 *(*kind)(struct nvkm_mmu *, int *count); }; extern const struct nvkm_mmu_func nv04_mmu; void nv50_vm_map_pgt(struct nvkm_vmm *, u32, struct nvkm_memory **); void nv50_vm_map(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, u32, u32, u64, u64); void nv50_vm_map_sg(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, u32, u32, dma_addr_t *); void nv50_vm_unmap(struct nvkm_vma *, struct nvkm_memory *, u32, u32); void nv50_vm_flush(struct nvkm_vm *); const u8 *nv50_mmu_kind(struct nvkm_mmu *, int *count); void gf100_vm_map_pgt(struct nvkm_vmm *, u32, struct nvkm_memory **); void gf100_vm_map(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *, Loading