Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7b865663 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau: directly handle comptag allocation



Another transition step to allow finer-grained patches transitioning to
new MMU backends.

Old backends will continue operate as before (accessing nvkm_mem::tag),
and new backends will get a reference to the tags allocated here.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent bd275f1d
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -22,8 +22,6 @@ struct nvkm_ltc {
	u32 zbc_depth[NVKM_LTC_MAX_ZBC_CNT];
};

int nvkm_ltc_tags_alloc(struct nvkm_ltc *, u32 count, struct nvkm_mm_node **);
void nvkm_ltc_tags_free(struct nvkm_ltc *, struct nvkm_mm_node **);
void nvkm_ltc_tags_clear(struct nvkm_device *, u32 first, u32 count);

int nvkm_ltc_zbc_color_get(struct nvkm_ltc *, int index, const u32[4]);
+36 −2
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@
#include "nouveau_drv.h"
#include "nouveau_bo.h"

#include <subdev/ltc.h>

#include <drm/ttm/ttm_bo_driver.h>

int
@@ -44,6 +46,8 @@ nouveau_mem_fini(struct nouveau_mem *mem)
		nvkm_vm_unmap(&mem->vma[0]);
		nvkm_vm_put(&mem->vma[0]);
	}
	nvkm_memory_tags_put(&mem->memory, nvxx_device(&mem->cli->device),
			     &mem->tags);
}

int
@@ -74,17 +78,47 @@ int
nouveau_mem_vram(struct ttm_mem_reg *reg, bool contig, u8 page)
{
	struct nouveau_mem *mem = nouveau_mem(reg);
	struct nvkm_ram *ram = nvxx_fb(&mem->cli->device)->ram;
	struct nouveau_cli *cli = mem->cli;
	struct nvkm_device *device = nvxx_device(&cli->device);
	struct nvkm_ram *ram = nvxx_fb(&cli->device)->ram;
	u64 size = ALIGN(reg->num_pages << PAGE_SHIFT, 1 << page);
	int ret;

	mem->mem.page = page;
	mem->_mem->memory = &mem->memory;

	if (cli->device.info.chipset < 0xc0 && mem->comp) {
		if (page == 16) {
			ret = nvkm_memory_tags_get(mem->_mem->memory, device,
						   size >> page, NULL,
						   &mem->tags);
			WARN_ON(ret);
		}
		if (!mem->tags || !mem->tags->mn)
			mem->comp = 0;
	} else
	if (cli->device.info.chipset >= 0xc0 &&
	    gf100_pte_storage_type_map[mem->kind] != mem->kind) {
		if (page == 17) {
			ret = nvkm_memory_tags_get(mem->_mem->memory, device,
						   size >> page,
						   nvkm_ltc_tags_clear,
						   &mem->tags);
			WARN_ON(ret);
		}
		if (!mem->tags || !mem->tags->mn)
			mem->kind = gf100_pte_storage_type_map[mem->kind];
	}

	ret = ram->func->get(ram, size, 1 << page, contig ? 0 : 1 << page,
			     (mem->comp << 8) | mem->kind, &mem->_mem);
	if (ret)
	if (ret) {
		nvkm_memory_tags_put(mem->_mem->memory, device, &mem->tags);
		return ret;
	}

	if (mem->tags && mem->tags->mn)
		mem->_mem->tag = mem->tags->mn;

	reg->start = mem->_mem->offset >> PAGE_SHIFT;
	return ret;
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ struct nouveau_mem {
	struct nvkm_vma bar_vma;

	struct nvkm_memory memory;
	struct nvkm_tags *tags;
};

enum nvif_vmm_get {
+0 −20
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@
#include <subdev/bios/timing.h>
#include <subdev/clk.h>
#include <subdev/clk/pll.h>
#include <subdev/ltc.h>

struct gf100_ramfuc {
	struct ramfuc base;
@@ -423,7 +422,6 @@ gf100_ram_tidy(struct nvkm_ram *base)
void
gf100_ram_put(struct nvkm_ram *ram, struct nvkm_mem **pmem)
{
	struct nvkm_ltc *ltc = ram->fb->subdev.device->ltc;
	struct nvkm_mem *mem = *pmem;

	*pmem = NULL;
@@ -431,8 +429,6 @@ gf100_ram_put(struct nvkm_ram *ram, struct nvkm_mem **pmem)
		return;

	mutex_lock(&ram->fb->subdev.mutex);
	if (mem->tag)
		nvkm_ltc_tags_free(ltc, &mem->tag);
	__nv50_ram_put(ram, mem);
	mutex_unlock(&ram->fb->subdev.mutex);

@@ -443,14 +439,11 @@ int
gf100_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin,
	      u32 memtype, struct nvkm_mem **pmem)
{
	struct nvkm_device *device = ram->fb->subdev.device;
	struct nvkm_ltc *ltc = ram->fb->subdev.device->ltc;
	struct nvkm_mm *mm = &ram->vram;
	struct nvkm_mm_node **node, *r;
	struct nvkm_mem *mem;
	int type = (memtype & 0x0ff);
	int back = (memtype & 0x800);
	const bool comp = gf100_pte_storage_type_map[type] != type;
	int ret;

	size  >>= NVKM_RAM_MM_SHIFT;
@@ -466,19 +459,6 @@ gf100_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin,
	mem->size = size;

	mutex_lock(&ram->fb->subdev.mutex);
	if (comp) {
		/* compression only works with lpages */
		if (align == (1 << (17 - NVKM_RAM_MM_SHIFT))) {
			int n = size >> 5;
			if (!nvkm_ltc_tags_alloc(ltc, n, &mem->tag)) {
				nvkm_ltc_tags_clear(device, mem->tag->offset,
							    mem->tag->length);
			}
		}

		if (unlikely(!mem->tag))
			type = gf100_pte_storage_type_map[type];
	}
	mem->memtype = type;

	node = &mem->mem;
+0 −15
Original line number Diff line number Diff line
@@ -502,7 +502,6 @@ __nv50_ram_put(struct nvkm_ram *ram, struct nvkm_mem *mem)
		next = node->next;
		nvkm_mm_free(&ram->vram, &node);
	}
	nvkm_mm_free(&ram->fb->tags, &mem->tag);
}

void
@@ -526,7 +525,6 @@ nv50_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin,
	     u32 memtype, struct nvkm_mem **pmem)
{
	struct nvkm_mm *heap = &ram->vram;
	struct nvkm_mm *tags = &ram->fb->tags;
	struct nvkm_mm_node **node, *r;
	struct nvkm_mem *mem;
	int comp = (memtype & 0x300) >> 8;
@@ -543,19 +541,6 @@ nv50_ram_get(struct nvkm_ram *ram, u64 size, u32 align, u32 ncmin,
		return -ENOMEM;

	mutex_lock(&ram->fb->subdev.mutex);
	if (comp) {
		if (align == (1 << (16 - NVKM_RAM_MM_SHIFT))) {
			int n = (max >> 4) * comp;

			ret = nvkm_mm_head(tags, 0, 1, n, n, 1, &mem->tag);
			if (ret)
				mem->tag = NULL;
		}

		if (unlikely(!mem->tag))
			comp = 0;
	}

	mem->memtype = (comp << 7) | type;
	mem->size = max;

Loading