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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/display/intel_frontbuffer.c
Extension
.c
Size
8675 bytes
Lines
242
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

#include <drm/drm_gem.h>
#include <drm/drm_print.h>

#include "intel_display_trace.h"
#include "intel_display_types.h"
#include "intel_dp.h"
#include "intel_drrs.h"
#include "intel_fbc.h"
#include "intel_frontbuffer.h"
#include "intel_parent.h"
#include "intel_psr.h"
#include "intel_tdf.h"

/**
 * frontbuffer_flush - flush frontbuffer
 * @display: display device
 * @frontbuffer_bits: frontbuffer plane tracking bits
 * @origin: which operation caused the flush
 *
 * This function gets called every time rendering on the given planes has
 * completed and frontbuffer caching can be started again. Flushes will get
 * delayed if they're blocked by some outstanding asynchronous rendering.
 *
 * Can be called without any locks held.
 */
static void frontbuffer_flush(struct intel_display *display,
			      unsigned int frontbuffer_bits,
			      enum fb_op_origin origin)
{
	/* Delay flushing when rings are still busy.*/
	spin_lock(&display->fb_tracking.lock);
	frontbuffer_bits &= ~display->fb_tracking.busy_bits;
	spin_unlock(&display->fb_tracking.lock);

	if (!frontbuffer_bits)
		return;

	trace_intel_frontbuffer_flush(display, frontbuffer_bits, origin);

	might_sleep();
	intel_td_flush(display);
	intel_drrs_flush(display, frontbuffer_bits);
	intel_psr_flush(display, frontbuffer_bits, origin);
	intel_fbc_flush(display, frontbuffer_bits, origin);
}

/**
 * intel_frontbuffer_flip - synchronous frontbuffer flip
 * @display: display device
 * @frontbuffer_bits: frontbuffer plane tracking bits
 *
 * This function gets called after scheduling a flip on @obj. This is for
 * synchronous plane updates which will happen on the next vblank and which will
 * not get delayed by pending gpu rendering.
 *
 * Can be called without any locks held.
 */
void intel_frontbuffer_flip(struct intel_display *display,
			    unsigned frontbuffer_bits)
{
	spin_lock(&display->fb_tracking.lock);
	/* Remove stale busy bits due to the old buffer. */
	display->fb_tracking.busy_bits &= ~frontbuffer_bits;
	spin_unlock(&display->fb_tracking.lock);

	frontbuffer_flush(display, frontbuffer_bits, ORIGIN_FLIP);
}

void __intel_frontbuffer_invalidate(struct intel_frontbuffer *front,
				    enum fb_op_origin origin,
				    unsigned int frontbuffer_bits)
{
	struct intel_display *display = front->display;

	if (origin == ORIGIN_CS) {
		spin_lock(&display->fb_tracking.lock);
		display->fb_tracking.busy_bits |= frontbuffer_bits;
		spin_unlock(&display->fb_tracking.lock);
	}

	trace_intel_frontbuffer_invalidate(display, frontbuffer_bits, origin);

	might_sleep();
	intel_psr_invalidate(display, frontbuffer_bits, origin);
	intel_drrs_invalidate(display, frontbuffer_bits);
	intel_fbc_invalidate(display, frontbuffer_bits, origin);
}

void __intel_frontbuffer_flush(struct intel_frontbuffer *front,
			       enum fb_op_origin origin,

Annotation

Implementation Notes