drivers/gpu/drm/xe/xe_lmtt.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/xe/xe_lmtt.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_lmtt.c
Extension
.c
Size
15605 bytes
Lines
610
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (pt->level != 0) {
			err = __lmtt_alloc_range(lmtt, pt, offset, next);
			if (err)
				return err;
		}

		offset = next;
	}

	return 0;
}

static int lmtt_alloc_range(struct xe_lmtt *lmtt, unsigned int vfid, u64 start, u64 end)
{
	struct xe_lmtt_pt *pd = lmtt->pd;
	struct xe_lmtt_pt *pt;
	u64 pt_addr;
	u64 pde;
	int err;

	lmtt_assert(lmtt, pd->level > 0);
	lmtt_assert(lmtt, vfid <= lmtt->ops->lmtt_pte_num(pd->level));
	lmtt_assert(lmtt, IS_ALIGNED(start, lmtt_page_size(lmtt)));
	lmtt_assert(lmtt, IS_ALIGNED(end, lmtt_page_size(lmtt)));

	if (pd->entries[vfid])
		return -ENOTEMPTY;

	pt = lmtt_pt_alloc(lmtt, pd->level - 1);
	if (IS_ERR(pt))
		return PTR_ERR(pt);

	pt_addr = xe_bo_main_addr(pt->bo, XE_PAGE_SIZE);

	pde = lmtt->ops->lmtt_pte_encode(pt_addr, pd->level);

	lmtt_write_pte(lmtt, pd, pde, vfid);

	pd->entries[vfid] = pt;

	if (pt->level != 0) {
		err = __lmtt_alloc_range(lmtt, pt, start, end);
		if (err)
			goto out_free_pt;
	}

	return 0;

out_free_pt:
	lmtt_pt_free(pt);
	return err;
}

static struct xe_lmtt_pt *lmtt_leaf_pt(struct xe_lmtt *lmtt, unsigned int vfid, u64 addr)
{
	struct xe_lmtt_pt *pd = lmtt->pd;
	struct xe_lmtt_pt *pt;

	lmtt_assert(lmtt, vfid <= lmtt->ops->lmtt_pte_num(pd->level));
	pt = pd->entries[vfid];

	while (pt->level) {
		lmtt_assert(lmtt, lmtt->ops->lmtt_pte_index(addr, pt->level) <=
			    lmtt->ops->lmtt_pte_num(pt->level));

		pt = pt->entries[lmtt->ops->lmtt_pte_index(addr, pt->level)];

		addr >>= lmtt->ops->lmtt_pte_shift(pt->level);
	}

	lmtt_assert(lmtt, lmtt->ops->lmtt_pte_index(addr, pt->level) <=
		    lmtt->ops->lmtt_pte_num(pt->level));
	lmtt_assert(lmtt, pt->level != pd->level);
	lmtt_assert(lmtt, pt->level == 0);
	return pt;
}

static void lmtt_insert_bo(struct xe_lmtt *lmtt, unsigned int vfid, struct xe_bo *bo, u64 start)
{
	u64 page_size = lmtt_page_size(lmtt);
	struct xe_res_cursor cur;
	struct xe_lmtt_pt *pt;
	u64 addr, vram_offset;

	lmtt_assert(lmtt, IS_ALIGNED(start, page_size));
	lmtt_assert(lmtt, IS_ALIGNED(xe_bo_size(bo), page_size));
	lmtt_assert(lmtt, xe_bo_is_vram(bo));

	vram_offset = vram_region_gpu_offset(bo->ttm.resource);
	xe_res_first(bo->ttm.resource, 0, xe_bo_size(bo), &cur);

Annotation

Implementation Notes