drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
Extension
.c
Size
16201 bytes
Lines
525
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 intel_gsc_mkhi_header {
	u8  group_id;
#define MKHI_GROUP_ID_GFX_SRV 0x30

	u8  command;
#define MKHI_GFX_SRV_GET_HOST_COMPATIBILITY_VERSION (0x42)

	u8  reserved;
	u8  result;
} __packed;

struct mtl_gsc_ver_msg_in {
	struct intel_gsc_mtl_header header;
	struct intel_gsc_mkhi_header mkhi;
} __packed;

struct mtl_gsc_ver_msg_out {
	struct intel_gsc_mtl_header header;
	struct intel_gsc_mkhi_header mkhi;
	u16 proj_major;
	u16 compat_major;
	u16 compat_minor;
	u16 reserved[5];
} __packed;

#define GSC_VER_PKT_SZ SZ_4K

static int gsc_fw_query_compatibility_version(struct intel_gsc_uc *gsc)
{
	struct intel_gt *gt = gsc_uc_to_gt(gsc);
	struct mtl_gsc_ver_msg_in *msg_in;
	struct mtl_gsc_ver_msg_out *msg_out;
	struct i915_vma *vma;
	u64 offset;
	void *vaddr;
	int err;

	err = intel_guc_allocate_and_map_vma(gt_to_guc(gt), GSC_VER_PKT_SZ * 2,
					     &vma, &vaddr);
	if (err) {
		gt_err(gt, "failed to allocate vma for GSC version query\n");
		return err;
	}

	offset = i915_ggtt_offset(vma);
	msg_in = vaddr;
	msg_out = vaddr + GSC_VER_PKT_SZ;

	intel_gsc_uc_heci_cmd_emit_mtl_header(&msg_in->header,
					      HECI_MEADDRESS_MKHI,
					      sizeof(*msg_in), 0);
	msg_in->mkhi.group_id = MKHI_GROUP_ID_GFX_SRV;
	msg_in->mkhi.command = MKHI_GFX_SRV_GET_HOST_COMPATIBILITY_VERSION;

	err = intel_gsc_uc_heci_cmd_submit_packet(&gt->uc.gsc,
						  offset,
						  sizeof(*msg_in),
						  offset + GSC_VER_PKT_SZ,
						  GSC_VER_PKT_SZ);
	if (err) {
		gt_err(gt,
		       "failed to submit GSC request for compatibility version: %d\n",
		       err);
		goto out_vma;
	}

	if (msg_out->header.message_size != sizeof(*msg_out)) {
		gt_err(gt, "invalid GSC reply length %u [expected %zu], s=0x%x, f=0x%x, r=0x%x\n",
		       msg_out->header.message_size, sizeof(*msg_out),
		       msg_out->header.status, msg_out->header.flags, msg_out->mkhi.result);
		err = -EPROTO;
		goto out_vma;
	}

	gsc->fw.file_selected.ver.major = msg_out->compat_major;
	gsc->fw.file_selected.ver.minor = msg_out->compat_minor;

out_vma:
	i915_vma_unpin_and_release(&vma, I915_VMA_RELEASE_MAP);
	return err;
}

int intel_gsc_uc_fw_upload(struct intel_gsc_uc *gsc)
{
	struct intel_gt *gt = gsc_uc_to_gt(gsc);
	struct intel_uc_fw *gsc_fw = &gsc->fw;
	int err;

	/* check current fw status */
	if (intel_gsc_uc_fw_init_done(gsc)) {

Annotation

Implementation Notes