diff options
author | Jérôme Glisse <jglisse@redhat.com> | 2017-08-08 22:50:58 -0400 |
---|---|---|
committer | Jérôme Glisse <jglisse@redhat.com> | 2017-08-23 16:41:40 -0400 |
commit | 91a96fcb30e78e0e400943c4ed6ad98733edb927 (patch) | |
tree | 2c21e23f07e2c2a42dc76b6621f3b9b29b5b85c5 /drivers/gpu/drm | |
parent | 5d4b6402c3d8ac28abf9260ca0678009b9833381 (diff) |
drm/nouveau/core/mm: allow partial mapping of bo (buffer object)
This allow to create partial mapping of a bo (nvkm_vma).
Signed-off-by: Jérôme Glisse <jglisse@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
5 files changed, 24 insertions, 11 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 73e7893ea20b..069c20940740 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -16,6 +16,7 @@ struct nvkm_vma { struct nvkm_vm *vm; struct nvkm_mm_node *node; u64 offset; + u64 skip; u32 access; }; @@ -50,7 +51,7 @@ int nvkm_vm_get_fix(struct nvkm_vm *vm, u64 offset, u64 size, u32 page_shift, u32 access, struct nvkm_vma *vma); void nvkm_vm_put(struct nvkm_vma *); void nvkm_vm_map(struct nvkm_vma *, struct nvkm_mem *); -void nvkm_vm_map_at(struct nvkm_vma *, u64 offset, struct nvkm_mem *); +void nvkm_vm_map_at(struct nvkm_vma *, u64 offset, u64 length, struct nvkm_mem *); void nvkm_vm_unmap(struct nvkm_vma *); void nvkm_vm_unmap_at(struct nvkm_vma *, u64 offset, u64 length); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c index cd5adbec5e57..863f2022fa68 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c @@ -277,7 +277,7 @@ gk20a_instobj_map(struct nvkm_memory *memory, struct nvkm_vma *vma, u64 offset) { struct gk20a_instobj *node = gk20a_instobj(memory); - nvkm_vm_map_at(vma, offset, &node->mem); + nvkm_vm_map_at(vma, offset, node->mem.size << 12, &node->mem); } static void * diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index 6d512c062ae3..673d567b2b13 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -159,7 +159,7 @@ static void nv50_instobj_map(struct nvkm_memory *memory, struct nvkm_vma *vma, u64 offset) { struct nv50_instobj *iobj = nv50_instobj(memory); - nvkm_vm_map_at(vma, offset, iobj->mem); + nvkm_vm_map_at(vma, offset, iobj->mem->size << 12, iobj->mem); } static void * diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index 4ee75b9bcd94..b1afd964d5cc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -28,7 +28,7 @@ #include <subdev/fb.h> void -nvkm_vm_map_at(struct nvkm_vma *vma, u64 delta, struct nvkm_mem *node) +nvkm_vm_map_at(struct nvkm_vma *vma, u64 delta, u64 length, struct nvkm_mem *node) { struct nvkm_vm *vm = vma->vm; struct nvkm_mmu *mmu = vm->mmu; @@ -40,11 +40,22 @@ nvkm_vm_map_at(struct nvkm_vma *vma, u64 delta, struct nvkm_mem *node) u32 pte = (offset & ((1 << mmu->func->pgt_bits) - 1)) >> bits; u32 max = 1 << (mmu->func->pgt_bits - bits); u32 end, len; + u64 skip = vma->skip >> 12; delta = 0; + + while (r && skip) { + if (skip < r->length) + break; + skip -= r->length; + r = r->next; + } + while (r) { - u64 phys = (u64)r->offset << 12; - u32 num = r->length >> bits; + u64 phys = ((u64)r->offset + skip) << 12; + u32 num = min(r->length, length) >> bits; + length -= (num << bits); + skip = 0; while (num) { struct nvkm_memory *pgt = vm->pgt[pde].mem[big]; @@ -66,6 +77,7 @@ nvkm_vm_map_at(struct nvkm_vma *vma, u64 delta, struct nvkm_mem *node) delta += (u64)len << vma->node->type; } + r = r->next; }; @@ -136,7 +148,7 @@ nvkm_vm_map_sg(struct nvkm_vma *vma, u64 delta, u64 length, { struct nvkm_vm *vm = vma->vm; struct nvkm_mmu *mmu = vm->mmu; - dma_addr_t *list = mem->pages; + dma_addr_t *list = &mem->pages[vma->skip >> vma->node->type]; int big = vma->node->type != mmu->func->spg_shift; u32 offset = vma->node->offset + (delta >> 12); u32 bits = vma->node->type - 12; @@ -172,12 +184,12 @@ void nvkm_vm_map(struct nvkm_vma *vma, struct nvkm_mem *node) { if (node->sg) - nvkm_vm_map_sg_table(vma, 0, node->size << 12, node); + nvkm_vm_map_sg_table(vma, 0, vma->node->length << 12, node); else if (node->pages) - nvkm_vm_map_sg(vma, 0, node->size << 12, node); + nvkm_vm_map_sg(vma, 0, vma->node->length << 12, node); else - nvkm_vm_map_at(vma, 0, node); + nvkm_vm_map_at(vma, 0, vma->node->length << 12, node); } void diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c index c205f2cdc915..6f7977bb9e78 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c @@ -39,7 +39,7 @@ gm200_secboot_run_blob(struct nvkm_secboot *sb, struct nvkm_gpuobj *blob, { struct gm200_secboot *gsb = gm200_secboot(sb); struct nvkm_subdev *subdev = &gsb->base.subdev; - struct nvkm_vma vma; + struct nvkm_vma vma = {0}; u32 start_address; int ret; |