drivers/gpu/drm/i915/i915_bo.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/i915_bo.c
Extension
.c
Size
7227 bytes
Lines
271
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 (tiling == I915_TILING_X) {
			mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED;
		} else if (tiling == I915_TILING_Y) {
			drm_dbg_kms(&i915->drm,
				    "No Y tiling for legacy addfb\n");
			return -EINVAL;
		}
	}

	/*
	 * gen2/3 display engine uses the fence if present,
	 * so the tiling mode must match the fb modifier exactly.
	 */
	if (GRAPHICS_VER(i915) < 4 &&
	    tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) {
		drm_dbg_kms(&i915->drm,
			    "tiling_mode must match fb modifier exactly on gen2/3\n");
		return -EINVAL;
	}

	/*
	 * If there's a fence, enforce that
	 * the fb pitch and fence stride match.
	 */
	if (tiling != I915_TILING_NONE && mode_cmd->pitches[0] != stride) {
		drm_dbg_kms(&i915->drm,
			    "pitch (%d) must match tiling stride (%d)\n",
			    mode_cmd->pitches[0], stride);
		return -EINVAL;
	}

	return 0;
}

static void i915_bo_framebuffer_fini(struct drm_gem_object *obj)
{
	/* Nothing to do for i915 */
}

static struct drm_gem_object *
i915_bo_framebuffer_lookup(struct drm_device *drm,
			   struct drm_file *filp,
			   const struct drm_mode_fb_cmd2 *mode_cmd)
{
	struct drm_i915_private *i915 = to_i915(drm);
	struct drm_i915_gem_object *obj;

	obj = i915_gem_object_lookup(filp, mode_cmd->handles[0]);
	if (!obj)
		return ERR_PTR(-ENOENT);

	/* object is backed with LMEM for discrete */
	if (HAS_LMEM(i915) && !i915_gem_object_can_migrate(obj, INTEL_REGION_LMEM_0)) {
		/* object is "remote", not in local memory */
		i915_gem_object_put(obj);
		drm_dbg_kms(&i915->drm, "framebuffer must reside in local memory\n");
		return ERR_PTR(-EREMOTE);
	}

	return intel_bo_to_drm_bo(obj);
}

#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
static u32 i915_bo_fbdev_pitch_align(u32 stride)
{
	return ALIGN(stride, 64);
}

bool i915_bo_fbdev_prefer_stolen(struct drm_i915_private *i915, unsigned int size)
{
	/* Skip stolen on MTL as Wa_22018444074 mitigation. */
	if (IS_METEORLAKE(i915))
		return false;

	/*
	 * If the FB is too big, just don't use it since fbdev is not very
	 * important and we should probably use that space with FBC or other
	 * features.
	 */
	return i915->dsm.usable_size >= size * 2;
}

static struct drm_gem_object *i915_bo_fbdev_create(struct drm_device *drm, int size)
{
	struct drm_i915_private *i915 = to_i915(drm);
	struct drm_i915_gem_object *obj;

	obj = ERR_PTR(-ENODEV);
	if (HAS_LMEM(i915)) {
		obj = i915_gem_object_create_lmem(i915, size,

Annotation

Implementation Notes