drivers/gpu/drm/xe/xe_reg_sr.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_reg_sr.c
Extension
.c
Size
7545 bytes
Lines
313
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (!compatible_entries(pentry, e)) {
			ret = -EINVAL;
			goto fail;
		}

		pentry->clr_bits |= e->clr_bits;
		pentry->set_bits |= e->set_bits;
		pentry->read_mask |= e->read_mask;

		return 0;
	}

	pentry = kmalloc_obj(*pentry);
	if (!pentry) {
		ret = -ENOMEM;
		goto fail;
	}

	*pentry = *e;
	pentry->reg = reg;
	ret = xa_err(xa_store(&sr->xa, idx, pentry, GFP_KERNEL));
	if (ret)
		goto fail_free;

	return 0;

fail_free:
	kfree(pentry);
fail:
	xe_gt_err(gt,
		  "discarding save-restore reg %04lx (clear: %08x, set: %08x, masked: %s, mcr: %s): ret=%d\n",
		  idx, e->clr_bits, e->set_bits,
		  str_yes_no(e->reg.masked),
		  str_yes_no(e->reg.mcr),
		  ret);
	reg_sr_inc_error(sr);

	return ret;
}

/*
 * Convert back from encoded value to type-safe, only to be used when reg.mcr
 * is true
 */
static struct xe_reg_mcr to_xe_reg_mcr(const struct xe_reg reg)
{
	return (const struct xe_reg_mcr){.__reg.raw = reg.raw };
}

static void apply_one_mmio(struct xe_gt *gt, struct xe_reg_sr_entry *entry)
{
	struct xe_reg reg = entry->reg;
	struct xe_reg_mcr reg_mcr = to_xe_reg_mcr(reg);
	u32 val;

	/*
	 * If this is a masked register, need to set the upper 16 bits.
	 * Set them to clr_bits since that is always a superset of the bits
	 * being modified.
	 *
	 * When it's not masked, we have to read it from hardware, unless we are
	 * supposed to set all bits.
	 */
	if (reg.masked)
		val = entry->clr_bits << 16;
	else if (entry->clr_bits + 1)
		val = (reg.mcr ?
		       xe_gt_mcr_unicast_read_any(gt, reg_mcr) :
		       xe_mmio_read32(&gt->mmio, reg)) & (~entry->clr_bits);
	else
		val = 0;

	/*
	 * TODO: add selftest to validate all tables, regardless of platform:
	 *   - Masked registers can't have set_bits with upper bits set
	 *   - set_bits must be contained in clr_bits
	 */
	val |= entry->set_bits;

	xe_gt_dbg(gt, "REG[0x%x] = 0x%08x", reg.addr, val);

	if (entry->reg.mcr)
		xe_gt_mcr_multicast_write(gt, reg_mcr, val);
	else
		xe_mmio_write32(&gt->mmio, reg, val);
}

void xe_reg_sr_apply_mmio(struct xe_reg_sr *sr, struct xe_gt *gt)
{
	struct xe_reg_sr_entry *entry;

Annotation

Implementation Notes