From 2d3c1b9759034a06052a0b187dd49e333ca253d4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 31 Jul 2017 14:22:18 +1000 Subject: mmu/gf100-: implement vmm on top of new base Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c | 47 ++--------- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c | 14 +++- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.h | 1 + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c | 10 +++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h | 6 -- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c | 96 ++++++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.h | 20 +++++ drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c | 38 +++++++++ 9 files changed, 185 insertions(+), 49 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 74ad6f1894a7..9a2b3ec7217f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -13,3 +13,5 @@ nvkm-y += nvkm/subdev/mmu/vmmnv41.o nvkm-y += nvkm/subdev/mmu/vmmnv44.o nvkm-y += nvkm/subdev/mmu/vmmnv50.o nvkm-y += nvkm/subdev/mmu/vmmg84.o +nvkm-y += nvkm/subdev/mmu/vmmgf100.o +nvkm-y += nvkm/subdev/mmu/vmmgp100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index b6ea293cbe8e..4b5634b16b9a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -362,53 +362,22 @@ nvkm_vm_boot(struct nvkm_vm *vm, u64 size) return ret; } -int -nvkm_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, - u32 block, struct lock_class_key *key, struct nvkm_vm **pvm) -{ - struct nvkm_vmm_func func = { .page_block = block }; - struct nvkm_vm *vm; - int ret; - - vm = kzalloc(sizeof(*vm), GFP_KERNEL); - if (!vm) - return -ENOMEM; - - ret = nvkm_vmm_ctor(&func, mmu, order_base_2(mmu->limit), - mm_offset, offset + length - mm_offset, key, vm); - vm->func = NULL; - if (ret) { - kfree(vm); - return ret; - } - - *pvm = vm; - - return 0; -} - int nvkm_vm_new(struct nvkm_device *device, u64 offset, u64 length, u64 mm_offset, struct lock_class_key *key, struct nvkm_vm **pvm) { + const struct nvkm_vmm_user *uvmm = NULL; struct nvkm_mmu *mmu = device->mmu; + int ret; + mmu->func->uvmm(mmu, 0, &uvmm); *pvm = NULL; - if (mmu->func->uvmm) { - const struct nvkm_vmm_user *uvmm; - int ret; - mmu->func->uvmm(mmu, 0, &uvmm); - ret = uvmm->ctor(mmu, mm_offset, offset + length - mm_offset, - NULL, 0, key, pvm); - if (ret) - nvkm_vm_ref(NULL, pvm, NULL); - return ret; - } - - if (!mmu->func->create) - return -EINVAL; - return mmu->func->create(mmu, offset, length, mm_offset, key, pvm); + ret = uvmm->ctor(mmu, mm_offset, offset + length - mm_offset, + NULL, 0, key, pvm); + if (ret) + nvkm_vm_ref(NULL, pvm, NULL); + return ret; } static int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c index 85172945eb79..da44472ae1d7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "gf100.h" +#include "vmmgf100.h" #include #include @@ -193,10 +194,15 @@ gf100_vm_flush(struct nvkm_vm *vm) } static int -gf100_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, - struct lock_class_key *key, struct nvkm_vm **pvm) +gf100_mmu_uvmm(struct nvkm_mmu *base, int i, const struct nvkm_vmm_user **puvmm) { - return nvkm_vm_create(mmu, offset, length, mm_offset, 4096, key, pvm); + struct gf100_mmu *mmu = gf100_mmu(base); + if (!mmu->func->uvmm) { + if (i == 0) + *puvmm = &gf100_vmm_user; + return 1; + } + return mmu->func->uvmm(mmu, i, puvmm); } static void * @@ -213,12 +219,12 @@ gf100_mmu_ = { .pgt_bits = 27 - 12, .spg_shift = 12, .lpg_shift = 17, - .create = gf100_vm_create, .map_pgt = gf100_vm_map_pgt, .map = gf100_vm_map, .map_sg = gf100_vm_map_sg, .unmap = gf100_vm_unmap, .flush = gf100_vm_flush, + .uvmm = gf100_mmu_uvmm, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.h index 9db14f566112..0840bb6b6c63 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.h @@ -9,6 +9,7 @@ struct gf100_mmu { }; struct gf100_mmu_func { + int (*uvmm)(struct gf100_mmu *, int, const struct nvkm_vmm_user **); }; int gf100_mmu_new_(const struct gf100_mmu_func *, struct nvkm_device *, int, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c index 38c4ab149c7c..e46369c01ed7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp100.c @@ -20,9 +20,19 @@ * OTHER DEALINGS IN THE SOFTWARE. */ #include "gf100.h" +#include "vmmgf100.h" + +static int +gp100_mmu_uvmm(struct gf100_mmu *mmu, int i, const struct nvkm_vmm_user **puvmm) +{ + if (i == 0) + *puvmm = &gp100_vmm_user; + return 1; +} static const struct gf100_mmu_func gp100_mmu = { + .uvmm = gp100_mmu_uvmm, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index f36b74903427..404a8849e181 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -20,9 +20,6 @@ struct nvkm_mmu_func { u8 spg_shift; u8 lpg_shift; - int (*create)(struct nvkm_mmu *, u64 offset, u64 length, u64 mm_offset, - struct lock_class_key *, struct nvkm_vm **); - void (*map_pgt)(struct nvkm_gpuobj *pgd, u32 pde, struct nvkm_memory *pgt[2]); void (*map)(struct nvkm_vma *, struct nvkm_memory *, @@ -38,7 +35,4 @@ struct nvkm_mmu_func { bool vmm_global; }; - -int nvkm_vm_create(struct nvkm_mmu *, u64, u64, u64, u32, - struct lock_class_key *, struct nvkm_vm **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c new file mode 100644 index 000000000000..bb9e28e6d9f2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.c @@ -0,0 +1,96 @@ +/* + * 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 "vmmgf100.h" + +#include +#include + +static const struct nvkm_vmm_page * +gf100_vmm_page(struct nvkm_vmm *base) +{ + struct gf100_vmm *vmm = gf100_vmm(base); + static const struct nvkm_vmm_page + page_17[] = { + { 17, NVKM_VMM_PAGE_COMP }, + { 12 }, + {} + }; + + switch (vmm->base.mmu->subdev.device->fb->page) { + case 17: return page_17; + default: + WARN_ON(1); + return NULL; + } +} + +static void * +gf100_vmm_dtor(struct nvkm_vmm *base) +{ + struct gf100_vmm *vmm = gf100_vmm(base); + return vmm; +} + +static const struct nvkm_vmm_func +gf100_vmm_ = { + .dtor = gf100_vmm_dtor, + .page = gf100_vmm_page, +}; + +int +gf100_vmm_new_(const struct gf100_vmm_func *func, struct nvkm_mmu *mmu, + u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, struct nvkm_vmm **pvmm) +{ + struct gf100_vmm *vmm; + int ret; + + if (argc != 0) + return -ENOSYS; + + if (!(vmm = kzalloc(sizeof(*vmm), GFP_KERNEL))) + return -ENOMEM; + vmm->func = func; + *pvmm = &vmm->base; + + ret = nvkm_vmm_ctor(&gf100_vmm_, mmu, 40, addr, size, key, &vmm->base); + if (ret) + return ret; + + return 0; +} + +static const struct gf100_vmm_func +gf100_vmm = { +}; + +static int +gf100_vmm_new(struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, struct nvkm_vmm **pvmm) +{ + return gf100_vmm_new_(&gf100_vmm, mmu, addr, size, argv, argc, key, pvmm); +} + +const struct nvkm_vmm_user +gf100_vmm_user = { + .ctor = gf100_vmm_new, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.h new file mode 100644 index 000000000000..df80c8a2a5b3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgf100.h @@ -0,0 +1,20 @@ +#ifndef __GF100_VMM_H__ +#define __GF100_VMM_H__ +#define gf100_vmm(p) container_of((p), struct gf100_vmm, base) +#include "vmm.h" + +struct gf100_vmm { + const struct gf100_vmm_func *func; + struct nvkm_vmm base; +}; + +struct gf100_vmm_func { +}; + +int gf100_vmm_new_(const struct gf100_vmm_func *, struct nvkm_mmu *, + u64, u64, void *, u32, struct lock_class_key *, + struct nvkm_vmm **); + +extern const struct nvkm_vmm_user gf100_vmm_user; +extern const struct nvkm_vmm_user gp100_vmm_user; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c new file mode 100644 index 000000000000..49e82f211b08 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c @@ -0,0 +1,38 @@ +/* + * 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 "vmmgf100.h" + +static const struct gf100_vmm_func +gp100_vmm = { +}; + +static int +gp100_vmm_new(struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc, + struct lock_class_key *key, struct nvkm_vmm **pvmm) +{ + return gf100_vmm_new_(&gp100_vmm, mmu, addr, size, argv, argc, key, pvmm); +} + +const struct nvkm_vmm_user +gp100_vmm_user = { + .ctor = gp100_vmm_new, +}; -- cgit v1.2.3