Commit 96da0bcd authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau: allocate vmm object for every client

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent acb16cfa
...@@ -134,6 +134,15 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname, ...@@ -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, ...@@ -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) ...@@ -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 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) ...@@ -545,7 +557,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
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) ...@@ -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);
......
...@@ -43,6 +43,7 @@ ...@@ -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>
......
...@@ -33,6 +33,8 @@ ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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;
......
...@@ -29,11 +29,6 @@ struct nouveau_mem { ...@@ -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 *);
......
...@@ -114,13 +114,19 @@ nouveau_vma_new(struct nouveau_bo *nvbo, struct nouveau_vmm *vmm, ...@@ -114,13 +114,19 @@ nouveau_vma_new(struct nouveau_bo *nvbo, struct nouveau_vmm *vmm,
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), vmm->vm = nvkm_uvmm(vmm->vmm.object.priv)->vmm;
0x1000, NULL, &vmm->vm); return 0;
} }
#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 *); ...@@ -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;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment