diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2017-07-31 13:55:35 +1000 |
---|---|---|
committer | Jérôme Glisse <jglisse@redhat.com> | 2017-08-09 18:13:31 -0400 |
commit | 5878d7c68b7409f14fffb6460d1df60161725430 (patch) | |
tree | c5b97cd2990694702bb1273511dbce93fc3d8c2a /drivers | |
parent | 729f884cb7ca962300740ede2690833181fdbbe6 (diff) |
mmu/nv04: implement vmm on top of new base
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_ttm.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c | 26 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv04.c | 82 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv04.h | 16 |
6 files changed, 116 insertions, 17 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 999c35a25498..eb526d3ff86b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -191,16 +191,13 @@ const struct ttm_mem_type_manager_func nouveau_gart_manager = { .debug = nouveau_gart_manager_debug }; -/*XXX*/ -#include <subdev/mmu/nv04.h> static int nv04_gart_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) { struct nouveau_drm *drm = nouveau_bdev(man->bdev); struct nvkm_mmu *mmu = nvxx_mmu(&drm->client.device); - struct nv04_mmu *priv = (void *)mmu; struct nvkm_vm *vm = NULL; - nvkm_vm_ref(priv->vm, &vm, NULL); + nvkm_vm_ref(mmu->vmm, &vm, NULL); man->priv = vm; return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c index c95942ef8216..acc45ce5f93e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c @@ -49,8 +49,7 @@ nv04_dmaobj_bind(struct nvkm_dmaobj *base, struct nvkm_gpuobj *parent, int ret; if (dmaobj->clone) { - struct nv04_mmu *mmu = nv04_mmu(device->mmu); - struct nvkm_memory *pgt = mmu->vm->pgt[0].mem[0]; + struct nvkm_memory *pgt = device->mmu->vmm->pgt[0].mem[0]; if (!dmaobj->base.start) return nvkm_gpuobj_wrap(pgt, pgpuobj); nvkm_kmap(pgt); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index a2e27244dbed..603682dac9a2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -8,3 +8,4 @@ nvkm-y += nvkm/subdev/mmu/gf100.o nvkm-y += nvkm/subdev/mmu/gp100.o nvkm-y += nvkm/subdev/mmu/vmm.o +nvkm-y += nvkm/subdev/mmu/vmmnv04.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c index 37927c3fdc3e..30c61d91de0b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "nv04.h" +#include "vmmnv04.h" #include <core/gpuobj.h> @@ -80,16 +81,11 @@ nv04_mmu_oneinit(struct nvkm_mmu *base) struct nvkm_memory *dma; int ret; - ret = nvkm_vm_create(&mmu->base, 0, NV04_PDMA_SIZE, 0, 4096, NULL, - &mmu->vm); - if (ret) - return ret; - ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, (NV04_PDMA_SIZE / NV04_PDMA_PAGE) * 4 + 8, 16, true, &dma); - mmu->vm->pgt[0].mem[0] = dma; - mmu->vm->pgt[0].refcount[0] = 1; + mmu->base.vmm->pgt[0].mem[0] = dma; + mmu->base.vmm->pgt[0].refcount[0] = 1; if (ret) return ret; @@ -105,10 +101,8 @@ nv04_mmu_dtor(struct nvkm_mmu *base) { struct nv04_mmu *mmu = nv04_mmu(base); struct nvkm_device *device = mmu->base.subdev.device; - if (mmu->vm) { - nvkm_memory_del(&mmu->vm->pgt[0].mem[0]); - nvkm_vm_ref(NULL, &mmu->vm, NULL); - } + if (mmu->base.vmm) + nvkm_memory_del(&mmu->base.vmm->pgt[0].mem[0]); if (mmu->nullp) { dma_free_coherent(device->dev, 16 * 1024, mmu->nullp, mmu->null); @@ -128,6 +122,14 @@ nv04_mmu_new_(const struct nvkm_mmu_func *func, struct nvkm_device *device, return 0; } +static int +nv04_mmu_uvmm(struct nvkm_mmu *base, int i, const struct nvkm_vmm_user **puvmm) +{ + if (i == 0) + *puvmm = &nv04_vmm_user; + return 1; +} + const struct nvkm_mmu_func nv04_mmu = { .oneinit = nv04_mmu_oneinit, @@ -140,6 +142,8 @@ nv04_mmu = { .map_sg = nv04_vm_map_sg, .unmap = nv04_vm_unmap, .flush = nv04_vm_flush, + .uvmm = nv04_mmu_uvmm, + .vmm_global = true, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv04.c new file mode 100644 index 000000000000..b6bdfed6a62a --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv04.c @@ -0,0 +1,82 @@ +/* + * Copyright 2017 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "vmmnv04.h" +#include "nv04.h" + +void * +nv04_vmm_dtor(struct nvkm_vmm *base) +{ + struct nv04_vmm *vmm = nv04_vmm(base); + return vmm; +} + +int +nv04_vmm_new_(const struct nvkm_vmm_func *func, struct nvkm_mmu *mmu, + int vma_bits, u64 addr, u64 size, struct lock_class_key *key, + struct nv04_vmm **pvmm) +{ + struct nv04_vmm *vmm; + + if (!(vmm = *pvmm = kzalloc(sizeof(*vmm), GFP_KERNEL))) + return -ENOMEM; + + return nvkm_vmm_ctor(func, mmu, vma_bits, addr, size, key, &vmm->base); +} + +const struct nvkm_vmm_page * +nv04_vmm_page(struct nvkm_vmm *base) +{ + static const struct nvkm_vmm_page page[] = { + { 12 }, + {} + }; + return page; +} + +static const struct nvkm_vmm_func +nv04_vmm = { + .dtor = nv04_vmm_dtor, + .page = nv04_vmm_page, +}; + +static int +nv04_vmm_new(struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, struct nvkm_vmm **pvmm) +{ + struct nv04_vmm *vmm; + int ret; + + if (argc != 0) + return -ENOSYS; + + ret = nv04_vmm_new_(&nv04_vmm, mmu, 27, addr, size, key, &vmm); + *pvmm = vmm ? &vmm->base : NULL; + if (ret) + return ret; + + return 0; +} + +const struct nvkm_vmm_user +nv04_vmm_user = { + .ctor = nv04_vmm_new, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv04.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv04.h new file mode 100644 index 000000000000..52eed3669dd1 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv04.h @@ -0,0 +1,16 @@ +#ifndef __NV04_VMM_H__ +#define __NV04_VMM_H__ +#define nv04_vmm(p) container_of((p), struct nv04_vmm, base) +#include "vmm.h" + +struct nv04_vmm { + struct nvkm_vmm base; +}; + +int nv04_vmm_new_(const struct nvkm_vmm_func *, struct nvkm_mmu *, int, + u64, u64, struct lock_class_key *, struct nv04_vmm **); +void *nv04_vmm_dtor(struct nvkm_vmm *); +const struct nvkm_vmm_page *nv04_vmm_page(struct nvkm_vmm *); + +extern const struct nvkm_vmm_user nv04_vmm_user; +#endif |