drivers/gpu/drm/xe/xe_hw_error.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/xe/xe_hw_error.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_hw_error.c
Extension
.c
Size
17349 bytes
Lines
566
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

for_each_set_bit(err_bit, &fw_err, HEC_UNCORR_FW_ERR_BITS) {
			drm_err_ratelimited(&xe->drm, HW_ERR
					    "HEC FW %s %s reported, bit[%d] is set\n",
					     hec_uncorrected_fw_errors[err_bit], severity_str,
					     err_bit);

			schedule_work(&tile->csc_hw_error_work);
		}
	}

	xe_mmio_write32(mmio, HEC_UNCORR_ERR_STATUS(base), err_src);
}

static void log_hw_error(struct xe_tile *tile, const char *name,
			 const enum drm_xe_ras_error_severity severity)
{
	const char *severity_str = error_severity[severity];
	struct xe_device *xe = tile_to_xe(tile);

	if (severity == DRM_XE_RAS_ERR_SEV_CORRECTABLE)
		drm_warn(&xe->drm, HW_ERR "%s %s detected\n", name, severity_str);
	else
		drm_err_ratelimited(&xe->drm, HW_ERR "%s %s detected\n", name, severity_str);
}

static void log_gt_err(struct xe_tile *tile, const char *name, int i, u32 err,
		       const enum drm_xe_ras_error_severity severity)
{
	const char *severity_str = error_severity[severity];
	struct xe_device *xe = tile_to_xe(tile);

	if (severity == DRM_XE_RAS_ERR_SEV_CORRECTABLE)
		drm_warn(&xe->drm, HW_ERR "%s %s detected, ERROR_STAT_GT_VECTOR%d:0x%08x\n",
			 name, severity_str, i, err);
	else
		drm_err_ratelimited(&xe->drm, HW_ERR "%s %s detected, ERROR_STAT_GT_VECTOR%d:0x%08x\n",
				    name, severity_str, i, err);
}

static void log_soc_error(struct xe_tile *tile, const char * const *reg_info,
			  const enum drm_xe_ras_error_severity severity, u32 err_bit, u32 index)
{
	const char *severity_str = error_severity[severity];
	struct xe_device *xe = tile_to_xe(tile);
	struct xe_drm_ras *ras = &xe->ras;
	struct xe_drm_ras_counter *info = ras->info[severity];
	const char *name;

	name = reg_info[err_bit];

	if (strcmp(name, "Undefined")) {
		if (severity == DRM_XE_RAS_ERR_SEV_CORRECTABLE)
			drm_warn(&xe->drm, HW_ERR "%s SOC %s detected", name, severity_str);
		else
			drm_err_ratelimited(&xe->drm, HW_ERR "%s SOC %s detected", name, severity_str);
		atomic_inc(&info[index].counter);
	}
}

static void gt_hw_error_handler(struct xe_tile *tile, const enum hardware_error hw_err,
				u32 error_id)
{
	const enum drm_xe_ras_error_severity severity = hw_err_to_severity(hw_err);
	struct xe_device *xe = tile_to_xe(tile);
	struct xe_drm_ras *ras = &xe->ras;
	struct xe_drm_ras_counter *info = ras->info[severity];
	struct xe_mmio *mmio = &tile->mmio;
	unsigned long err_stat = 0;
	int i;

	if (xe->info.platform != XE_PVC)
		return;

	if (hw_err == HARDWARE_ERROR_NONFATAL) {
		atomic_inc(&info[error_id].counter);
		log_hw_error(tile, info[error_id].name, severity);
		return;
	}

	for (i = 0; i < PVC_GT_VECTOR_LEN(hw_err); i++) {
		u32 vector, val;

		vector = xe_mmio_read32(mmio, ERR_STAT_GT_VECTOR_REG(hw_err, i));
		if (!vector)
			continue;

		switch (i) {
		case ERR_STAT_GT_VECTOR0:
		case ERR_STAT_GT_VECTOR1: {
			u32 errbit;

Annotation

Implementation Notes