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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/gt/uc/intel_huc.c
Extension
.c
Size
20658 bytes
Lines
689
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

void intel_huc_register_gsc_notifier(struct intel_huc *huc, const struct bus_type *bus)
{
	int ret;

	if (!intel_huc_is_loaded_by_gsc(huc))
		return;

	huc->delayed_load.nb.notifier_call = gsc_notifier;
	ret = bus_register_notifier(bus, &huc->delayed_load.nb);
	if (ret) {
		huc_err(huc, "failed to register GSC notifier %pe\n", ERR_PTR(ret));
		huc->delayed_load.nb.notifier_call = NULL;
		gsc_init_error(huc);
	}
}

void intel_huc_unregister_gsc_notifier(struct intel_huc *huc, const struct bus_type *bus)
{
	if (!huc->delayed_load.nb.notifier_call)
		return;

	delayed_huc_load_complete(huc);

	bus_unregister_notifier(bus, &huc->delayed_load.nb);
	huc->delayed_load.nb.notifier_call = NULL;
}

static void delayed_huc_load_init(struct intel_huc *huc)
{
	/*
	 * Initialize fence to be complete as this is expected to be complete
	 * unless there is a delayed HuC load in progress.
	 */
	i915_sw_fence_init(&huc->delayed_load.fence,
			   sw_fence_dummy_notify);
	i915_sw_fence_commit(&huc->delayed_load.fence);

	hrtimer_setup(&huc->delayed_load.timer, huc_delayed_load_timer_callback, CLOCK_MONOTONIC,
		      HRTIMER_MODE_REL);
}

static void delayed_huc_load_fini(struct intel_huc *huc)
{
	/*
	 * the fence is initialized in init_early, so we need to clean it up
	 * even if HuC loading is off.
	 */
	delayed_huc_load_complete(huc);
	i915_sw_fence_fini(&huc->delayed_load.fence);
}

int intel_huc_sanitize(struct intel_huc *huc)
{
	delayed_huc_load_complete(huc);
	intel_uc_fw_sanitize(&huc->fw);
	return 0;
}

static bool vcs_supported(struct intel_gt *gt)
{
	intel_engine_mask_t mask = gt->info.engine_mask;

	/*
	 * We reach here from i915_driver_early_probe for the primary GT before
	 * its engine mask is set, so we use the device info engine mask for it;
	 * this means we're not taking VCS fusing into account, but if the
	 * primary GT supports VCS engines we expect at least one of them to
	 * remain unfused so we're fine.
	 * For other GTs we expect the GT-specific mask to be set before we
	 * call this function.
	 */
	GEM_BUG_ON(!gt_is_root(gt) && !gt->info.engine_mask);

	if (gt_is_root(gt))
		mask = INTEL_INFO(gt->i915)->platform_engine_mask;
	else
		mask = gt->info.engine_mask;

	return __ENGINE_INSTANCES_MASK(mask, VCS0, I915_MAX_VCS);
}

void intel_huc_init_early(struct intel_huc *huc)
{
	struct drm_i915_private *i915 = huc_to_gt(huc)->i915;
	struct intel_gt *gt = huc_to_gt(huc);

	intel_uc_fw_init_early(&huc->fw, INTEL_UC_FW_TYPE_HUC, true);

	/*
	 * we always init the fence as already completed, even if HuC is not

Annotation

Implementation Notes