drivers/gpu/drm/xe/xe_guc_buf.c

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

File Facts

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

// SPDX-License-Identifier: MIT
/*
 * Copyright © 2024 Intel Corporation
 */

#include <linux/cleanup.h>
#include <drm/drm_managed.h>

#include "xe_bo.h"
#include "xe_gt_printk.h"
#include "xe_guc.h"
#include "xe_guc_buf.h"
#include "xe_sa.h"

#define XE_GUC_BUF_CACHE_DEFAULT_SIZE SZ_8K

static struct xe_guc *cache_to_guc(struct xe_guc_buf_cache *cache)
{
	return container_of(cache, struct xe_guc, buf);
}

static struct xe_gt *cache_to_gt(struct xe_guc_buf_cache *cache)
{
	return guc_to_gt(cache_to_guc(cache));
}

static int guc_buf_cache_init(struct xe_guc_buf_cache *cache, u32 size)
{
	struct xe_gt *gt = cache_to_gt(cache);
	struct xe_sa_manager *sam;

	sam = __xe_sa_bo_manager_init(gt_to_tile(gt), size, 0, sizeof(u32), 0);
	if (IS_ERR(sam))
		return PTR_ERR(sam);
	cache->sam = sam;

	xe_gt_dbg(gt, "reusable buffer with %u dwords at %#x for %ps\n",
		  xe_guc_buf_cache_dwords(cache), xe_bo_ggtt_addr(sam->bo),
		  __builtin_return_address(0));
	return 0;
}

/**
 * xe_guc_buf_cache_init() - Initialize the GuC Buffer Cache.
 * @cache: the &xe_guc_buf_cache to initialize
 *
 * The Buffer Cache allows to obtain a reusable buffer that can be used to pass
 * data to GuC or read data from GuC without a need to create a ad-hoc allocation.
 *
 * Return: 0 on success or a negative error code on failure.
 */
int xe_guc_buf_cache_init(struct xe_guc_buf_cache *cache)
{
	return guc_buf_cache_init(cache, XE_GUC_BUF_CACHE_DEFAULT_SIZE);
}

/**
 * xe_guc_buf_cache_init_with_size() - Initialize the GuC Buffer Cache.
 * @cache: the &xe_guc_buf_cache to initialize
 * @size: size in bytes
 *
 * Like xe_guc_buf_cache_init(), except it allows the caller to make the cache
 * buffer larger, allowing to accommodate larger objects.
 *
 * Return: 0 on success or a negative error code on failure.
 */
int xe_guc_buf_cache_init_with_size(struct xe_guc_buf_cache *cache, u32 size)
{
	return guc_buf_cache_init(cache, max(XE_GUC_BUF_CACHE_DEFAULT_SIZE, size));
}

/**
 * xe_guc_buf_cache_dwords() - Number of dwords the GuC Buffer Cache supports.
 * @cache: the &xe_guc_buf_cache to query
 *
 * Return: a size of the largest reusable buffer (in dwords)
 */
u32 xe_guc_buf_cache_dwords(struct xe_guc_buf_cache *cache)
{
	return cache->sam ? cache->sam->base.size / sizeof(u32) : 0;
}

/**
 * xe_guc_buf_reserve() - Reserve a new sub-allocation.
 * @cache: the &xe_guc_buf_cache where reserve sub-allocation
 * @dwords: the requested size of the buffer in dwords
 *
 * Use xe_guc_buf_is_valid() to check if returned buffer reference is valid.
 * Must use xe_guc_buf_release() to release a sub-allocation.
 *

Annotation

Implementation Notes