Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

drm/nouveau: allocate vmm object for every client



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent acb16cfa
Loading
Loading
Loading
Loading
+26 −24
Original line number Diff line number Diff line
@@ -134,6 +134,15 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname,
		{ 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);
	int ret;

@@ -180,6 +189,23 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname,
		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:
	if (ret)
		nouveau_cli_fini(cli);
@@ -486,20 +512,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)

	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);
	if (ret)
		goto fail_ttm;
@@ -545,7 +557,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
	nouveau_ttm_fini(drm);
fail_ttm:
	nouveau_vga_fini(drm);
fail_device:
	nouveau_cli_fini(&drm->client);
	nouveau_cli_fini(&drm->master);
	kfree(drm);
@@ -881,15 +892,6 @@ nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv)

	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;

	mutex_lock(&drm->client.mutex);
+1 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#include <nvif/device.h>
#include <nvif/ioctl.h>
#include <nvif/mmu.h>
#include <nvif/vmm.h>

#include <drm/drmP.h>

+5 −3
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@
#include "nouveau_gem.h"
#include "nouveau_vmm.h"

#include <nvif/class.h>

void
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;
	int ret;

	if (!cli->vm)
	if (cli->vmm.vmm.object.oclass < NVIF_CLASS_VMM_NV50)
		return 0;

	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;
	int ret;

	if (!cli->vm)
	if (cli->vmm.vmm.object.oclass < NVIF_CLASS_VMM_NV50)
		return;

	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
		rep->domain = NOUVEAU_GEM_DOMAIN_VRAM;
	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);
		if (!vma)
			return -EINVAL;
+0 −5
Original line number Diff line number Diff line
@@ -29,11 +29,6 @@ struct nouveau_mem {
	struct nvkm_memory memory;
};

enum nvif_vmm_get {
	PTES,
	LAZY,
};

int nouveau_mem_new(struct nouveau_cli *, u8 kind, u8 comp,
		    struct ttm_mem_reg *);
void nouveau_mem_del(struct ttm_mem_reg *);
+9 −3
Original line number Diff line number Diff line
@@ -114,13 +114,19 @@ nouveau_vma_new(struct nouveau_bo *nvbo, struct nouveau_vmm *vmm,
void
nouveau_vmm_fini(struct nouveau_vmm *vmm)
{
	nvkm_vm_ref(NULL, &vmm->vm, NULL);
	nvif_vmm_fini(&vmm->vmm);
	vmm->cli = NULL;
}

int
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;
	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;
}
Loading