Browse Source

drm/nouveau: allocate vmm object for every client

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Ben Skeggs 7 years ago
parent
commit
96da0bcd51

+ 26 - 24
drivers/gpu/drm/nouveau/nouveau_drm.c

@@ -134,6 +134,15 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname,
 		{ NVIF_CLASS_MMU_NV04 , -1 },
 		{ NVIF_CLASS_MMU_NV04 , -1 },
 		{}
 		{}
 	};
 	};
+	static const struct nvif_mclass
+	vmms[] = {
+		{ NVIF_CLASS_VMM_GP100, -1 },
+		{ NVIF_CLASS_VMM_GM200, -1 },
+		{ NVIF_CLASS_VMM_GF100, -1 },
+		{ NVIF_CLASS_VMM_NV50 , -1 },
+		{ NVIF_CLASS_VMM_NV04 , -1 },
+		{}
+	};
 	u64 device = nouveau_name(drm->dev);
 	u64 device = nouveau_name(drm->dev);
 	int ret;
 	int ret;
 
 
@@ -180,6 +189,23 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname,
 		goto done;
 		goto done;
 	}
 	}
 
 
+	ret = nvif_mclass(&cli->mmu.object, vmms);
+	if (ret < 0) {
+		NV_ERROR(drm, "No supported VMM class\n");
+		goto done;
+	}
+
+	ret = nouveau_vmm_init(cli, vmms[ret].oclass, &cli->vmm);
+	if (ret) {
+		NV_ERROR(drm, "VMM allocation failed: %d\n", ret);
+		goto done;
+	}
+
+	if (1) {
+		cli->vm = cli->vmm.vm;
+		nvxx_client(&cli->base)->vm = cli->vm;
+	}
+
 done:
 done:
 	if (ret)
 	if (ret)
 		nouveau_cli_fini(cli);
 		nouveau_cli_fini(cli);
@@ -486,20 +512,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
 
 
 	nouveau_vga_init(drm);
 	nouveau_vga_init(drm);
 
 
-	if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
-		if (!nvxx_device(&drm->client.device)->mmu) {
-			ret = -ENOSYS;
-			goto fail_device;
-		}
-
-		ret = nouveau_vmm_init(&drm->client, 0, &drm->client.vmm);
-		if (ret)
-			goto fail_device;
-
-		drm->client.vm = drm->client.vmm.vm;
-		nvxx_client(&drm->client.base)->vm = drm->client.vm;
-	}
-
 	ret = nouveau_ttm_init(drm);
 	ret = nouveau_ttm_init(drm);
 	if (ret)
 	if (ret)
 		goto fail_ttm;
 		goto fail_ttm;
@@ -545,7 +557,6 @@ fail_bios:
 	nouveau_ttm_fini(drm);
 	nouveau_ttm_fini(drm);
 fail_ttm:
 fail_ttm:
 	nouveau_vga_fini(drm);
 	nouveau_vga_fini(drm);
-fail_device:
 	nouveau_cli_fini(&drm->client);
 	nouveau_cli_fini(&drm->client);
 	nouveau_cli_fini(&drm->master);
 	nouveau_cli_fini(&drm->master);
 	kfree(drm);
 	kfree(drm);
@@ -881,15 +892,6 @@ nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv)
 
 
 	cli->base.super = false;
 	cli->base.super = false;
 
 
-	if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
-		ret = nouveau_vmm_init(cli, 0, &cli->vmm);
-		if (ret)
-			goto done;
-
-		cli->vm = cli->vmm.vm;
-		nvxx_client(&cli->base)->vm = cli->vm;
-	}
-
 	fpriv->driver_priv = cli;
 	fpriv->driver_priv = cli;
 
 
 	mutex_lock(&drm->client.mutex);
 	mutex_lock(&drm->client.mutex);

+ 1 - 0
drivers/gpu/drm/nouveau/nouveau_drv.h

@@ -43,6 +43,7 @@
 #include <nvif/device.h>
 #include <nvif/device.h>
 #include <nvif/ioctl.h>
 #include <nvif/ioctl.h>
 #include <nvif/mmu.h>
 #include <nvif/mmu.h>
+#include <nvif/vmm.h>
 
 
 #include <drm/drmP.h>
 #include <drm/drmP.h>
 
 

+ 5 - 3
drivers/gpu/drm/nouveau/nouveau_gem.c

@@ -33,6 +33,8 @@
 #include "nouveau_gem.h"
 #include "nouveau_gem.h"
 #include "nouveau_vmm.h"
 #include "nouveau_vmm.h"
 
 
