drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c
Extension
.c
Size
6310 bytes
Lines
234
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 i915_gem_ttm_pm_apply {
	struct i915_gem_apply_to_region base;
	bool allow_gpu : 1;
	bool backup_pinned : 1;
};

static int i915_ttm_backup(struct i915_gem_apply_to_region *apply,
			   struct drm_i915_gem_object *obj)
{
	struct i915_gem_ttm_pm_apply *pm_apply =
		container_of(apply, typeof(*pm_apply), base);
	struct ttm_buffer_object *bo = i915_gem_to_ttm(obj);
	struct ttm_buffer_object *backup_bo;
	struct drm_i915_private *i915 =
		container_of(bo->bdev, typeof(*i915), bdev);
	struct drm_i915_gem_object *backup;
	struct ttm_operation_ctx ctx = {};
	unsigned int flags;
	int err = 0;

	if (!i915_ttm_cpu_maps_iomem(bo->resource) || obj->ttm.backup)
		return 0;

	if (pm_apply->allow_gpu && i915_gem_object_evictable(obj))
		return ttm_bo_validate(bo, i915_ttm_sys_placement(), &ctx);

	if (!pm_apply->backup_pinned ||
	    (pm_apply->allow_gpu && (obj->flags & I915_BO_ALLOC_PM_EARLY)))
		return 0;

	if (obj->flags & I915_BO_ALLOC_PM_VOLATILE)
		return 0;

	/*
	 * It seems that we might have some framebuffers still pinned at this
	 * stage, but for such objects we might also need to deal with the CCS
	 * aux state. Make sure we force the save/restore of the CCS state,
	 * otherwise we might observe display corruption, when returning from
	 * suspend.
	 */
	flags = 0;
	if (i915_gem_object_needs_ccs_pages(obj)) {
		WARN_ON_ONCE(!i915_gem_object_is_framebuffer(obj));
		WARN_ON_ONCE(!pm_apply->allow_gpu);

		flags = I915_BO_ALLOC_CCS_AUX;
	}
	backup = i915_gem_object_create_region(i915->mm.regions[INTEL_REGION_SMEM],
					       obj->base.size, 0, flags);
	if (IS_ERR(backup))
		return PTR_ERR(backup);

	err = i915_gem_object_lock(backup, apply->ww);
	if (err)
		goto out_no_lock;

	backup_bo = i915_gem_to_ttm(backup);
	err = ttm_bo_populate(backup_bo, &ctx);
	if (err)
		goto out_no_populate;

	err = i915_gem_obj_copy_ttm(backup, obj, pm_apply->allow_gpu, false);
	if (err) {
		drm_err(&i915->drm,
			"Unable to copy from device to system memory, err:%pe\n",
			ERR_PTR(err));
		goto out_no_populate;
	}
	ttm_bo_wait_ctx(backup_bo, &ctx);

	obj->ttm.backup = backup;
	return 0;

out_no_populate:
	i915_gem_ww_unlock_single(backup);
out_no_lock:
	i915_gem_object_put(backup);

	return err;
}

static int i915_ttm_recover(struct i915_gem_apply_to_region *apply,
			    struct drm_i915_gem_object *obj)
{
	i915_ttm_backup_free(obj);
	return 0;
}

/**
 * i915_ttm_recover_region - Free the backup of all objects of a region

Annotation

Implementation Notes