drivers/gpu/drm/i915/display/intel_fbc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/display/intel_fbc.c
Extension
.c
Size
68542 bytes
Lines
2481
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 intel_fbc_funcs {
	void (*activate)(struct intel_fbc *fbc);
	void (*deactivate)(struct intel_fbc *fbc);
	bool (*is_active)(struct intel_fbc *fbc);
	bool (*is_compressing)(struct intel_fbc *fbc);
	void (*nuke)(struct intel_fbc *fbc);
	void (*program_cfb)(struct intel_fbc *fbc);
	void (*set_false_color)(struct intel_fbc *fbc, bool enable);
};

struct intel_fbc_state {
	struct intel_plane *plane;
	unsigned int cfb_stride;
	unsigned int cfb_size;
	unsigned int fence_y_offset;
	u16 override_cfb_stride;
	u16 interval;
	s8 fence_id;
	struct drm_rect dirty_rect;
};

struct intel_fbc {
	struct intel_display *display;
	const struct intel_fbc_funcs *funcs;

	/* This is always the outer lock when overlapping with stolen_lock */
	struct mutex lock;
	unsigned int busy_bits;

	struct intel_stolen_node *compressed_fb;
	struct intel_stolen_node *compressed_llb;

	enum intel_fbc_id id;

	u8 limit;

	bool false_color;

	bool active;
	bool activated;
	bool flip_pending;

	bool underrun_detected;
	struct work_struct underrun_work;

	/*
	 * This structure contains everything that's relevant to program the
	 * hardware registers. When we want to figure out if we need to disable
	 * and re-enable FBC for a new configuration we just check if there's
	 * something different in the struct. The genx_fbc_activate functions
	 * are supposed to read from it in order to program the registers.
	 */
	struct intel_fbc_state state;
	const char *no_fbc_reason;
};

static struct intel_fbc *intel_fbc_for_pipe(struct intel_display *display, enum pipe pipe)
{
	struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
	struct intel_plane *primary = NULL;

	primary = to_intel_plane(crtc->base.primary);

	if (drm_WARN_ON(display->drm, !primary))
		return NULL;

	return primary->fbc;
}

/* plane stride in pixels */
static unsigned int intel_fbc_plane_stride(const struct intel_plane_state *plane_state)
{
	const struct drm_framebuffer *fb = plane_state->hw.fb;
	unsigned int stride;

	stride = plane_state->view.color_plane[0].mapping_stride;
	if (!drm_rotation_90_or_270(plane_state->hw.rotation))
		stride /= fb->format->cpp[0];

	return stride;
}

static unsigned int intel_fbc_cfb_cpp(const struct intel_plane_state *plane_state)
{
	const struct drm_framebuffer *fb = plane_state->hw.fb;
	unsigned int cpp = fb->format->cpp[0];

	return max(cpp, 4);
}

Annotation

Implementation Notes