+#include <nvif/class.h>
+
 void
 void
 nouveau_gem_object_del(struct drm_gem_object *gem)
 nouveau_gem_object_del(struct drm_gem_object *gem)
 {
 {
@@ -69,7 +71,7 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
 	struct nouveau_vma *vma;
 	struct nouveau_vma *vma;
 	int ret;
 	int ret;
 
 
-	if (!cli->vm)
+	if (cli->vmm.vmm.object.oclass < NVIF_CLASS_VMM_NV50)
 		return 0;
 		return 0;
 
 
 	ret = ttm_bo_reserve(&nvbo->bo, false, false, NULL);
 	ret = ttm_bo_reserve(&nvbo->bo, false, false, NULL);
@@ -131,7 +133,7 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
 	struct nouveau_vma *vma;
 	struct nouveau_vma *vma;
 	int ret;
 	int ret;
 
 
-	if (!cli->vm)
+	if (cli->vmm.vmm.object.oclass < NVIF_CLASS_VMM_NV50)
 		return;
 		return;
 
 
 	ret = ttm_bo_reserve(&nvbo->bo, false, false, NULL);
 	ret = ttm_bo_reserve(&nvbo->bo, false, false, NULL);
@@ -214,7 +216,7 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem,
 	else
 	else
 		rep->domain = NOUVEAU_GEM_DOMAIN_VRAM;
 		rep->domain = NOUVEAU_GEM_DOMAIN_VRAM;
 	rep->offset = nvbo->bo.offset;
 	rep->offset = nvbo->bo.offset;
-	if (cli->vm) {
+	if (cli->vmm.vmm.object.oclass >= NVIF_CLASS_VMM_NV50) {
 		vma = nouveau_vma_find(nvbo, &cli->vmm);
 		vma = nouveau_vma_find(nvbo, &cli->vmm);
 		if (!vma)
 		if (!vma)
 			return -EINVAL;
 			return -EINVAL;

+ 0 - 5
drivers/gpu/drm/nouveau/nouveau_mem.h

@@ -29,11 +29,6 @@ struct nouveau_mem {
 	struct nvkm_memory memory;
 	struct nvkm_memory memory;
 };
 };
 
 
-enum nvif_vmm_get {
-	PTES,
-	LAZY,
-};
-
 int nouveau_mem_new(struct nouveau_cli *, u8 kind, u8 comp,
 int nouveau_mem_new(struct nouveau_cli *, u8 kind, u8 comp,
 		    struct ttm_mem_reg *);
 		    struct ttm_mem_reg *);
 void nouveau_mem_del(struct ttm_mem_reg *);
 void nouveau_mem_del(struct ttm_mem_reg *);

+ 9 - 3
drivers/gpu/drm/nouveau/nouveau_vmm.c

@@ -114,13 +114,19 @@ done:
 void
 void
 nouveau_vmm_fini(struct nouveau_vmm *vmm)
 nouveau_vmm_fini(struct nouveau_vmm *vmm)
 {
 {
-	nvkm_vm_ref(NULL, &vmm->vm, NULL);
+	nvif_vmm_fini(&vmm->vmm);
+	vmm->cli = NULL;
 }
 }
 
 
 int
 int
 nouveau_vmm_init(struct nouveau_cli *cli, s32 oclass, struct nouveau_vmm *vmm)
 nouveau_vmm_init(struct nouveau_cli *cli, s32 oclass, struct nouveau_vmm *vmm)
 {
 {
+	int ret = nvif_vmm_init(&cli->mmu, oclass, PAGE_SIZE, 0, NULL, 0,
+				&vmm->vmm);
+	if (ret)
+		return ret;
+
 	vmm->cli = cli;
 	vmm->cli = cli;
-	return nvkm_vm_new(nvxx_device(&cli->device), 0, (1ULL << 40),
-			   0x1000, NULL, &vmm->vm);
+	vmm->vm = nvkm_uvmm(vmm->vmm.object.priv)->vmm;
+	return 0;
 }
 }

+ 3 - 1
drivers/gpu/drm/nouveau/nouveau_vmm.h

@@ -1,6 +1,7 @@
 #ifndef __NOUVEAU_VMA_H__
 #ifndef __NOUVEAU_VMA_H__
 #define __NOUVEAU_VMA_H__
 #define __NOUVEAU_VMA_H__
-#include <subdev/mmu.h>
+#include <subdev/mmu/uvmm.h>
+#include <nvif/vmm.h>
 struct nouveau_bo;
 struct nouveau_bo;
 struct nouveau_mem;
 struct nouveau_mem;
 
 
@@ -24,6 +25,7 @@ void nouveau_vma_unmap(struct nouveau_vma *);
 
 
 struct nouveau_vmm {
 struct nouveau_vmm {
 	struct nouveau_cli *cli;
 	struct nouveau_cli *cli;
+	struct nvif_vmm vmm;
 	struct nvkm_vm *vm;
 	struct nvkm_vm *vm;
 };
 };