drivers/gpu/drm/xe/display/xe_fb_pin.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/display/xe_fb_pin.c
Extension
.c
Size
14101 bytes
Lines
508
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

struct fb_rotate_args {
	const struct i915_gtt_view *view;
	struct xe_bo *bo;
};

static void write_ggtt_rotated_node(struct xe_ggtt *ggtt, struct xe_ggtt_node *node,
				    u64 pte_flags, xe_ggtt_set_pte_fn write_pte, void *data)
{
	struct fb_rotate_args *args = data;
	struct xe_bo *bo = args->bo;
	const struct intel_rotation_info *rot_info = &args->view->rotated;
	u32 ggtt_ofs = xe_ggtt_node_addr(node);

	for (u32 i = 0; i < ARRAY_SIZE(rot_info->plane); i++)
		write_ggtt_rotated(ggtt, &ggtt_ofs, pte_flags, write_pte,
				   bo, rot_info->plane[i].offset,
				   rot_info->plane[i].width,
				   rot_info->plane[i].height,
				   rot_info->plane[i].src_stride,
				   rot_info->plane[i].dst_stride);
}

static int __xe_pin_fb_vma_ggtt(struct drm_gem_object *obj,
				const struct intel_fb_pin_params *pin_params,
				struct i915_vma *vma)
{
	const struct i915_gtt_view *view = pin_params->view;
	struct xe_bo *bo = gem_to_xe_bo(obj);
	struct xe_device *xe = to_xe_device(obj->dev);
	struct xe_tile *tile0 = xe_device_get_root_tile(xe);
	struct xe_ggtt *ggtt = tile0->mem.ggtt;
	u64 pte, size;
	u32 align;
	int ret = 0;

	/* TODO: Consider sharing framebuffer mapping?
	 * embed i915_vma inside intel_framebuffer
	 */
	guard(xe_pm_runtime_noresume)(xe);

	align = max(XE_PAGE_SIZE, pin_params->alignment);
	if (xe_bo_is_vram(bo) && xe->info.vram_flags & XE_VRAM_FLAGS_NEED64K)
		align = max(align, SZ_64K);

	/* Fast case, preallocated GGTT view? */
	if (bo->ggtt_node[tile0->id] && view->type == I915_GTT_VIEW_NORMAL) {
		vma->node = bo->ggtt_node[tile0->id];
		return 0;
	}

	/* TODO: Consider sharing framebuffer mapping?
	 * embed i915_vma inside intel_framebuffer
	 */
	if (view->type == I915_GTT_VIEW_NORMAL)
		size = xe_bo_size(bo);
	else
		/* display uses tiles instead of bytes here, so convert it back.. */
		size = intel_rotation_info_size(&view->rotated) * XE_PAGE_SIZE;

	pte = xe_ggtt_encode_pte_flags(ggtt, bo, xe_cache_pat_idx(xe, XE_CACHE_NONE));
	vma->node = xe_ggtt_insert_node_transform(ggtt, bo, pte,
						  ALIGN(size, align), align,
						  view->type == I915_GTT_VIEW_NORMAL ?
						  NULL : write_ggtt_rotated_node,
						  &(struct fb_rotate_args){view, bo});
	if (IS_ERR(vma->node))
		ret = PTR_ERR(vma->node);

	return ret;
}

static struct i915_vma *__xe_pin_fb_vma(struct drm_gem_object *obj, bool is_dpt,
					const struct intel_fb_pin_params *pin_params)
{
	struct xe_device *xe = to_xe_device(obj->dev);
	struct i915_vma *vma = kzalloc(sizeof(*vma), GFP_KERNEL);
	struct xe_bo *bo = gem_to_xe_bo(obj);
	struct xe_validation_ctx ctx;
	struct drm_exec exec;
	int ret = 0;

	/* We reject creating !SCANOUT fb's, so this is weird.. */
	drm_WARN_ON(bo->ttm.base.dev, !(bo->flags & XE_BO_FLAG_FORCE_WC));

	if (!vma)
		return ERR_PTR(-ENODEV);

	refcount_set(&vma->ref, 1);
	if (IS_DGFX(to_xe_device(bo->ttm.base.dev)) &&
	    pin_params->needs_cpu_lmem_access &&

Annotation

Implementation Notes