xref: /linux/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c (revision a13d7201d7deedcbb6ac6efa94a1a7d34d3d79ec)
1 /*
2  * Copyright 2010 Red Hat Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: Ben Skeggs
23  */
24 #include <subdev/mmu.h>
25 #include <subdev/fb.h>
26 
27 #include <core/gpuobj.h>
28 
29 void
30 nvkm_vm_map_at(struct nvkm_vma *vma, u64 delta, struct nvkm_mem *node)
31 {
32 	struct nvkm_vm *vm = vma->vm;
33 	struct nvkm_mmu *mmu = vm->mmu;
34 	struct nvkm_mm_node *r;
35 	int big = vma->node->type != mmu->spg_shift;
36 	u32 offset = vma->node->offset + (delta >> 12);
37 	u32 bits = vma->node->type - 12;
38 	u32 pde  = (offset >> mmu->pgt_bits) - vm->fpde;
39 	u32 pte  = (offset & ((1 << mmu->pgt_bits) - 1)) >> bits;
40 	u32 max  = 1 << (mmu->pgt_bits - bits);
41 	u32 end, len;
42 
43 	delta = 0;
44 	list_for_each_entry(r, &node->regions, rl_entry) {
45 		u64 phys = (u64)r->offset << 12;
46 		u32 num  = r->length >> bits;
47 
48 		while (num) {
49 			struct nvkm_gpuobj *pgt = vm->pgt[pde].obj[big];
50 
51 			end = (pte + num);
52 			if (unlikely(end >= max))
53 				end = max;
54 			len = end - pte;
55 
56 			mmu->map(vma, pgt, node, pte, len, phys, delta);
57 
58 			num -= len;
59 			pte += len;
60 			if (unlikely(end >= max)) {
61 				phys += len << (bits + 12);
62 				pde++;
63 				pte = 0;
64 			}
65 
66 			delta += (u64)len << vma->node->type;
67 		}
68 	}
69 
70 	mmu->flush(vm);
71 }
72 
73 static void
74 nvkm_vm_map_sg_table(struct nvkm_vma *vma, u64 delta, u64 length,
75 		     struct nvkm_mem *mem)
76 {
77 	struct nvkm_vm *vm = vma->vm;
78 	struct nvkm_mmu *mmu = vm->mmu;
79 	int big = vma->node->type != mmu->spg_shift;
80 	u32 offset = vma->node->offset + (delta >> 12);
81 	u32 bits = vma->node->type - 12;
82 	u32 num  = length >> vma->node->type;
83 	u32 pde  = (offset >> mmu->pgt_bits) - vm->fpde;
84 	u32 pte  = (offset & ((1 << mmu->pgt_bits) - 1)) >> bits;
85 	u32 max  = 1 << (mmu->pgt_bits - bits);
86 	unsigned m, sglen;
87 	u32 end, len;
88 	int i;
89 	struct scatterlist *sg;
90 
91 	for_each_sg(mem->sg->sgl, sg, mem->sg->nents, i) {
92 		struct nvkm_gpuobj *pgt = vm->pgt[pde].obj[big];
93 		sglen = sg_dma_len(sg) >> PAGE_SHIFT;
94 
95 		end = pte + sglen;
96 		if (unlikely(end >= max))
97 			end = max;
98 		len = end - pte;
99 
100 		for (m = 0; m < len; m++) {
101 			dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT);
102 
103 			mmu->map_sg(vma, pgt, mem, pte, 1, &addr);
104 			num--;
105 			pte++;
106 
107 			if (num == 0)
108 				goto finish;
109 		}
110 		if (unlikely(end >= max)) {
111 			pde++;
112 			pte = 0;
113 		}
114 		if (m < sglen) {
115 			for (; m < sglen; m++) {
116 				dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT);
117 
118 				mmu->map_sg(vma, pgt, mem, pte, 1, &addr);
119 				num--;
120 				pte++;
121 				if (num == 0)
122 					goto finish;
123 			}
124 		}
125 
126 	}
127 finish:
128 	mmu->flush(vm);
129 }
130 
131 static void
132 nvkm_vm_map_sg(struct nvkm_vma *vma, u64 delta, u64 length,
133 	       struct nvkm_mem *mem)
134 {
135 	struct nvkm_vm *vm = vma->vm;
136 	struct nvkm_mmu *mmu = vm->mmu;
137 	dma_addr_t *list = mem->pages;
138 	int big = vma->node->type != mmu->spg_shift;
139 	u32 offset = vma->node->offset + (delta >> 12);
140 	u32 bits = vma->node->type - 12;
141 	u32 num  = length >> vma->node->type;
142 	u32 pde  = (offset >> mmu->pgt_bits) - vm->fpde;
143 	u32 pte  = (offset & ((1 << mmu->pgt_bits) - 1)) >> bits;
144 	u32 max  = 1 << (mmu->pgt_bits - bits);
145 	u32 end, len;
146 
147 	while (num) {
148 		struct nvkm_gpuobj *pgt = vm->pgt[pde].obj[big];
149 
150 		end = (pte + num);
151 		if (unlikely(end >= max))
152 			end = max;
153 		len = end - pte;
154 
155 		mmu->map_sg(vma, pgt, mem, pte, len, list);
156 
157 		num  -= len;
158 		pte  += len;
159 		list += len;
160 		if (unlikely(end >= max)) {
161 			pde++;
162 			pte = 0;
163 		}
164 	}
165 
166 	mmu->flush(vm);
167 }
168 
169 void
170 nvkm_vm_map(struct nvkm_vma *vma, struct nvkm_mem *node)
171 {
172 	if (node->sg)
173 		nvkm_vm_map_sg_table(vma, 0, node->size << 12, node);
174 	else
175 	if (node->pages)
176 		nvkm_vm_map_sg(vma, 0, node->size << 12, node);
177 	else
178 		nvkm_vm_map_at(vma, 0, node);
179 }
180 
181 void
182 nvkm_vm_unmap_at(struct nvkm_vma *vma, u64 delta, u64 length)
183 {
184 	struct nvkm_vm *vm = vma->vm;
185 	struct nvkm_mmu *mmu = vm->mmu;
186 	int big = vma->node->type != mmu->spg_shift;
187 	u32 offset = vma->node->offset + (delta >> 12);
188 	u32 bits = vma->node->type - 12;
189 	u32 num  = length >> vma->node->type;
190 	u32 pde  = (offset >> mmu->pgt_bits) - vm->fpde;
191 	u32 pte  = (offset & ((1 << mmu->pgt_bits) - 1)) >> bits;
192 	u32 max  = 1 << (mmu->pgt_bits - bits);
193 	u32 end, len;
194 
195 	while (num) {
196 		struct nvkm_gpuobj *pgt = vm->pgt[pde].obj[big];
197 
198 		end = (pte + num);
199 		if (unlikely(end >= max))
200 			end = max;
201 		len = end - pte;
202 
203 		mmu->unmap(pgt, pte, len);
204 
205 		num -= len;
206 		pte += len;
207 		if (unlikely(end >= max)) {
208 			pde++;
209 			pte = 0;
210 		}
211 	}
212 
213 	mmu->flush(vm);
214 }
215 
216 void
217 nvkm_vm_unmap(struct nvkm_vma *vma)
218 {
219 	nvkm_vm_unmap_at(vma, 0, (u64)vma->node->length << 12);
220 }
221 
222 static void
223 nvkm_vm_unmap_pgt(struct nvkm_vm *vm, int big, u32 fpde, u32 lpde)
224 {
225 	struct nvkm_mmu *mmu = vm->mmu;
226 	struct nvkm_vm_pgd *vpgd;
227 	struct nvkm_vm_pgt *vpgt;
228 	struct nvkm_gpuobj *pgt;
229 	u32 pde;
230 
231 	for (pde = fpde; pde <= lpde; pde++) {
232 		vpgt = &vm->pgt[pde - vm->fpde];
233 		if (--vpgt->refcount[big])
234 			continue;
235 
236 		pgt = vpgt->obj[big];
237 		vpgt->obj[big] = NULL;
238 
239 		list_for_each_entry(vpgd, &vm->pgd_list, head) {
240 			mmu->map_pgt(vpgd->obj, pde, vpgt->obj);
241 		}
242 
243 		mutex_unlock(&nv_subdev(mmu)->mutex);
244 		nvkm_gpuobj_ref(NULL, &pgt);
245 		mutex_lock(&nv_subdev(mmu)->mutex);
246 	}
247 }
248 
249 static int
250 nvkm_vm_map_pgt(struct nvkm_vm *vm, u32 pde, u32 type)
251 {
252 	struct nvkm_mmu *mmu = vm->mmu;
253 	struct nvkm_vm_pgt *vpgt = &vm->pgt[pde - vm->fpde];
254 	struct nvkm_vm_pgd *vpgd;
255 	struct nvkm_gpuobj *pgt;
256 	int big = (type != mmu->spg_shift);
257 	u32 pgt_size;
258 	int ret;
259 
260 	pgt_size  = (1 << (mmu->pgt_bits + 12)) >> type;
261 	pgt_size *= 8;
262 
263 	mutex_unlock(&nv_subdev(mmu)->mutex);
264 	ret = nvkm_gpuobj_new(nv_object(vm->mmu), NULL, pgt_size, 0x1000,
265 			      NVOBJ_FLAG_ZERO_ALLOC, &pgt);
266 	mutex_lock(&nv_subdev(mmu)->mutex);
267 	if (unlikely(ret))
268 		return ret;
269 
270 	/* someone beat us to filling the PDE while we didn't have the lock */
271 	if (unlikely(vpgt->refcount[big]++)) {
272 		mutex_unlock(&nv_subdev(mmu)->mutex);
273 		nvkm_gpuobj_ref(NULL, &pgt);
274 		mutex_lock(&nv_subdev(mmu)->mutex);
275 		return 0;
276 	}
277 
278 	vpgt->obj[big] = pgt;
279 	list_for_each_entry(vpgd, &vm->pgd_list, head) {
280 		mmu->map_pgt(vpgd->obj, pde, vpgt->obj);
281 	}
282 
283 	return 0;
284 }
285 
286 int
287 nvkm_vm_get(struct nvkm_vm *vm, u64 size, u32 page_shift, u32 access,
288 	    struct nvkm_vma *vma)
289 {
290 	struct nvkm_mmu *mmu = vm->mmu;
291 	u32 align = (1 << page_shift) >> 12;
292 	u32 msize = size >> 12;
293 	u32 fpde, lpde, pde;
294 	int ret;
295 
296 	mutex_lock(&nv_subdev(mmu)->mutex);
297 	ret = nvkm_mm_head(&vm->mm, 0, page_shift, msize, msize, align,
298 			   &vma->node);
299 	if (unlikely(ret != 0)) {
300 		mutex_unlock(&nv_subdev(mmu)->mutex);
301 		return ret;
302 	}
303 
304 	fpde = (vma->node->offset >> mmu->pgt_bits);
305 	lpde = (vma->node->offset + vma->node->length - 1) >> mmu->pgt_bits;
306 
307 	for (pde = fpde; pde <= lpde; pde++) {
308 		struct nvkm_vm_pgt *vpgt = &vm->pgt[pde - vm->fpde];
309 		int big = (vma->node->type != mmu->spg_shift);
310 
311 		if (likely(vpgt->refcount[big])) {
312 			vpgt->refcount[big]++;
313 			continue;
314 		}
315 
316 		ret = nvkm_vm_map_pgt(vm, pde, vma->node->type);
317 		if (ret) {
318 			if (pde != fpde)
319 				nvkm_vm_unmap_pgt(vm, big, fpde, pde - 1);
320 			nvkm_mm_free(&vm->mm, &vma->node);
321 			mutex_unlock(&nv_subdev(mmu)->mutex);
322 			return ret;
323 		}
324 	}
325 	mutex_unlock(&nv_subdev(mmu)->mutex);
326 
327 	vma->vm = NULL;
328 	nvkm_vm_ref(vm, &vma->vm, NULL);
329 	vma->offset = (u64)vma->node->offset << 12;
330 	vma->access = access;
331 	return 0;
332 }
333 
334 void
335 nvkm_vm_put(struct nvkm_vma *vma)
336 {
337 	struct nvkm_vm *vm = vma->vm;
338 	struct nvkm_mmu *mmu = vm->mmu;
339 	u32 fpde, lpde;
340 
341 	if (unlikely(vma->node == NULL))
342 		return;
343 	fpde = (vma->node->offset >> mmu->pgt_bits);
344 	lpde = (vma->node->offset + vma->node->length - 1) >> mmu->pgt_bits;
345 
346 	mutex_lock(&nv_subdev(mmu)->mutex);
347 	nvkm_vm_unmap_pgt(vm, vma->node->type != mmu->spg_shift, fpde, lpde);
348 	nvkm_mm_free(&vm->mm, &vma->node);
349 	mutex_unlock(&nv_subdev(mmu)->mutex);
350 
351 	nvkm_vm_ref(NULL, &vma->vm, NULL);
352 }
353 
354 int
355 nvkm_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset,
356 	       u32 block, struct nvkm_vm **pvm)
357 {
358 	struct nvkm_vm *vm;
359 	u64 mm_length = (offset + length) - mm_offset;
360 	int ret;
361 
362 	vm = kzalloc(sizeof(*vm), GFP_KERNEL);
363 	if (!vm)
364 		return -ENOMEM;
365 
366 	INIT_LIST_HEAD(&vm->pgd_list);
367 	vm->mmu = mmu;
368 	kref_init(&vm->refcount);
369 	vm->fpde = offset >> (mmu->pgt_bits + 12);
370 	vm->lpde = (offset + length - 1) >> (mmu->pgt_bits + 12);
371 
372 	vm->pgt  = vzalloc((vm->lpde - vm->fpde + 1) * sizeof(*vm->pgt));
373 	if (!vm->pgt) {
374 		kfree(vm);
375 		return -ENOMEM;
376 	}
377 
378 	ret = nvkm_mm_init(&vm->mm, mm_offset >> 12, mm_length >> 12,
379 			   block >> 12);
380 	if (ret) {
381 		vfree(vm->pgt);
382 		kfree(vm);
383 		return ret;
384 	}
385 
386 	*pvm = vm;
387 
388 	return 0;
389 }
390 
391 int
392 nvkm_vm_new(struct nvkm_device *device, u64 offset, u64 length, u64 mm_offset,
393 	    struct nvkm_vm **pvm)
394 {
395 	struct nvkm_mmu *mmu = nvkm_mmu(device);
396 	return mmu->create(mmu, offset, length, mm_offset, pvm);
397 }
398 
399 static int
400 nvkm_vm_link(struct nvkm_vm *vm, struct nvkm_gpuobj *pgd)
401 {
402 	struct nvkm_mmu *mmu = vm->mmu;
403 	struct nvkm_vm_pgd *vpgd;
404 	int i;
405 
406 	if (!pgd)
407 		return 0;
408 
409 	vpgd = kzalloc(sizeof(*vpgd), GFP_KERNEL);
410 	if (!vpgd)
411 		return -ENOMEM;
412 
413 	nvkm_gpuobj_ref(pgd, &vpgd->obj);
414 
415 	mutex_lock(&nv_subdev(mmu)->mutex);
416 	for (i = vm->fpde; i <= vm->lpde; i++)
417 		mmu->map_pgt(pgd, i, vm->pgt[i - vm->fpde].obj);
418 	list_add(&vpgd->head, &vm->pgd_list);
419 	mutex_unlock(&nv_subdev(mmu)->mutex);
420 	return 0;
421 }
422 
423 static void
424 nvkm_vm_unlink(struct nvkm_vm *vm, struct nvkm_gpuobj *mpgd)
425 {
426 	struct nvkm_mmu *mmu = vm->mmu;
427 	struct nvkm_vm_pgd *vpgd, *tmp;
428 	struct nvkm_gpuobj *pgd = NULL;
429 
430 	if (!mpgd)
431 		return;
432 
433 	mutex_lock(&nv_subdev(mmu)->mutex);
434 	list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) {
435 		if (vpgd->obj == mpgd) {
436 			pgd = vpgd->obj;
437 			list_del(&vpgd->head);
438 			kfree(vpgd);
439 			break;
440 		}
441 	}
442 	mutex_unlock(&nv_subdev(mmu)->mutex);
443 
444 	nvkm_gpuobj_ref(NULL, &pgd);
445 }
446 
447 static void
448 nvkm_vm_del(struct kref *kref)
449 {
450 	struct nvkm_vm *vm = container_of(kref, typeof(*vm), refcount);
451 	struct nvkm_vm_pgd *vpgd, *tmp;
452 
453 	list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) {
454 		nvkm_vm_unlink(vm, vpgd->obj);
455 	}
456 
457 	nvkm_mm_fini(&vm->mm);
458 	vfree(vm->pgt);
459 	kfree(vm);
460 }
461 
462 int
463 nvkm_vm_ref(struct nvkm_vm *ref, struct nvkm_vm **ptr, struct nvkm_gpuobj *pgd)
464 {
465 	if (ref) {
466 		int ret = nvkm_vm_link(ref, pgd);
467 		if (ret)
468 			return ret;
469 
470 		kref_get(&ref->refcount);
471 	}
472 
473 	if (*ptr) {
474 		nvkm_vm_unlink(*ptr, pgd);
475 		kref_put(&(*ptr)->refcount, nvkm_vm_del);
476 	}
477 
478 	*ptr = ref;
479 	return 0;
480 }
481