drivers/gpu/drm/i915/i915_hdcp_gsc.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/i915_hdcp_gsc.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/i915_hdcp_gsc.c
Extension
.c
Size
7001 bytes
Lines
248
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_hdcp_gsc_context {
	struct drm_i915_private *i915;
	struct i915_vma *vma;
	void *hdcp_cmd_in;
	void *hdcp_cmd_out;
};

static bool intel_hdcp_gsc_check_status(struct drm_device *drm)
{
	struct drm_i915_private *i915 = to_i915(drm);
	struct intel_gt *gt = i915->media_gt;
	struct intel_gsc_uc *gsc = gt ? &gt->uc.gsc : NULL;

	if (!gsc || !intel_uc_fw_is_running(&gsc->fw)) {
		drm_dbg_kms(&i915->drm,
			    "GSC components required for HDCP2.2 are not ready\n");
		return false;
	}

	return true;
}

/*This function helps allocate memory for the command that we will send to gsc cs */
static int intel_hdcp_gsc_initialize_message(struct drm_i915_private *i915,
					     struct intel_hdcp_gsc_context *gsc_context)
{
	struct intel_gt *gt = i915->media_gt;
	struct drm_i915_gem_object *obj = NULL;
	struct i915_vma *vma = NULL;
	void *cmd_in, *cmd_out;
	int err;

	/* allocate object of two page for HDCP command memory and store it */
	obj = i915_gem_object_create_shmem(i915, 2 * PAGE_SIZE);

	if (IS_ERR(obj)) {
		drm_err(&i915->drm, "Failed to allocate HDCP streaming command!\n");
		return PTR_ERR(obj);
	}

	cmd_in = i915_gem_object_pin_map_unlocked(obj, intel_gt_coherent_map_type(gt, obj, true));
	if (IS_ERR(cmd_in)) {
		drm_err(&i915->drm, "Failed to map gsc message page!\n");
		err = PTR_ERR(cmd_in);
		goto out_unpin;
	}

	cmd_out = cmd_in + PAGE_SIZE;

	vma = i915_vma_instance(obj, &gt->ggtt->vm, NULL);
	if (IS_ERR(vma)) {
		err = PTR_ERR(vma);
		goto out_unmap;
	}

	err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH);
	if (err)
		goto out_unmap;

	memset(cmd_in, 0, obj->base.size);

	gsc_context->hdcp_cmd_in = cmd_in;
	gsc_context->hdcp_cmd_out = cmd_out;
	gsc_context->vma = vma;
	gsc_context->i915 = i915;

	return 0;

out_unmap:
	i915_gem_object_unpin_map(obj);
out_unpin:
	i915_gem_object_put(obj);
	return err;
}

static struct intel_hdcp_gsc_context *intel_hdcp_gsc_context_alloc(struct drm_device *drm)
{
	struct drm_i915_private *i915 = to_i915(drm);
	struct intel_hdcp_gsc_context *gsc_context;
	int ret;

	gsc_context = kzalloc_obj(*gsc_context);
	if (!gsc_context)
		return ERR_PTR(-ENOMEM);

	/*
	 * NOTE: No need to lock the comp mutex here as it is already
	 * going to be taken before this function called
	 */
	ret = intel_hdcp_gsc_initialize_message(i915, gsc_context);

Annotation

Implementation Notes