drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c
Extension
.c
Size
21606 bytes
Lines
667
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

// SPDX-License-Identifier: MIT
/*
 * Copyright 2023, Intel Corporation.
 */

#include <linux/err.h>

#include <drm/drm_print.h>
#include <drm/intel/i915_hdcp_interface.h>

#include "intel_display_core.h"
#include "intel_display_types.h"
#include "intel_hdcp_gsc_message.h"
#include "intel_parent.h"

static int
intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data,
				struct hdcp2_ake_init *ake_data)
{
	struct wired_cmd_initiate_hdcp2_session_in session_init_in = {};
	struct wired_cmd_initiate_hdcp2_session_out session_init_out = {};
	struct intel_hdcp_gsc_context *gsc_context;
	struct intel_display *display;
	ssize_t byte;

	if (!dev || !data || !ake_data)
		return -EINVAL;

	display = to_intel_display(dev);
	if (!display) {
		dev_err(dev, "DRM not initialized, aborting HDCP.\n");
		return -ENODEV;
	}
	gsc_context = display->hdcp.gsc_context;

	session_init_in.header.api_version = HDCP_API_VERSION;
	session_init_in.header.command_id = WIRED_INITIATE_HDCP2_SESSION;
	session_init_in.header.status = FW_HDCP_STATUS_SUCCESS;
	session_init_in.header.buffer_len =
				WIRED_CMD_BUF_LEN_INITIATE_HDCP2_SESSION_IN;

	session_init_in.port.integrated_port_type = data->port_type;
	session_init_in.port.physical_port = (u8)data->hdcp_ddi;
	session_init_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
	session_init_in.protocol = data->protocol;

	byte = intel_parent_hdcp_gsc_msg_send(display, gsc_context,
					      &session_init_in, sizeof(session_init_in),
					      &session_init_out, sizeof(session_init_out));
	if (byte < 0) {
		drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
		return byte;
	}

	if (session_init_out.header.status != FW_HDCP_STATUS_SUCCESS) {
		drm_dbg_kms(display->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n",
			    WIRED_INITIATE_HDCP2_SESSION,
			    session_init_out.header.status);
		return -EIO;
	}

	ake_data->msg_id = HDCP_2_2_AKE_INIT;
	ake_data->tx_caps = session_init_out.tx_caps;
	memcpy(ake_data->r_tx, session_init_out.r_tx, HDCP_2_2_RTX_LEN);

	return 0;
}

static int
intel_hdcp_gsc_verify_receiver_cert_prepare_km(struct device *dev,
					       struct hdcp_port_data *data,
					       struct hdcp2_ake_send_cert *rx_cert,
					       bool *km_stored,
					       struct hdcp2_ake_no_stored_km
					       *ek_pub_km,
					       size_t *msg_sz)
{
	struct wired_cmd_verify_receiver_cert_in verify_rxcert_in = {};
	struct wired_cmd_verify_receiver_cert_out verify_rxcert_out = {};
	struct intel_hdcp_gsc_context *gsc_context;
	struct intel_display *display;
	ssize_t byte;

	if (!dev || !data || !rx_cert || !km_stored || !ek_pub_km || !msg_sz)
		return -EINVAL;

	display = to_intel_display(dev);
	if (!display) {
		dev_err(dev, "DRM not initialized, aborting HDCP.\n");
		return -ENODEV;

Annotation

Implementation Notes