drivers/gpu/drm/xe/xe_sysctrl_mailbox.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_sysctrl_mailbox.c
Extension
.c
Size
9733 bytes
Lines
372
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 xe_sysctrl_mailbox_msg_hdr {
	__le32 data;
} __packed;

#define XE_SYSCTRL_HDR_GROUP_ID(hdr) \
	FIELD_GET(SYSCTRL_HDR_GROUP_ID_MASK, le32_to_cpu((hdr)->data))

#define XE_SYSCTRL_HDR_COMMAND(hdr) \
	FIELD_GET(SYSCTRL_HDR_COMMAND_MASK, le32_to_cpu((hdr)->data))

#define XE_SYSCTRL_HDR_IS_RESPONSE(hdr) \
	FIELD_GET(SYSCTRL_HDR_IS_RESPONSE, le32_to_cpu((hdr)->data))

#define XE_SYSCTRL_HDR_RESULT(hdr) \
	FIELD_GET(SYSCTRL_HDR_RESULT_MASK, le32_to_cpu((hdr)->data))

static bool sysctrl_wait_bit_clear(struct xe_sysctrl *sc, u32 bit_mask,
				   unsigned int timeout_ms)
{
	int ret;

	ret = xe_mmio_wait32_not(sc->mmio, SYSCTRL_MB_CTRL, bit_mask, bit_mask,
				 timeout_ms * 1000, NULL, false);

	return ret == 0;
}

static bool sysctrl_wait_bit_set(struct xe_sysctrl *sc, u32 bit_mask,
				 unsigned int timeout_ms)
{
	int ret;

	ret = xe_mmio_wait32(sc->mmio, SYSCTRL_MB_CTRL, bit_mask, bit_mask,
			     timeout_ms * 1000, NULL, false);

	return ret == 0;
}

static int sysctrl_write_frame(struct xe_sysctrl *sc, const void *frame,
			       size_t len)
{
	static const struct xe_reg regs[] = {
		SYSCTRL_MB_DATA0, SYSCTRL_MB_DATA1, SYSCTRL_MB_DATA2, SYSCTRL_MB_DATA3
	};
	struct xe_device *xe = sc_to_xe(sc);
	u32 val[XE_SYSCTRL_MB_FRAME_SIZE / sizeof(u32)] = {0};
	u32 dw = DIV_ROUND_UP(len, sizeof(u32));
	u32 i;

	xe_assert(xe, len > 0 && len <= XE_SYSCTRL_MB_FRAME_SIZE);

	memcpy(val, frame, len);

	for (i = 0; i < dw; i++)
		xe_mmio_write32(sc->mmio, regs[i], val[i]);

	return 0;
}

static int sysctrl_read_frame(struct xe_sysctrl *sc, void *frame,
			      size_t len)
{
	static const struct xe_reg regs[] = {
		SYSCTRL_MB_DATA0, SYSCTRL_MB_DATA1, SYSCTRL_MB_DATA2, SYSCTRL_MB_DATA3
	};
	struct xe_device *xe = sc_to_xe(sc);
	u32 val[XE_SYSCTRL_MB_FRAME_SIZE / sizeof(u32)] = {0};
	u32 dw = DIV_ROUND_UP(len, sizeof(u32));
	u32 i;

	xe_assert(xe, len > 0 && len <= XE_SYSCTRL_MB_FRAME_SIZE);

	for (i = 0; i < dw; i++)
		val[i] = xe_mmio_read32(sc->mmio, regs[i]);

	memcpy(frame, val, len);

	return 0;
}

static void sysctrl_clear_response(struct xe_sysctrl *sc)
{
	xe_mmio_rmw32(sc->mmio, SYSCTRL_MB_CTRL, SYSCTRL_MB_CTRL_RUN_BUSY_OUT, 0);
}

static int sysctrl_prepare_command(struct xe_device *xe,
				   u8 group_id, u8 command,
				   const void *data_in, size_t data_in_len,
				   u8 **mbox_cmd, size_t *cmd_size)
{

Annotation

Implementation Notes