Commit b77791da authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/mmu/gf100: implement new vmm backend



Adds support for:
- 64KiB big page size.
- System-memory PTs.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent fd542a3e
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -5,4 +5,17 @@
struct gf100_vmm_vn {
	/* nvif_vmm_vX ... */
};

struct gf100_vmm_map_vn {
	/* nvif_vmm_map_vX ... */
};

struct gf100_vmm_map_v0 {
	/* nvif_vmm_map_vX ... */
	__u8  version;
	__u8  vol;
	__u8  ro;
	__u8  priv;
	__u8  kind;
};
#endif
+15 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <subdev/fb.h>

#include <nvif/if500d.h>
#include <nvif/if900d.h>

struct nvkm_mmu_ptp {
	struct nvkm_mmu_pt *pt;
@@ -222,6 +223,7 @@ nvkm_vm_map_(const struct nvkm_vmm_page *page, struct nvkm_vma *vma, u64 delta,
{
	union {
		struct nv50_vmm_map_v0 nv50;
		struct gf100_vmm_map_v0 gf100;
	} args;
	struct nvkm_vmm *vmm = vma->vm;
	void *argv = NULL;
@@ -242,6 +244,19 @@ nvkm_vm_map_(const struct nvkm_vmm_page *page, struct nvkm_vma *vma, u64 delta,
			argv = &args.nv50;
			argc = sizeof(args.nv50);
			break;
		case NV_C0:
		case NV_E0:
		case GM100:
		case GP100: {
			args.gf100.version = 0;
			args.gf100.vol = (nvkm_memory_target(map->memory) != NVKM_MEM_TARGET_VRAM);
			args.gf100.ro = !(vma->access & NV_MEM_ACCESS_WO);
			args.gf100.priv = !!(vma->access & NV_MEM_ACCESS_SYS);
			args.gf100.kind = (mem->memtype & 0x0ff);
			argv = &args.gf100;
			argc = sizeof(args.gf100);
		}
			break;
		default:
			break;
		}
+7 −5
Original line number Diff line number Diff line
@@ -68,6 +68,12 @@ const u8 gf100_pte_storage_type_map[256] =
	0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xfd, 0xfe, 0xff
};

const u8 *
gf100_mmu_kind(struct nvkm_mmu *mmu, int *count)
{
	*count = ARRAY_SIZE(gf100_pte_storage_type_map);
	return gf100_pte_storage_type_map;
}

void
gf100_vm_map_pgt(struct nvkm_vmm *vmm, u32 index, struct nvkm_memory *pgt[2])
@@ -195,12 +201,8 @@ gf100_mmu = {
	.pgt_bits  = 27 - 12,
	.spg_shift = 12,
	.lpg_shift = 17,
	.map_pgt = gf100_vm_map_pgt,
	.map = gf100_vm_map,
	.map_sg = gf100_vm_map_sg,
	.unmap = gf100_vm_unmap,
	.flush = gf100_vm_flush,
	.vmm = {{ -1, -1, NVIF_CLASS_VMM_GF100}, gf100_vmm_new },
	.kind = gf100_mmu_kind,
};

int
+1 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ void gf100_vm_map_sg(struct nvkm_vma *, struct nvkm_memory *, struct nvkm_mem *,
		     u32, u32, dma_addr_t *);
void gf100_vm_unmap(struct nvkm_vma *, struct nvkm_memory *, u32, u32);
void gf100_vm_flush(struct nvkm_vm *);
const u8 *gf100_mmu_kind(struct nvkm_mmu *, int *count);

struct nvkm_mmu_pt {
	union {
+12 −0
Original line number Diff line number Diff line
@@ -70,7 +70,15 @@ struct nvkm_vmm_desc_func {
};

extern const struct nvkm_vmm_desc_func gf100_vmm_pgd;
void gf100_vmm_pgd_pde(struct nvkm_vmm *, struct nvkm_vmm_pt *, u32);
extern const struct nvkm_vmm_desc_func gf100_vmm_pgt;
void gf100_vmm_pgt_unmap(struct nvkm_vmm *, struct nvkm_mmu_pt *, u32, u32);
void gf100_vmm_pgt_mem(struct nvkm_vmm *, struct nvkm_mmu_pt *, u32, u32,
		       struct nvkm_vmm_map *);
void gf100_vmm_pgt_dma(struct nvkm_vmm *, struct nvkm_mmu_pt *, u32, u32,
		       struct nvkm_vmm_map *);
void gf100_vmm_pgt_sgl(struct nvkm_vmm *, struct nvkm_mmu_pt *, u32, u32,
		       struct nvkm_vmm_map *);

struct nvkm_vmm_desc {
	enum {
@@ -165,6 +173,10 @@ int gf100_vmm_new_(const struct nvkm_vmm_func *, const struct nvkm_vmm_func *,
int gf100_vmm_join_(struct nvkm_vmm *, struct nvkm_memory *, u64 base);
int gf100_vmm_join(struct nvkm_vmm *, struct nvkm_memory *);
void gf100_vmm_part(struct nvkm_vmm *, struct nvkm_memory *);
int gf100_vmm_aper(enum nvkm_memory_target);
int gf100_vmm_valid(struct nvkm_vmm *, void *, u32, struct nvkm_vmm_map *);
void gf100_vmm_flush_(struct nvkm_vmm *, int);
void gf100_vmm_flush(struct nvkm_vmm *, int);

int gm200_vmm_new_(const struct nvkm_vmm_func *, const struct nvkm_vmm_func *,
		   struct nvkm_mmu *, u64, u64, void *, u32,
Loading