drivers/gpu/drm/i915/gt/intel_gt.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/gt/intel_gt.c
Extension
.c
Size
26405 bytes
Lines
1067
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 (fault & RING_FAULT_VALID) {
			gt_dbg(gt, "Unexpected fault\n"
			       "\tAddr: 0x%08x\n"
			       "\tAddress space: %s\n"
			       "\tSource ID: %d\n"
			       "\tType: %d\n",
			       fault & RING_FAULT_VADDR_MASK,
			       fault & RING_FAULT_GTTSEL_MASK ?
			       "GGTT" : "PPGTT",
			       REG_FIELD_GET(RING_FAULT_SRCID_MASK, fault),
			       REG_FIELD_GET(RING_FAULT_FAULT_TYPE_MASK, fault));
		}
	}
}

static void gen8_report_fault(struct intel_gt *gt, u32 fault,
			      u32 fault_data0, u32 fault_data1)
{
	u64 fault_addr;

	fault_addr = ((u64)(fault_data1 & FAULT_VA_HIGH_BITS) << 44) |
		((u64)fault_data0 << 12);

	gt_dbg(gt, "Unexpected fault\n"
	       "\tAddr: 0x%08x_%08x\n"
	       "\tAddress space: %s\n"
	       "\tEngine ID: %d\n"
	       "\tSource ID: %d\n"
	       "\tType: %d\n",
	       upper_32_bits(fault_addr), lower_32_bits(fault_addr),
	       fault_data1 & FAULT_GTT_SEL ? "GGTT" : "PPGTT",
	       REG_FIELD_GET(RING_FAULT_ENGINE_ID_MASK, fault),
	       REG_FIELD_GET(RING_FAULT_SRCID_MASK, fault),
	       REG_FIELD_GET(RING_FAULT_FAULT_TYPE_MASK, fault));
}

static void xehp_check_faults(struct intel_gt *gt)
{
	u32 fault;

	/*
	 * Although the fault register now lives in an MCR register range,
	 * the GAM registers are special and we only truly need to read
	 * the "primary" GAM instance rather than handling each instance
	 * individually.  intel_gt_mcr_read_any() will automatically steer
	 * toward the primary instance.
	 */
	fault = intel_gt_mcr_read_any(gt, XEHP_RING_FAULT_REG);
	if (fault & RING_FAULT_VALID)
		gen8_report_fault(gt, fault,
				  intel_gt_mcr_read_any(gt, XEHP_FAULT_TLB_DATA0),
				  intel_gt_mcr_read_any(gt, XEHP_FAULT_TLB_DATA1));
}

static void gen8_check_faults(struct intel_gt *gt)
{
	struct intel_uncore *uncore = gt->uncore;
	i915_reg_t fault_reg, fault_data0_reg, fault_data1_reg;
	u32 fault;

	if (GRAPHICS_VER(gt->i915) >= 12) {
		fault_reg = GEN12_RING_FAULT_REG;
		fault_data0_reg = GEN12_FAULT_TLB_DATA0;
		fault_data1_reg = GEN12_FAULT_TLB_DATA1;
	} else {
		fault_reg = GEN8_RING_FAULT_REG;
		fault_data0_reg = GEN8_FAULT_TLB_DATA0;
		fault_data1_reg = GEN8_FAULT_TLB_DATA1;
	}

	fault = intel_uncore_read(uncore, fault_reg);
	if (fault & RING_FAULT_VALID)
		gen8_report_fault(gt, fault,
				  intel_uncore_read(uncore, fault_data0_reg),
				  intel_uncore_read(uncore, fault_data1_reg));
}

void intel_gt_check_and_clear_faults(struct intel_gt *gt)
{
	struct drm_i915_private *i915 = gt->i915;

	/* From GEN8 onwards we only have one 'All Engine Fault Register' */
	if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 55))
		xehp_check_faults(gt);
	else if (GRAPHICS_VER(i915) >= 8)
		gen8_check_faults(gt);
	else if (GRAPHICS_VER(i915) >= 6)
		gen6_check_faults(gt);
	else
		return;

Annotation

Implementation Notes