drivers/gpu/drm/xe/display/xe_hdcp_gsc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
Extension
.c
Size
5811 bytes
Lines
218
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 xe_device *xe;
	struct xe_bo *hdcp_bo;
	u64 hdcp_cmd_in;
	u64 hdcp_cmd_out;
};

#define HDCP_GSC_HEADER_SIZE sizeof(struct intel_gsc_mtl_header)

static bool intel_hdcp_gsc_check_status(struct drm_device *drm)
{
	struct xe_device *xe = to_xe_device(drm);
	struct xe_tile *tile = xe_device_get_root_tile(xe);
	struct xe_gt *gt = tile->media_gt;
	struct xe_gsc *gsc;

	if (!gt) {
		drm_dbg_kms(&xe->drm,
			    "not checking GSC status for HDCP2.x: media GT not present or disabled\n");
		return false;
	}

	gsc = &gt->uc.gsc;

	if (!xe_uc_fw_is_available(&gsc->fw)) {
		drm_dbg_kms(&xe->drm,
			    "GSC Components not ready for HDCP2.x\n");
		return false;
	}

	guard(xe_pm_runtime)(xe);
	CLASS(xe_force_wake, fw_ref)(gt_to_fw(gt), XE_FW_GSC);
	if (!fw_ref.domains) {
		drm_dbg_kms(&xe->drm,
			    "failed to get forcewake to check proxy status\n");
		return false;
	}

	return xe_gsc_proxy_init_done(gsc);
}

/*This function helps allocate memory for the command that we will send to gsc cs */
static int intel_hdcp_gsc_initialize_message(struct xe_device *xe,
					     struct intel_hdcp_gsc_context *gsc_context)
{
	struct xe_bo *bo = NULL;
	u64 cmd_in, cmd_out;
	int ret = 0;

	/* allocate object of two page for HDCP command memory and store it */
	bo = xe_bo_create_pin_map_novm(xe, xe_device_get_root_tile(xe), PAGE_SIZE * 2,
				       ttm_bo_type_kernel,
				       XE_BO_FLAG_SYSTEM |
				       XE_BO_FLAG_GGTT, false);

	if (IS_ERR(bo)) {
		drm_err(&xe->drm, "Failed to allocate bo for HDCP streaming command!\n");
		ret = PTR_ERR(bo);
		goto out;
	}

	cmd_in = xe_bo_ggtt_addr(bo);
	cmd_out = cmd_in + PAGE_SIZE;
	xe_map_memset(xe, &bo->vmap, 0, 0, xe_bo_size(bo));

	gsc_context->hdcp_bo = bo;
	gsc_context->hdcp_cmd_in = cmd_in;
	gsc_context->hdcp_cmd_out = cmd_out;
	gsc_context->xe = xe;

out:
	return ret;
}

static struct intel_hdcp_gsc_context *intel_hdcp_gsc_context_alloc(struct drm_device *drm)
{
	struct xe_device *xe = to_xe_device(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(xe, gsc_context);
	if (ret) {

Annotation

Implementation Notes