1b7019ac5SIlia Mirkin /* SPDX-License-Identifier: MIT */
242594600SBen Skeggs #ifndef __NVKM_MMU_H__
342594600SBen Skeggs #define __NVKM_MMU_H__
45ce3bf3cSBen Skeggs #include <core/subdev.h>
55ce3bf3cSBen Skeggs 
642594600SBen Skeggs struct nvkm_vma {
75ce3bf3cSBen Skeggs 	struct list_head head;
8f9463a4bSBen Skeggs 	struct rb_node tree;
99ce523ccSBen Skeggs 	u64 addr;
10f9463a4bSBen Skeggs 	u64 size:50;
11f9463a4bSBen Skeggs 	bool mapref:1; /* PTs (de)referenced on (un)map (vs pre-allocated). */
12f9463a4bSBen Skeggs 	bool sparse:1; /* Unmapped PDEs/PTEs will not trigger MMU faults. */
13f9463a4bSBen Skeggs #define NVKM_VMA_PAGE_NONE 7
14f9463a4bSBen Skeggs 	u8   page:3; /* Requested page type (index, or NONE for automatic). */
15f9463a4bSBen Skeggs 	u8   refd:3; /* Current page type (index, or NONE for unreferenced). */
16f9463a4bSBen Skeggs 	bool used:1; /* Region allocated. */
17f9463a4bSBen Skeggs 	bool part:1; /* Region was split from an allocated region by map(). */
18f9463a4bSBen Skeggs 	bool user:1; /* Region user-allocated. */
19f9463a4bSBen Skeggs 	bool busy:1; /* Region busy (for temporarily preventing user access). */
208e68271dSBen Skeggs 	bool mapped:1; /* Region contains valid pages. */
21f9463a4bSBen Skeggs 	struct nvkm_memory *memory; /* Memory currently mapped into VMA. */
22f9463a4bSBen Skeggs 	struct nvkm_tags *tags; /* Compression tag reference. */
235ce3bf3cSBen Skeggs };
245ce3bf3cSBen Skeggs 
25632b740cSBen Skeggs struct nvkm_vmm {
26806a7335SBen Skeggs 	const struct nvkm_vmm_func *func;
2742594600SBen Skeggs 	struct nvkm_mmu *mmu;
28806a7335SBen Skeggs 	const char *name;
29eb813999SBen Skeggs 	u32 debug;
30806a7335SBen Skeggs 	struct kref kref;
311de68568SBen Skeggs 	struct mutex mutex;
325ce3bf3cSBen Skeggs 
33806a7335SBen Skeggs 	u64 start;
34806a7335SBen Skeggs 	u64 limit;
35806a7335SBen Skeggs 
36806a7335SBen Skeggs 	struct nvkm_vmm_pt *pd;
37806a7335SBen Skeggs 	struct list_head join;
38806a7335SBen Skeggs 
39f9463a4bSBen Skeggs 	struct list_head list;
40f9463a4bSBen Skeggs 	struct rb_root free;
41f9463a4bSBen Skeggs 	struct rb_root root;
425e075fdeSBen Skeggs 
435e075fdeSBen Skeggs 	bool bootstrapped;
4468f3f702SBen Skeggs 	atomic_t engref[NVKM_SUBDEV_NR];
455ce3bf3cSBen Skeggs 
4603b0ba7bSBen Skeggs 	dma_addr_t null;
4703b0ba7bSBen Skeggs 	void *nullp;
48ab2ee9ffSBen Skeggs 
49ab2ee9ffSBen Skeggs 	bool replay;
505ce3bf3cSBen Skeggs };
515ce3bf3cSBen Skeggs 
52f9463a4bSBen Skeggs int nvkm_vmm_new(struct nvkm_device *, u64 addr, u64 size, void *argv, u32 argc,
53f9463a4bSBen Skeggs 		 struct lock_class_key *, const char *name, struct nvkm_vmm **);
54f9463a4bSBen Skeggs struct nvkm_vmm *nvkm_vmm_ref(struct nvkm_vmm *);
55f9463a4bSBen Skeggs void nvkm_vmm_unref(struct nvkm_vmm **);
56eb813999SBen Skeggs int nvkm_vmm_boot(struct nvkm_vmm *);
57f9463a4bSBen Skeggs int nvkm_vmm_join(struct nvkm_vmm *, struct nvkm_memory *inst);
58f9463a4bSBen Skeggs void nvkm_vmm_part(struct nvkm_vmm *, struct nvkm_memory *inst);
59f9463a4bSBen Skeggs int nvkm_vmm_get(struct nvkm_vmm *, u8 page, u64 size, struct nvkm_vma **);
60f9463a4bSBen Skeggs void nvkm_vmm_put(struct nvkm_vmm *, struct nvkm_vma **);
61eb813999SBen Skeggs 
62eb813999SBen Skeggs struct nvkm_vmm_map {
63eb813999SBen Skeggs 	struct nvkm_memory *memory;
64eb813999SBen Skeggs 	u64 offset;
65eb813999SBen Skeggs 
66eb813999SBen Skeggs 	struct nvkm_mm_node *mem;
67eb813999SBen Skeggs 	struct scatterlist *sgl;
68eb813999SBen Skeggs 	dma_addr_t *dma;
69a5ff307fSBen Skeggs 	u64 *pfn;
70eb813999SBen Skeggs 	u64 off;
71eb813999SBen Skeggs 
72eb813999SBen Skeggs 	const struct nvkm_vmm_page *page;
73eb813999SBen Skeggs 
74eb813999SBen Skeggs 	struct nvkm_tags *tags;
75eb813999SBen Skeggs 	u64 next;
76eb813999SBen Skeggs 	u64 type;
77eb813999SBen Skeggs 	u64 ctag;
78eb813999SBen Skeggs };
79eb813999SBen Skeggs 
80f9463a4bSBen Skeggs int nvkm_vmm_map(struct nvkm_vmm *, struct nvkm_vma *, void *argv, u32 argc,
81f9463a4bSBen Skeggs 		 struct nvkm_vmm_map *);
82f9463a4bSBen Skeggs void nvkm_vmm_unmap(struct nvkm_vmm *, struct nvkm_vma *);
83f9463a4bSBen Skeggs 
84c83c4097SBen Skeggs struct nvkm_memory *nvkm_umem_search(struct nvkm_client *, u64);
85f9463a4bSBen Skeggs struct nvkm_vmm *nvkm_uvmm_search(struct nvkm_client *, u64 handle);
86c9582455SBen Skeggs 
87c9582455SBen Skeggs struct nvkm_mmu {
88c9582455SBen Skeggs 	const struct nvkm_mmu_func *func;
89c9582455SBen Skeggs 	struct nvkm_subdev subdev;
90c9582455SBen Skeggs 
91c9582455SBen Skeggs 	u8  dma_bits;
920b11b30dSBen Skeggs 
9351645eb7SBen Skeggs 	int heap_nr;
9451645eb7SBen Skeggs 	struct {
9551645eb7SBen Skeggs #define NVKM_MEM_VRAM                                                      0x01
9651645eb7SBen Skeggs #define NVKM_MEM_HOST                                                      0x02
9751645eb7SBen Skeggs #define NVKM_MEM_COMP                                                      0x04
9851645eb7SBen Skeggs #define NVKM_MEM_DISP                                                      0x08
9951645eb7SBen Skeggs 		u8  type;
10051645eb7SBen Skeggs 		u64 size;
10151645eb7SBen Skeggs 	} heap[4];
10251645eb7SBen Skeggs 
10351645eb7SBen Skeggs 	int type_nr;
10451645eb7SBen Skeggs 	struct {
10551645eb7SBen Skeggs #define NVKM_MEM_KIND                                                      0x10
10651645eb7SBen Skeggs #define NVKM_MEM_MAPPABLE                                                  0x20
10751645eb7SBen Skeggs #define NVKM_MEM_COHERENT                                                  0x40
10851645eb7SBen Skeggs #define NVKM_MEM_UNCACHED                                                  0x80
10951645eb7SBen Skeggs 		u8 type;
11051645eb7SBen Skeggs 		u8 heap;
11151645eb7SBen Skeggs 	} type[16];
11251645eb7SBen Skeggs 
1130b11b30dSBen Skeggs 	struct nvkm_vmm *vmm;
1149a45ddaaSBen Skeggs 
1159a45ddaaSBen Skeggs 	struct {
1169a45ddaaSBen Skeggs 		struct mutex mutex;
1179a45ddaaSBen Skeggs 		struct list_head list;
118f1280394SBen Skeggs 	} ptc, ptp;
119eea5cf0fSBen Skeggs 
120*5ec69c91SBen Skeggs 	struct mutex mutex; /* serialises mmu invalidations */
121*5ec69c91SBen Skeggs 
122eea5cf0fSBen Skeggs 	struct nvkm_device_oclass user;
123c9582455SBen Skeggs };
124c9582455SBen Skeggs 
125c9582455SBen Skeggs int nv04_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
126c9582455SBen Skeggs int nv41_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
127c9582455SBen Skeggs int nv44_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
128c9582455SBen Skeggs int nv50_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
1290f43715fSBen Skeggs int g84_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
1302ffa64ebSBen Skeggs int mcp77_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
131c9582455SBen Skeggs int gf100_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
132db018585SBen Skeggs int gk104_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
133d1f6c8d2SBen Skeggs int gk20a_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
134e1e33c79SBen Skeggs int gm200_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
135cedc4d57SBen Skeggs int gm20b_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
136b86a4587SBen Skeggs int gp100_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
1376359c982SBen Skeggs int gp10b_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
138edf50395SBen Skeggs int gv100_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
139c011b254SBen Skeggs int tu102_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
1405ce3bf3cSBen Skeggs #endif
141