drivers/gpu/drm/xe/xe_psmi.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_psmi.c
Extension
.c
Size
7364 bytes
Lines
295
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

ARRAY_SIZE(xe->psmi.capture_obj)) {
		/* smem should never be set */
		xe_assert(xe, id);

		bo = xe->psmi.capture_obj[id];
		if (bo) {
			psmi_free_object(bo);
			xe->psmi.capture_obj[id] = NULL;
		}
	}
}

static struct xe_bo *psmi_alloc_object(struct xe_device *xe,
				       unsigned int id, size_t bo_size)
{
	struct xe_tile *tile;

	xe_assert(xe, id);
	xe_assert(xe, bo_size);

	tile = &xe->tiles[id - 1];

	/* VRAM: Allocate GEM object for the capture buffer */
	return xe_bo_create_pin_range_novm(xe, tile, bo_size, 0, ~0ull,
					   ttm_bo_type_kernel,
					   XE_BO_FLAG_VRAM_IF_DGFX(tile) |
					   XE_BO_FLAG_PINNED |
					   XE_BO_FLAG_PINNED_LATE_RESTORE |
					   XE_BO_FLAG_NEEDS_CPU_ACCESS);
}

/*
 * Allocate PSMI capture buffer objects (via debugfs set function), based on
 * which regions the user has selected in region_mask.  @size: size in bytes
 * (should be power of 2)
 *
 * Always release/free the current buffer objects before attempting to allocate
 * new ones.  Size == 0 will free all current buffers.
 *
 * Note, we don't write any registers as the capture tool is already configuring
 * all PSMI registers itself via mmio space.
 */
static int psmi_resize_object(struct xe_device *xe, size_t size)
{
	unsigned long id, region_mask = xe->psmi.region_mask;
	struct xe_bo *bo = NULL;
	int err = 0;

	/* if resizing, free currently allocated buffers first */
	psmi_cleanup(xe);

	/* can set size to 0, in which case, now done */
	if (!size)
		return 0;

	for_each_set_bit(id, &region_mask,
			 ARRAY_SIZE(xe->psmi.capture_obj)) {
		/* smem should never be set */
		xe_assert(xe, id);

		bo = psmi_alloc_object(xe, id, size);
		if (IS_ERR(bo)) {
			err = PTR_ERR(bo);
			break;
		}
		xe->psmi.capture_obj[id] = bo;

		drm_info(&xe->drm,
			 "PSMI capture size requested: %zu bytes, allocated: %lu:%zu\n",
			 size, id, bo ? xe_bo_size(bo) : 0);
	}

	/* on error, reverse what was allocated */
	if (err)
		psmi_cleanup(xe);

	return err;
}

/*
 * Returns an address for the capture tool to use to find start of capture
 * buffer. Capture tool requires the capability to have a buffer allocated per
 * each tile (VRAM region), thus we return an address for each region.
 */
static int psmi_debugfs_capture_addr_show(struct seq_file *m, void *data)
{
	struct xe_device *xe = m->private;
	unsigned long id, region_mask;
	struct xe_bo *bo;
	u64 val;

Annotation

Implementation Notes