Commit 65270a65 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/core/mm: allow allocation to be confined to a specific slice of heap



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 13dfe128
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -115,7 +115,7 @@ nouveau_gpuobj_create_(struct nouveau_object *parent,
	gpuobj->size = size;

	if (heap) {
		ret = nouveau_mm_head(heap, 1, size, size,
		ret = nouveau_mm_head(heap, 0, 1, size, size,
				      max(align, (u32)1), &gpuobj->node);
		if (ret)
			return ret;
+15 −5
Original line number Diff line number Diff line
@@ -98,6 +98,7 @@ region_head(struct nouveau_mm *mm, struct nouveau_mm_node *a, u32 size)

	b->offset = a->offset;
	b->length = size;
	b->heap   = a->heap;
	b->type   = a->type;
	a->offset += size;
	a->length -= size;
@@ -108,8 +109,8 @@ region_head(struct nouveau_mm *mm, struct nouveau_mm_node *a, u32 size)
}

int
nouveau_mm_head(struct nouveau_mm *mm, u8 type, u32 size_max, u32 size_min,
		u32 align, struct nouveau_mm_node **pnode)
nouveau_mm_head(struct nouveau_mm *mm, u8 heap, u8 type, u32 size_max,
		u32 size_min, u32 align, struct nouveau_mm_node **pnode)
{
	struct nouveau_mm_node *prev, *this, *next;
	u32 mask = align - 1;
@@ -119,6 +120,10 @@ nouveau_mm_head(struct nouveau_mm *mm, u8 type, u32 size_max, u32 size_min,
	BUG_ON(type == NVKM_MM_TYPE_NONE || type == NVKM_MM_TYPE_HOLE);

	list_for_each_entry(this, &mm->free, fl_entry) {
		if (unlikely(heap != NVKM_MM_HEAP_ANY)) {
			if (this->heap != heap)
				continue;
		}
		e = this->offset + this->length;
		s = this->offset;

@@ -167,6 +172,7 @@ region_tail(struct nouveau_mm *mm, struct nouveau_mm_node *a, u32 size)
	a->length -= size;
	b->offset  = a->offset + a->length;
	b->length  = size;
	b->heap    = a->heap;
	b->type    = a->type;

	list_add(&b->nl_entry, &a->nl_entry);
@@ -176,8 +182,8 @@ region_tail(struct nouveau_mm *mm, struct nouveau_mm_node *a, u32 size)
}

int
nouveau_mm_tail(struct nouveau_mm *mm, u8 type, u32 size_max, u32 size_min,
		u32 align, struct nouveau_mm_node **pnode)
nouveau_mm_tail(struct nouveau_mm *mm, u8 heap, u8 type, u32 size_max,
		u32 size_min, u32 align, struct nouveau_mm_node **pnode)
{
	struct nouveau_mm_node *prev, *this, *next;
	u32 mask = align - 1;
@@ -188,6 +194,10 @@ nouveau_mm_tail(struct nouveau_mm *mm, u8 type, u32 size_max, u32 size_min,
		u32 e = this->offset + this->length;
		u32 s = this->offset;
		u32 c = 0, a;
		if (unlikely(heap != NVKM_MM_HEAP_ANY)) {
			if (this->heap != heap)
				continue;
		}

		prev = node(this, prev);
		if (prev && prev->type != type)
@@ -262,7 +272,7 @@ nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block)

	list_add_tail(&node->nl_entry, &mm->nodes);
	list_add_tail(&node->fl_entry, &mm->free);
	mm->heap_nodes++;
	node->heap = ++mm->heap_nodes;
	return 0;
}

+6 −4
Original line number Diff line number Diff line
@@ -6,6 +6,8 @@ struct nouveau_mm_node {
	struct list_head fl_entry;
	struct list_head rl_entry;

#define NVKM_MM_HEAP_ANY 0x00
	u8  heap;
#define NVKM_MM_TYPE_NONE 0x00
#define NVKM_MM_TYPE_HOLE 0xff
	u8  type;
@@ -29,10 +31,10 @@ nouveau_mm_initialised(struct nouveau_mm *mm)

int  nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block);
int  nouveau_mm_fini(struct nouveau_mm *);
int  nouveau_mm_head(struct nouveau_mm *, u8 type, u32 size_max, u32 size_min,
		     u32 align, struct nouveau_mm_node **);
int  nouveau_mm_tail(struct nouveau_mm *, u8 type, u32 size_max, u32 size_min,
		     u32 align, struct nouveau_mm_node **);
int  nouveau_mm_head(struct nouveau_mm *, u8 heap, u8 type, u32 size_max,
		     u32 size_min, u32 align, struct nouveau_mm_node **);
int  nouveau_mm_tail(struct nouveau_mm *, u8 heap, u8 type, u32 size_max,
		     u32 size_min, u32 align, struct nouveau_mm_node **);
void nouveau_mm_free(struct nouveau_mm *, struct nouveau_mm_node **);

#endif
+1 −1
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ nv20_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
{
	u32 tiles = DIV_ROUND_UP(size, 0x40);
	u32 tags  = round_up(tiles / pfb->ram->parts, 0x40);
	if (!nouveau_mm_head(&pfb->tags, 1, tags, tags, 1, &tile->tag)) {
	if (!nouveau_mm_head(&pfb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
		if (!(flags & 2)) tile->zcomp = 0x00000000; /* Z16 */
		else              tile->zcomp = 0x04000000; /* Z24S8 */
		tile->zcomp |= tile->tag->offset;
+1 −1
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ nv25_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
{
	u32 tiles = DIV_ROUND_UP(size, 0x40);
	u32 tags  = round_up(tiles / pfb->ram->parts, 0x40);
	if (!nouveau_mm_head(&pfb->tags, 1, tags, tags, 1, &tile->tag)) {
	if (!nouveau_mm_head(&pfb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
		if (!(flags & 2)) tile->zcomp = 0x00100000; /* Z16 */
		else              tile->zcomp = 0x00200000; /* Z24S8 */
		tile->zcomp |= tile->tag->offset;
Loading