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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/display/intel_display_irq.c
Extension
.c
Size
77395 bytes
Lines
2669
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 pipe_fault_handler {
	bool (*handle)(struct intel_crtc *crtc, enum plane_id plane_id);
	u32 fault;
	enum plane_id plane_id;
};

static bool handle_plane_fault(struct intel_crtc *crtc, enum plane_id plane_id)
{
	struct intel_display *display = to_intel_display(crtc);
	struct intel_plane_error error = {};
	struct intel_plane *plane;

	plane = intel_crtc_get_plane(crtc, plane_id);
	if (!plane || !plane->capture_error)
		return false;

	plane->capture_error(crtc, plane, &error);

	drm_err_ratelimited(display->drm,
			    "[CRTC:%d:%s][PLANE:%d:%s] fault (CTL=0x%x, SURF=0x%x, SURFLIVE=0x%x)\n",
			    crtc->base.base.id, crtc->base.name,
			    plane->base.base.id, plane->base.name,
			    error.ctl, error.surf, error.surflive);

	return true;
}

static void intel_pipe_fault_irq_handler(struct intel_display *display,
					 const struct pipe_fault_handler *handlers,
					 enum pipe pipe, u32 fault_errors)
{
	struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
	const struct pipe_fault_handler *handler;

	for (handler = handlers; handler && handler->fault; handler++) {
		if ((fault_errors & handler->fault) == 0)
			continue;

		if (handler->handle(crtc, handler->plane_id))
			fault_errors &= ~handler->fault;
	}

	WARN_ONCE(fault_errors, "[CRTC:%d:%s] unreported faults 0x%x\n",
		  crtc->base.base.id, crtc->base.name, fault_errors);
}

static void
intel_handle_vblank(struct intel_display *display, enum pipe pipe)
{
	struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);

	drm_crtc_handle_vblank(&crtc->base);
}

/**
 * ilk_update_display_irq - update DEIMR
 * @display: display device
 * @interrupt_mask: mask of interrupt bits to update
 * @enabled_irq_mask: mask of interrupt bits to enable
 */
void ilk_update_display_irq(struct intel_display *display,
			    u32 interrupt_mask, u32 enabled_irq_mask)
{
	u32 new_val;

	lockdep_assert_held(&display->irq.lock);
	drm_WARN_ON(display->drm, enabled_irq_mask & ~interrupt_mask);

	new_val = display->irq.ilk_de_imr_mask;
	new_val &= ~interrupt_mask;
	new_val |= (~enabled_irq_mask & interrupt_mask);

	if (new_val != display->irq.ilk_de_imr_mask &&
	    !drm_WARN_ON(display->drm, !intel_parent_irq_enabled(display))) {
		display->irq.ilk_de_imr_mask = new_val;
		intel_de_write(display, DEIMR, display->irq.ilk_de_imr_mask);
		intel_de_posting_read(display, DEIMR);
	}
}

void ilk_enable_display_irq(struct intel_display *display, u32 bits)
{
	ilk_update_display_irq(display, bits, bits);
}

void ilk_disable_display_irq(struct intel_display *display, u32 bits)
{
	ilk_update_display_irq(display, bits, 0);
}

Annotation

Implementation Notes