Commit 9f6219fd authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/mmu/nv50,g84: implement vmm on top of new base

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 03b0ba7b
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#define NVIF_CLASS_VMM /* if000c.h */ 0x8000000c #define NVIF_CLASS_VMM /* if000c.h */ 0x8000000c
#define NVIF_CLASS_VMM_NV04 /* if000d.h */ 0x8000000d #define NVIF_CLASS_VMM_NV04 /* if000d.h */ 0x8000000d
#define NVIF_CLASS_VMM_NV50 /* if500d.h */ 0x8000500d
/* the below match nvidia-assigned (either in hw, or sw) class numbers */ /* the below match nvidia-assigned (either in hw, or sw) class numbers */
#define NV_NULL_CLASS 0x00000030 #define NV_NULL_CLASS 0x00000030
......
#ifndef __NVIF_IF500D_H__
#define __NVIF_IF500D_H__
#include "if000c.h"
struct nv50_vmm_vn {
/* nvif_vmm_vX ... */
};
#endif
...@@ -36,7 +36,6 @@ struct nvkm_vm { ...@@ -36,7 +36,6 @@ struct nvkm_vm {
u64 limit; u64 limit;
struct nvkm_vmm_pt *pd; struct nvkm_vmm_pt *pd;
u16 pd_offset;
struct list_head join; struct list_head join;
struct nvkm_mm mm; struct nvkm_mm mm;
......
...@@ -16,3 +16,4 @@ nvkm-y += nvkm/subdev/mmu/vmm.o ...@@ -16,3 +16,4 @@ nvkm-y += nvkm/subdev/mmu/vmm.o
nvkm-y += nvkm/subdev/mmu/vmmnv04.o nvkm-y += nvkm/subdev/mmu/vmmnv04.o
nvkm-y += nvkm/subdev/mmu/vmmnv41.o nvkm-y += nvkm/subdev/mmu/vmmnv41.o
nvkm-y += nvkm/subdev/mmu/vmmnv44.o nvkm-y += nvkm/subdev/mmu/vmmnv44.o
nvkm-y += nvkm/subdev/mmu/vmmnv50.o
...@@ -727,7 +727,6 @@ nvkm_vm_del(struct kref *kref) ...@@ -727,7 +727,6 @@ nvkm_vm_del(struct kref *kref)
nvkm_mm_fini(&vm->mm); nvkm_mm_fini(&vm->mm);
vfree(vm->pgt); vfree(vm->pgt);
if (vm->func) if (vm->func)
nvkm_vmm_dtor(vm); nvkm_vmm_dtor(vm);
kfree(vm); kfree(vm);
......
...@@ -19,7 +19,9 @@ ...@@ -19,7 +19,9 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include "priv.h" #include "vmm.h"
#include <nvif/class.h>
static const struct nvkm_mmu_func static const struct nvkm_mmu_func
g84_mmu = { g84_mmu = {
...@@ -34,6 +36,7 @@ g84_mmu = { ...@@ -34,6 +36,7 @@ g84_mmu = {
.map_sg = nv50_vm_map_sg, .map_sg = nv50_vm_map_sg,
.unmap = nv50_vm_unmap, .unmap = nv50_vm_unmap,
.flush = nv50_vm_flush, .flush = nv50_vm_flush,
.vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x0200 },
}; };
int int
......
...@@ -21,13 +21,15 @@ ...@@ -21,13 +21,15 @@
* *
* Authors: Ben Skeggs * Authors: Ben Skeggs
*/ */
#include "priv.h" #include "vmm.h"
#include <core/gpuobj.h> #include <core/gpuobj.h>
#include <subdev/fb.h> #include <subdev/fb.h>
#include <subdev/timer.h> #include <subdev/timer.h>
#include <engine/gr.h> #include <engine/gr.h>
#include <nvif/class.h>
void void
nv50_vm_map_pgt(struct nvkm_gpuobj *pgd, u32 pde, struct nvkm_memory *pgt[2]) nv50_vm_map_pgt(struct nvkm_gpuobj *pgd, u32 pde, struct nvkm_memory *pgt[2])
{ {
...@@ -205,7 +207,6 @@ nv50_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset, ...@@ -205,7 +207,6 @@ nv50_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset,
u32 block = (1 << (mmu->func->pgt_bits + 12)); u32 block = (1 << (mmu->func->pgt_bits + 12));
if (block > length) if (block > length)
block = length; block = length;
return nvkm_vm_create(mmu, offset, length, mm_offset, block, key, pvm); return nvkm_vm_create(mmu, offset, length, mm_offset, block, key, pvm);
} }
...@@ -222,6 +223,7 @@ nv50_mmu = { ...@@ -222,6 +223,7 @@ nv50_mmu = {
.map_sg = nv50_vm_map_sg, .map_sg = nv50_vm_map_sg,
.unmap = nv50_vm_unmap, .unmap = nv50_vm_unmap,
.flush = nv50_vm_flush, .flush = nv50_vm_flush,
.vmm = {{ -1, -1, NVIF_CLASS_VMM_NV50}, nv50_vmm_new, false, 0x1400 },
}; };
int int
......
...@@ -38,6 +38,7 @@ struct nvkm_mmu_func { ...@@ -38,6 +38,7 @@ struct nvkm_mmu_func {
void *argv, u32 argc, struct lock_class_key *, void *argv, u32 argc, struct lock_class_key *,
const char *name, struct nvkm_vmm **); const char *name, struct nvkm_vmm **);
bool global; bool global;
u32 pd_offset;
} vmm; } vmm;
}; };
......
...@@ -94,6 +94,11 @@ struct nvkm_vmm_func { ...@@ -94,6 +94,11 @@ struct nvkm_vmm_func {
const struct nvkm_vmm_page page[]; const struct nvkm_vmm_page page[];
}; };
struct nvkm_vmm_join {
struct nvkm_memory *inst;
struct list_head head;
};
int nvkm_vmm_new_(const struct nvkm_vmm_func *, struct nvkm_mmu *, int nvkm_vmm_new_(const struct nvkm_vmm_func *, struct nvkm_mmu *,
u32 pd_header, u64 addr, u64 size, struct lock_class_key *, u32 pd_header, u64 addr, u64 size, struct lock_class_key *,
const char *name, struct nvkm_vmm **); const char *name, struct nvkm_vmm **);
...@@ -112,4 +117,8 @@ int nv41_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, ...@@ -112,4 +117,8 @@ int nv41_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32,
struct lock_class_key *, const char *, struct nvkm_vmm **); struct lock_class_key *, const char *, struct nvkm_vmm **);
int nv44_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32, int nv44_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32,
struct lock_class_key *, const char *, struct nvkm_vmm **); struct lock_class_key *, const char *, struct nvkm_vmm **);
int nv50_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32,
struct lock_class_key *, const char *, struct nvkm_vmm **);
int g84_vmm_new(struct nvkm_mmu *, u64, u64, void *, u32,
struct lock_class_key *, const char *, struct nvkm_vmm **);
#endif #endif
/*
* 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 "vmm.h"
#include <nvif/if500d.h>
#include <nvif/unpack.h>
static const struct nvkm_vmm_desc_func
nv50_vmm_pgt = {
};
static const struct nvkm_vmm_desc_func
nv50_vmm_pgd = {
};
static const struct nvkm_vmm_desc
nv50_vmm_desc_12[] = {
{ PGT, 17, 8, 0x1000, &nv50_vmm_pgt },
{ PGD, 11, 0, 0x0000, &nv50_vmm_pgd },
{}
};
static const struct nvkm_vmm_desc
nv50_vmm_desc_16[] = {
{ PGT, 13, 8, 0x1000, &nv50_vmm_pgt },
{ PGD, 11, 0, 0x0000, &nv50_vmm_pgd },
{}
};
static void
nv50_vmm_part(struct nvkm_vmm *vmm, struct nvkm_memory *inst)
{
struct nvkm_vmm_join *join;
list_for_each_entry(join, &vmm->join, head) {
if (join->inst == inst) {
list_del(&join->head);
kfree(join);
break;
}
}
}
static int
nv50_vmm_join(struct nvkm_vmm *vmm, struct nvkm_memory *inst)
{
struct nvkm_vmm_join *join;
if (!(join = kmalloc(sizeof(*join), GFP_KERNEL)))
return -ENOMEM;
join->inst = inst;
list_add_tail(&join->head, &vmm->join);
return 0;
}
static const struct nvkm_vmm_func
nv50_vmm = {
.join = nv50_vmm_join,
.part = nv50_vmm_part,
.page_block = 1 << 29,
.page = {
{ 16, &nv50_vmm_desc_16[0], NVKM_VMM_PAGE_xVxC },
{ 12, &nv50_vmm_desc_12[0], NVKM_VMM_PAGE_xVHx },
{}
}
};
int
nv50_vmm_new(struct nvkm_mmu *mmu, u64 addr, u64 size, void *argv, u32 argc,
struct lock_class_key *key, const char *name,
struct nvkm_vmm **pvmm)
{
return nv04_vmm_new_(&nv50_vmm, mmu, 0, addr, size,
argv, argc, key, name, pvmm);
}
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