Home | History | Annotate | Line # | Download | only in mmu
      1 /*	$NetBSD: nouveau_nvkm_subdev_mmu_base.c,v 1.8 2021/12/19 10:51:58 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright 2010 Red Hat Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors: Ben Skeggs
     25  */
     26 #include <sys/cdefs.h>
     27 __KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_subdev_mmu_base.c,v 1.8 2021/12/19 10:51:58 riastradh Exp $");
     28 
     29 #include "ummu.h"
     30 #include "vmm.h"
     31 
     32 #include <subdev/bar.h>
     33 #include <subdev/fb.h>
     34 
     35 #include <nvif/if500d.h>
     36 #include <nvif/if900d.h>
     37 
     38 #include <linux/nbsd-namespace.h>
     39 
     40 struct nvkm_mmu_ptp {
     41 	struct nvkm_mmu_pt *pt;
     42 	struct list_head head;
     43 	u8  shift;
     44 	u16 mask;
     45 	u16 free;
     46 };
     47 
     48 static void
     49 nvkm_mmu_ptp_put(struct nvkm_mmu *mmu, bool force, struct nvkm_mmu_pt *pt)
     50 {
     51 	const int slot = pt->base >> pt->ptp->shift;
     52 	struct nvkm_mmu_ptp *ptp = pt->ptp;
     53 
     54 	/* If there were no free slots in the parent allocation before,
     55 	 * there will be now, so return PTP to the cache.
     56 	 */
     57 	if (!ptp->free)
     58 		list_add(&ptp->head, &mmu->ptp.list);
     59 	ptp->free |= BIT(slot);
     60 
     61 	/* If there's no more sub-allocations, destroy PTP. */
     62 	if (ptp->free == ptp->mask) {
     63 		nvkm_mmu_ptc_put(mmu, force, &ptp->pt);
     64 		list_del(&ptp->head);
     65 		kfree(ptp);
     66 	}
     67 
     68 	kfree(pt);
     69 }
     70 
     71 static struct nvkm_mmu_pt *
     72 nvkm_mmu_ptp_get(struct nvkm_mmu *mmu, u32 size, bool zero)
     73 {
     74 	struct nvkm_mmu_pt *pt;
     75 	struct nvkm_mmu_ptp *ptp;
     76 	int slot;
     77 
     78 	if (!(pt = kzalloc(sizeof(*pt), GFP_KERNEL)))
     79 		return NULL;
     80 
     81 	ptp = list_first_entry_or_null(&mmu->ptp.list, typeof(*ptp), head);
     82 	if (!ptp) {
     83 		/* Need to allocate a new parent to sub-allocate from. */
     84 		if (!(ptp = kmalloc(sizeof(*ptp), GFP_KERNEL))) {
     85 			kfree(pt);
     86 			return NULL;
     87 		}
     88 
     89 		ptp->pt = nvkm_mmu_ptc_get(mmu, 0x1000, 0x1000, false);
     90 		if (!ptp->pt) {
     91 			kfree(ptp);
     92 			kfree(pt);
     93 			return NULL;
     94 		}
     95 
     96 		ptp->shift = order_base_2(size);
     97 		slot = nvkm_memory_size(ptp->pt->memory) >> ptp->shift;
     98 		ptp->mask = (1 << slot) - 1;
     99 		ptp->free = ptp->mask;
    100 		list_add(&ptp->head, &mmu->ptp.list);
    101 	}
    102 	pt->ptp = ptp;
    103 	pt->sub = true;
    104 
    105 	/* Sub-allocate from parent object, removing PTP from cache
    106 	 * if there's no more free slots left.
    107 	 */
    108 	slot = __ffs(ptp->free);
    109 	ptp->free &= ~BIT(slot);
    110 	if (!ptp->free)
    111 		list_del(&ptp->head);
    112 
    113 	pt->memory = pt->ptp->pt->memory;
    114 	pt->base = slot << ptp->shift;
    115 	pt->addr = pt->ptp->pt->addr + pt->base;
    116 	return pt;
    117 }
    118 
    119 struct nvkm_mmu_ptc {
    120 	struct list_head head;
    121 	struct list_head item;
    122 	u32 size;
    123 	u32 refs;
    124 };
    125 
    126 static inline struct nvkm_mmu_ptc *
    127 nvkm_mmu_ptc_find(struct nvkm_mmu *mmu, u32 size)
    128 {
    129 	struct nvkm_mmu_ptc *ptc;
    130 
    131 	list_for_each_entry(ptc, &mmu->ptc.list, head) {
    132 		if (ptc->size == size)
    133 			return ptc;
    134 	}
    135 
    136 	ptc = kmalloc(sizeof(*ptc), GFP_KERNEL);
    137 	if (ptc) {
    138 		INIT_LIST_HEAD(&ptc->item);
    139 		ptc->size = size;
    140 		ptc->refs = 0;
    141 		list_add(&ptc->head, &mmu->ptc.list);
    142 	}
    143 
    144 	return ptc;
    145 }
    146 
    147 void
    148 nvkm_mmu_ptc_put(struct nvkm_mmu *mmu, bool force, struct nvkm_mmu_pt **ppt)
    149 {
    150 	struct nvkm_mmu_pt *pt = *ppt;
    151 	if (pt) {
    152 		/* Handle sub-allocated page tables. */
    153 		if (pt->sub) {
    154 			mutex_lock(&mmu->ptp.mutex);
    155 			nvkm_mmu_ptp_put(mmu, force, pt);
    156 			mutex_unlock(&mmu->ptp.mutex);
    157 			return;
    158 		}
    159 
    160 		/* Either cache or free the object. */
    161 		mutex_lock(&mmu->ptc.mutex);
    162 		if (pt->ptc->refs < 8 /* Heuristic. */ && !force) {
    163 			list_add_tail(&pt->head, &pt->ptc->item);
    164 			pt->ptc->refs++;
    165 		} else {
    166 			nvkm_memory_unref(&pt->memory);
    167 			kfree(pt);
    168 		}
    169 		mutex_unlock(&mmu->ptc.mutex);
    170 	}
    171 }
    172 
    173 struct nvkm_mmu_pt *
    174 nvkm_mmu_ptc_get(struct nvkm_mmu *mmu, u32 size, u32 align, bool zero)
    175 {
    176 	struct nvkm_mmu_ptc *ptc;
    177 	struct nvkm_mmu_pt *pt;
    178 	int ret;
    179 
    180 	/* Sub-allocated page table (ie. GP100 LPT). */
    181 	if (align < 0x1000) {
    182 		mutex_lock(&mmu->ptp.mutex);
    183 		pt = nvkm_mmu_ptp_get(mmu, align, zero);
    184 		mutex_unlock(&mmu->ptp.mutex);
    185 		return pt;
    186 	}
    187 
    188 	/* Lookup cache for this page table size. */
    189 	mutex_lock(&mmu->ptc.mutex);
    190 	ptc = nvkm_mmu_ptc_find(mmu, size);
    191 	if (!ptc) {
    192 		mutex_unlock(&mmu->ptc.mutex);
    193 		return NULL;
    194 	}
    195 
    196 	/* If there's a free PT in the cache, reuse it. */
    197 	pt = list_first_entry_or_null(&ptc->item, typeof(*pt), head);
    198 	if (pt) {
    199 		if (zero)
    200 			nvkm_fo64(pt->memory, 0, 0, size >> 3);
    201 		list_del(&pt->head);
    202 		ptc->refs--;
    203 		mutex_unlock(&mmu->ptc.mutex);
    204 		return pt;
    205 	}
    206 	mutex_unlock(&mmu->ptc.mutex);
    207 
    208 	/* No such luck, we need to allocate. */
    209 	if (!(pt = kmalloc(sizeof(*pt), GFP_KERNEL)))
    210 		return NULL;
    211 	pt->ptc = ptc;
    212 	pt->sub = false;
    213 
    214 	ret = nvkm_memory_new(mmu->subdev.device, NVKM_MEM_TARGET_INST,
    215 			      size, align, zero, &pt->memory);
    216 	if (ret) {
    217 		kfree(pt);
    218 		return NULL;
    219 	}
    220 
    221 	pt->base = 0;
    222 	pt->addr = nvkm_memory_addr(pt->memory);
    223 	return pt;
    224 }
    225 
    226 void
    227 nvkm_mmu_ptc_dump(struct nvkm_mmu *mmu)
    228 {
    229 	struct nvkm_mmu_ptc *ptc;
    230 	list_for_each_entry(ptc, &mmu->ptc.list, head) {
    231 		struct nvkm_mmu_pt *pt, *tt;
    232 		list_for_each_entry_safe(pt, tt, &ptc->item, head) {
    233 			nvkm_memory_unref(&pt->memory);
    234 			list_del(&pt->head);
    235 			kfree(pt);
    236 		}
    237 	}
    238 }
    239 
    240 static void
    241 nvkm_mmu_ptc_fini(struct nvkm_mmu *mmu)
    242 {
    243 	struct nvkm_mmu_ptc *ptc, *ptct;
    244 
    245 	list_for_each_entry_safe(ptc, ptct, &mmu->ptc.list, head) {
    246 		WARN_ON(!list_empty(&ptc->item));
    247 		list_del(&ptc->head);
    248 		kfree(ptc);
    249 	}
    250 
    251 	mutex_destroy(&mmu->ptp.mutex);
    252 	mutex_destroy(&mmu->ptc.mutex);
    253 }
    254 
    255 static void
    256 nvkm_mmu_ptc_init(struct nvkm_mmu *mmu)
    257 {
    258 	mutex_init(&mmu->ptc.mutex);
    259 	INIT_LIST_HEAD(&mmu->ptc.list);
    260 	mutex_init(&mmu->ptp.mutex);
    261 	INIT_LIST_HEAD(&mmu->ptp.list);
    262 }
    263 
    264 static void
    265 nvkm_mmu_type(struct nvkm_mmu *mmu, int heap, u8 type)
    266 {
    267 	if (heap >= 0 && !WARN_ON(mmu->type_nr == ARRAY_SIZE(mmu->type))) {
    268 		mmu->type[mmu->type_nr].type = type | mmu->heap[heap].type;
    269 		mmu->type[mmu->type_nr].heap = heap;
    270 		mmu->type_nr++;
    271 	}
    272 }
    273 
    274 static int
    275 nvkm_mmu_heap(struct nvkm_mmu *mmu, u8 type, u64 size)
    276 {
    277 	if (size) {
    278 		if (!WARN_ON(mmu->heap_nr == ARRAY_SIZE(mmu->heap))) {
    279 			mmu->heap[mmu->heap_nr].type = type;
    280 			mmu->heap[mmu->heap_nr].size = size;
    281 			return mmu->heap_nr++;
    282 		}
    283 	}
    284 	return -EINVAL;
    285 }
    286 
    287 static void
    288 nvkm_mmu_host(struct nvkm_mmu *mmu)
    289 {
    290 	struct nvkm_device *device = mmu->subdev.device;
    291 	u8 type = NVKM_MEM_KIND * !!mmu->func->kind_sys;
    292 	int heap;
    293 
    294 	/* Non-mappable system memory. */
    295 	heap = nvkm_mmu_heap(mmu, NVKM_MEM_HOST, ~0ULL);
    296 	nvkm_mmu_type(mmu, heap, type);
    297 
    298 	/* Non-coherent, cached, system memory.
    299 	 *
    300 	 * Block-linear mappings of system memory must be done through
    301 	 * BAR1, and cannot be supported on systems where we're unable
    302 	 * to map BAR1 with write-combining.
    303 	 */
    304 	type |= NVKM_MEM_MAPPABLE;
    305 	if (!device->bar || device->bar->iomap_uncached)
    306 		nvkm_mmu_type(mmu, heap, type & ~NVKM_MEM_KIND);
    307 	else
    308 		nvkm_mmu_type(mmu, heap, type);
    309 
    310 	/* Coherent, cached, system memory.
    311 	 *
    312 	 * Unsupported on systems that aren't able to support snooped
    313 	 * mappings, and also for block-linear mappings which must be
    314 	 * done through BAR1.
    315 	 */
    316 	type |= NVKM_MEM_COHERENT;
    317 	if (device->func->cpu_coherent)
    318 		nvkm_mmu_type(mmu, heap, type & ~NVKM_MEM_KIND);
    319 
    320 	/* Uncached system memory. */
    321 	nvkm_mmu_type(mmu, heap, type |= NVKM_MEM_UNCACHED);
    322 }
    323 
    324 static void
    325 nvkm_mmu_vram(struct nvkm_mmu *mmu)
    326 {
    327 	struct nvkm_device *device = mmu->subdev.device;
    328 	struct nvkm_mm *mm = &device->fb->ram->vram;
    329 	const u32 sizeN = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NORMAL);
    330 	const u32 sizeU = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NOMAP);
    331 	const u32 sizeM = nvkm_mm_heap_size(mm, NVKM_RAM_MM_MIXED);
    332 	u8 type = NVKM_MEM_KIND * !!mmu->func->kind;
    333 	u8 heap = NVKM_MEM_VRAM;
    334 	int heapM, heapN, heapU;
    335 
    336 	/* Mixed-memory doesn't support compression or display. */
    337 	heapM = nvkm_mmu_heap(mmu, heap, sizeM << NVKM_RAM_MM_SHIFT);
    338 
    339 	heap |= NVKM_MEM_COMP;
    340 	heap |= NVKM_MEM_DISP;
    341 	heapN = nvkm_mmu_heap(mmu, heap, sizeN << NVKM_RAM_MM_SHIFT);
    342 	heapU = nvkm_mmu_heap(mmu, heap, sizeU << NVKM_RAM_MM_SHIFT);
    343 
    344 	/* Add non-mappable VRAM types first so that they're preferred
    345 	 * over anything else.  Mixed-memory will be slower than other
    346 	 * heaps, it's prioritised last.
    347 	 */
    348 	nvkm_mmu_type(mmu, heapU, type);
    349 	nvkm_mmu_type(mmu, heapN, type);
    350 	nvkm_mmu_type(mmu, heapM, type);
    351 
    352 	/* Add host memory types next, under the assumption that users
    353 	 * wanting mappable memory want to use them as staging buffers
    354 	 * or the like.
    355 	 */
    356 	nvkm_mmu_host(mmu);
    357 
    358 	/* Mappable VRAM types go last, as they're basically the worst
    359 	 * possible type to ask for unless there's no other choice.
    360 	 */
    361 	if (device->bar) {
    362 		/* Write-combined BAR1 access. */
    363 		type |= NVKM_MEM_MAPPABLE;
    364 		if (!device->bar->iomap_uncached) {
    365 			nvkm_mmu_type(mmu, heapN, type);
    366 			nvkm_mmu_type(mmu, heapM, type);
    367 		}
    368 
    369 		/* Uncached BAR1 access. */
    370 		type |= NVKM_MEM_COHERENT;
    371 		type |= NVKM_MEM_UNCACHED;
    372 		nvkm_mmu_type(mmu, heapN, type);
    373 		nvkm_mmu_type(mmu, heapM, type);
    374 	}
    375 }
    376 
    377 static int
    378 nvkm_mmu_oneinit(struct nvkm_subdev *subdev)
    379 {
    380 	struct nvkm_mmu *mmu = nvkm_mmu(subdev);
    381 
    382 	/* Determine available memory types. */
    383 	if (mmu->subdev.device->fb && mmu->subdev.device->fb->ram)
    384 		nvkm_mmu_vram(mmu);
    385 	else
    386 		nvkm_mmu_host(mmu);
    387 
    388 	if (mmu->func->vmm.global) {
    389 		int ret = nvkm_vmm_new(subdev->device, 0, 0, NULL, 0, NULL,
    390 				       "gart", &mmu->vmm);
    391 		if (ret)
    392 			return ret;
    393 	}
    394 
    395 	return 0;
    396 }
    397 
    398 static int
    399 nvkm_mmu_init(struct nvkm_subdev *subdev)
    400 {
    401 	struct nvkm_mmu *mmu = nvkm_mmu(subdev);
    402 	if (mmu->func->init)
    403 		mmu->func->init(mmu);
    404 	return 0;
    405 }
    406 
    407 static void *
    408 nvkm_mmu_dtor(struct nvkm_subdev *subdev)
    409 {
    410 	struct nvkm_mmu *mmu = nvkm_mmu(subdev);
    411 
    412 	nvkm_vmm_unref(&mmu->vmm);
    413 
    414 	nvkm_mmu_ptc_fini(mmu);
    415 	return mmu;
    416 }
    417 
    418 static const struct nvkm_subdev_func
    419 nvkm_mmu = {
    420 	.dtor = nvkm_mmu_dtor,
    421 	.oneinit = nvkm_mmu_oneinit,
    422 	.init = nvkm_mmu_init,
    423 };
    424 
    425 void
    426 nvkm_mmu_ctor(const struct nvkm_mmu_func *func, struct nvkm_device *device,
    427 	      int index, struct nvkm_mmu *mmu)
    428 {
    429 	nvkm_subdev_ctor(&nvkm_mmu, device, index, &mmu->subdev);
    430 	mmu->func = func;
    431 	mmu->dma_bits = func->dma_bits;
    432 	nvkm_mmu_ptc_init(mmu);
    433 	mmu->user.ctor = nvkm_ummu_new;
    434 	mmu->user.base = func->mmu.user;
    435 }
    436 
    437 int
    438 nvkm_mmu_new_(const struct nvkm_mmu_func *func, struct nvkm_device *device,
    439 	      int index, struct nvkm_mmu **pmmu)
    440 {
    441 	if (!(*pmmu = kzalloc(sizeof(**pmmu), GFP_KERNEL)))
    442 		return -ENOMEM;
    443 	nvkm_mmu_ctor(func, device, index, *pmmu);
    444 	return 0;
    445 }
    446