summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJérôme Glisse <jglisse@redhat.com>2017-08-08 22:50:58 -0400
committerJérôme Glisse <jglisse@redhat.com>2017-08-23 16:41:40 -0400
commit91a96fcb30e78e0e400943c4ed6ad98733edb927 (patch)
tree2c21e23f07e2c2a42dc76b6621f3b9b29b5b85c5
parent5d4b6402c3d8ac28abf9260ca0678009b9833381 (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>
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c26
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c2
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;