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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
Extension
.c
Size
10763 bytes
Lines
336
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

switch (bootrom) {
		case INTEL_BOOTROM_STATUS_NO_KEY_FOUND:
			guc_info(guc, "invalid key requested, header = 0x%08X\n",
				 intel_uncore_read(uncore, GUC_HEADER_INFO));
			ret = -ENOEXEC;
			break;

		case INTEL_BOOTROM_STATUS_RSA_FAILED:
			guc_info(guc, "firmware signature verification failed\n");
			ret = -ENOEXEC;
			break;

		case INTEL_BOOTROM_STATUS_PROD_KEY_CHECK_FAILURE:
			guc_info(guc, "firmware production part check failure\n");
			ret = -ENOEXEC;
			break;
		}

		switch (ukernel) {
		case INTEL_GUC_LOAD_STATUS_EXCEPTION:
			guc_info(guc, "firmware exception. EIP: %#x\n",
				 intel_uncore_read(uncore, SOFT_SCRATCH(13)));
			ret = -ENXIO;
			break;

		case INTEL_GUC_LOAD_STATUS_INIT_MMIO_SAVE_RESTORE_INVALID:
			guc_info(guc, "illegal register in save/restore workaround list\n");
			ret = -EPERM;
			break;

		case INTEL_GUC_LOAD_STATUS_KLV_WORKAROUND_INIT_ERROR:
			guc_info(guc, "invalid w/a KLV entry\n");
			ret = -EINVAL;
			break;

		case INTEL_GUC_LOAD_STATUS_HWCONFIG_START:
			guc_info(guc, "still extracting hwconfig table.\n");
			ret = -ETIMEDOUT;
			break;
		}

		/* Uncommon/unexpected error, see earlier status code print for details */
		if (ret == 0)
			ret = -ENXIO;
	} else if (delta_ms > 200) {
		guc_warn(guc, "excessive init time: %lldms! [status = 0x%08X, count = %d, ret = %d]\n",
			 delta_ms, status, count, ret);
		guc_warn(guc, "excessive init time: [freq = %dMHz -> %dMHz vs %dMHz, perf_limit_reasons = 0x%08X]\n",
			 before_freq, intel_rps_read_actual_frequency(&gt->rps),
			 intel_rps_get_requested_frequency(&gt->rps),
			 intel_uncore_read(uncore, intel_gt_perf_limit_reasons_reg(gt)));
	} else {
		guc_dbg(guc, "init took %lldms, freq = %dMHz -> %dMHz vs %dMHz, status = 0x%08X, count = %d, ret = %d\n",
			delta_ms, before_freq, intel_rps_read_actual_frequency(&gt->rps),
			intel_rps_get_requested_frequency(&gt->rps), status, count, ret);
	}

	return ret;
}

/**
 * intel_guc_fw_upload() - load GuC uCode to device
 * @guc: intel_guc structure
 *
 * Called from intel_uc_init_hw() during driver load, resume from sleep and
 * after a GPU reset.
 *
 * The firmware image should have already been fetched into memory, so only
 * check that fetch succeeded, and then transfer the image to the h/w.
 *
 * Return:	non-zero code on error
 */
int intel_guc_fw_upload(struct intel_guc *guc)
{
	struct intel_gt *gt = guc_to_gt(guc);
	struct intel_uncore *uncore = gt->uncore;
	int ret;

	guc_prepare_xfer(gt);

	/*
	 * Note that GuC needs the CSS header plus uKernel code to be copied
	 * by the DMA engine in one operation, whereas the RSA signature is
	 * loaded separately, either by copying it to the UOS_RSA_SCRATCH
	 * register (if key size <= 256) or through a ggtt-pinned vma (if key
	 * size > 256). The RSA size and therefore the way we provide it to the
	 * HW is fixed for each platform and hard-coded in the bootrom.
	 */
	ret = guc_xfer_rsa(&guc->fw, uncore);
	if (ret)

Annotation

Implementation Notes