Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9df5c683 authored by Tatenda Chipeperekwa's avatar Tatenda Chipeperekwa
Browse files

drm/msm: modularize QSEECOM and HDCP functionalities



Create separate modules to handle QSEECOM communications with the
TrustZone layer and to manage the HDCP 2.2 state machine.
This modularization will improve the extensibility and testability
of each module.

CRs-Fixed: 2213798
Change-Id: I9bedd5d97e855d164650ca70a785698403851f25
Signed-off-by: default avatarAjay Singh Parmar <aparmar@codeaurora.org>
Signed-off-by: default avatarTatenda Chipeperekwa <tatendac@codeaurora.org>
parent 1529c90d
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -44,7 +44,8 @@ msm_drm-y := \
	sde/sde_hw_color_proc_v4.o \
	sde/sde_hw_ad4.o \
	sde_edid_parser.o \
	sde_hdcp_1x.o
	sde_hdcp_1x.o \
	sde_hdcp_2x.o

msm_drm-$(CONFIG_DRM_MSM_HDMI) += hdmi/hdmi.o \
	hdmi/hdmi_audio.o \
+13 −15
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@
#include <linux/debugfs.h>
#include <linux/component.h>
#include <linux/of_irq.h>
#include <linux/hdcp_qseecom.h>
#include <linux/soc/qcom/fsa4480-i2c.h>

#include "sde_connector.h"
@@ -237,25 +236,21 @@ static void dp_display_update_hdcp_info(struct dp_display_private *dp)

	if (ops && ops->feature_supported)
		hdcp2_present = ops->feature_supported(fd);
	else
		hdcp2_present = false;

	pr_debug("hdcp2p2: %s\n",
			hdcp2_present ? "supported" : "not supported");
	if (hdcp2_present)
		dp->link->hdcp_status.hdcp_version = HDCP_VERSION_2P2;

	if (IS_ENABLED(CONFIG_HDCP_QSEECOM) && !hdcp2_present) {
		hdcp1_present = hdcp1_check_if_supported_load_app();
		if (hdcp1_present) {
	if (!hdcp2_present) {
		fd = dp->hdcp.hdcp1;
		if (fd)
			ops = sde_hdcp_1x_start(fd);

		if (ops && ops->feature_supported)
			hdcp1_present = ops->feature_supported(fd);

		if (hdcp1_present)
			dp->link->hdcp_status.hdcp_version = HDCP_VERSION_1X;
	}
	} else {
		dp->link->hdcp_status.hdcp_version = HDCP_VERSION_2P2;
	}

	pr_debug("hdcp1x: %s\n",
			hdcp1_present ? "supported" : "not supported");

	if (hdcp2_present || hdcp1_present) {
		dp->hdcp.data = fd;
@@ -264,6 +259,9 @@ static void dp_display_update_hdcp_info(struct dp_display_private *dp)
		dp->hdcp.data = NULL;
		dp->hdcp.ops = NULL;
	}

	pr_debug("HDCP version supported: %s\n",
		sde_hdcp_version(dp->link->hdcp_status.hdcp_version));
}

static void dp_display_deinitialize_hdcp(struct dp_display_private *dp)
+86 −97
Original line number Diff line number Diff line
@@ -18,11 +18,10 @@
#include <linux/stat.h>
#include <linux/types.h>
#include <linux/kthread.h>
#include <linux/hdcp_qseecom.h>
#include <linux/msm_hdcp.h>
#include <drm/drm_dp_helper.h>

#include "sde_hdcp.h"
#include "sde_hdcp_2x.h"

#define DP_INTR_STATUS2				(0x00000024)
#define DP_INTR_STATUS3				(0x00000028)
@@ -50,8 +49,8 @@ struct dp_hdcp2p2_ctrl {
	struct mutex wakeup_mutex; /* mutex to protect access to wakeup call*/
	struct sde_hdcp_ops *ops;
	void *lib_ctx; /* Handle to HDCP 2.2 Trustzone library */
	struct hdcp_txmtr_ops *lib; /* Ops for driver to call into TZ */
	enum hdcp_wakeup_cmd wakeup_cmd;
	struct sde_hdcp_2x_ops *lib; /* Ops for driver to call into TZ */
	enum hdcp_transport_wakeup_cmd wakeup_cmd;
	enum dp_auth_status auth_status;

	struct task_struct *thread;
@@ -61,11 +60,11 @@ struct dp_hdcp2p2_ctrl {
	struct kthread_work send_msg;
	struct kthread_work recv_msg;
	struct kthread_work link;
	char *msg_buf;
	uint32_t send_msg_len; /* length of all parameters in msg */
	struct hdcp2_buffer response;
	struct hdcp2_buffer request;
	uint32_t total_message_length;
	uint32_t timeout;
	uint32_t num_messages;
	struct hdcp_msg_part msg_part[HDCP_MAX_MESSAGE_PARTS];
	struct sde_hdcp_2x_msg_part msg_part[HDCP_MAX_MESSAGE_PARTS];
	u8 sink_rx_status;
	u8 rx_status;
	char abort_mask;
@@ -87,7 +86,7 @@ struct dp_hdcp2p2_interrupts {

static inline bool dp_hdcp2p2_is_valid_state(struct dp_hdcp2p2_ctrl *ctrl)
{
	if (ctrl->wakeup_cmd == HDCP_WKUP_CMD_AUTHENTICATE)
	if (ctrl->wakeup_cmd == HDCP_TRANSPORT_CMD_AUTHENTICATE)
		return true;

	if (atomic_read(&ctrl->auth_state) != HDCP_STATE_INACTIVE)
@@ -97,9 +96,10 @@ static inline bool dp_hdcp2p2_is_valid_state(struct dp_hdcp2p2_ctrl *ctrl)
}

static int dp_hdcp2p2_copy_buf(struct dp_hdcp2p2_ctrl *ctrl,
	struct hdcp_wakeup_data *data)
	struct hdcp_transport_wakeup_data *data)
{
	int i = 0;
	uint32_t num_messages = 0;

	if (!data || !data->message_data)
		return 0;
@@ -107,11 +107,12 @@ static int dp_hdcp2p2_copy_buf(struct dp_hdcp2p2_ctrl *ctrl,
	mutex_lock(&ctrl->msg_lock);

	ctrl->timeout = data->timeout;
	ctrl->num_messages = data->message_data->num_messages;
	ctrl->send_msg_len = 0; /* Total len of all messages */
	num_messages = data->message_data->num_messages;
	ctrl->total_message_length = 0; /* Total length of all messages */

	for (i = 0; i < ctrl->num_messages ; i++)
		ctrl->send_msg_len += data->message_data->messages[i].length;
	for (i = 0; i < num_messages; i++)
		ctrl->total_message_length +=
			data->message_data->messages[i].length;

	memcpy(ctrl->msg_part, data->message_data->messages,
		sizeof(data->message_data->messages));
@@ -119,29 +120,22 @@ static int dp_hdcp2p2_copy_buf(struct dp_hdcp2p2_ctrl *ctrl,
	ctrl->rx_status = data->message_data->rx_status;
	ctrl->abort_mask = data->abort_mask;

	if (!data->send_msg_len) {
	if (!ctrl->total_message_length) {
		mutex_unlock(&ctrl->msg_lock);
		return 0;
	}

	kzfree(ctrl->msg_buf);

	ctrl->msg_buf = kzalloc(ctrl->send_msg_len, GFP_KERNEL);

	if (!ctrl->msg_buf) {
		mutex_unlock(&ctrl->msg_lock);
		return -ENOMEM;
	}

	/* ignore first byte as it contains message id */
	memcpy(ctrl->msg_buf, data->send_msg_buf + 1, ctrl->send_msg_len);
	ctrl->response.data = data->buf;
	ctrl->response.length = ctrl->total_message_length;
	ctrl->request.data = data->buf;
	ctrl->request.length = ctrl->total_message_length;

	mutex_unlock(&ctrl->msg_lock);

	return 0;
}

static int dp_hdcp2p2_wakeup(struct hdcp_wakeup_data *data)
static int dp_hdcp2p2_wakeup(struct hdcp_transport_wakeup_data *data)
{
	struct dp_hdcp2p2_ctrl *ctrl;
	u32 const default_timeout_us = 500;
@@ -174,29 +168,31 @@ static int dp_hdcp2p2_wakeup(struct hdcp_wakeup_data *data)
	if (dp_hdcp2p2_copy_buf(ctrl, data))
		goto exit;

	if (ctrl->wakeup_cmd == HDCP_WKUP_CMD_STATUS_SUCCESS)
	pr_debug("%s\n", hdcp_transport_cmd_to_str(ctrl->wakeup_cmd));

	if (ctrl->wakeup_cmd == HDCP_TRANSPORT_CMD_STATUS_SUCCESS)
		ctrl->auth_status = DP_HDCP_AUTH_STATUS_SUCCESS;
	else if (ctrl->wakeup_cmd == HDCP_WKUP_CMD_STATUS_FAILED)
	else if (ctrl->wakeup_cmd == HDCP_TRANSPORT_CMD_STATUS_FAILED)
		ctrl->auth_status = DP_HDCP_AUTH_STATUS_FAILURE;

	switch (ctrl->wakeup_cmd) {
	case HDCP_WKUP_CMD_SEND_MESSAGE:
	case HDCP_TRANSPORT_CMD_SEND_MESSAGE:
		kthread_queue_work(&ctrl->worker, &ctrl->send_msg);
		break;
	case HDCP_WKUP_CMD_RECV_MESSAGE:
	case HDCP_TRANSPORT_CMD_RECV_MESSAGE:
		kthread_queue_work(&ctrl->worker, &ctrl->recv_msg);
		break;
	case HDCP_WKUP_CMD_STATUS_SUCCESS:
	case HDCP_WKUP_CMD_STATUS_FAILED:
	case HDCP_TRANSPORT_CMD_STATUS_SUCCESS:
	case HDCP_TRANSPORT_CMD_STATUS_FAILED:
		kthread_queue_work(&ctrl->worker, &ctrl->status);
		break;
	case HDCP_WKUP_CMD_LINK_POLL:
	case HDCP_TRANSPORT_CMD_LINK_POLL:
		if (ctrl->cp_irq_done)
			kthread_queue_work(&ctrl->worker, &ctrl->recv_msg);
		else
			ctrl->polling = true;
		break;
	case HDCP_WKUP_CMD_AUTHENTICATE:
	case HDCP_TRANSPORT_CMD_AUTHENTICATE:
		kthread_queue_work(&ctrl->worker, &ctrl->auth);
		break;
	default:
@@ -209,16 +205,16 @@ static int dp_hdcp2p2_wakeup(struct hdcp_wakeup_data *data)
}

static inline void dp_hdcp2p2_wakeup_lib(struct dp_hdcp2p2_ctrl *ctrl,
	struct hdcp_lib_wakeup_data *data)
	struct sde_hdcp_2x_wakeup_data *data)
{
	int rc = 0;

	if (ctrl && ctrl->lib && ctrl->lib->wakeup &&
		data && (data->cmd != HDCP_LIB_WKUP_CMD_INVALID)) {
		data && (data->cmd != HDCP_2X_CMD_INVALID)) {
		rc = ctrl->lib->wakeup(data);
		if (rc)
			pr_err("error sending %s to lib\n",
				hdcp_lib_cmd_to_str(data->cmd));
				sde_hdcp_2x_cmd_to_str(data->cmd));
	}
}

@@ -260,7 +256,8 @@ static void dp_hdcp2p2_set_interrupts(struct dp_hdcp2p2_ctrl *ctrl, bool enable)
static void dp_hdcp2p2_off(void *input)
{
	struct dp_hdcp2p2_ctrl *ctrl = (struct dp_hdcp2p2_ctrl *)input;
	struct hdcp_wakeup_data cdata = {HDCP_WKUP_CMD_AUTHENTICATE};
	struct hdcp_transport_wakeup_data cdata = {
					HDCP_TRANSPORT_CMD_AUTHENTICATE};

	if (!ctrl) {
		pr_err("invalid input\n");
@@ -285,7 +282,8 @@ static void dp_hdcp2p2_off(void *input)
static int dp_hdcp2p2_authenticate(void *input)
{
	struct dp_hdcp2p2_ctrl *ctrl = input;
	struct hdcp_wakeup_data cdata = {HDCP_WKUP_CMD_AUTHENTICATE};
	struct hdcp_transport_wakeup_data cdata = {
					HDCP_TRANSPORT_CMD_AUTHENTICATE};
	int rc = 0;

	kthread_flush_worker(&ctrl->worker);
@@ -319,8 +317,8 @@ static void dp_hdcp2p2_min_level_change(void *client_ctx,
		int min_enc_level)
{
	struct dp_hdcp2p2_ctrl *ctrl = (struct dp_hdcp2p2_ctrl *)client_ctx;
	struct hdcp_lib_wakeup_data cdata = {
		HDCP_LIB_WKUP_CMD_QUERY_STREAM_TYPE};
	struct sde_hdcp_2x_wakeup_data cdata = {
		HDCP_2X_CMD_QUERY_STREAM_TYPE};

	if (!ctrl) {
		pr_err("invalid input\n");
@@ -349,17 +347,20 @@ static void dp_hdcp2p2_auth_failed(struct dp_hdcp2p2_ctrl *ctrl)
		HDCP_STATE_AUTH_FAIL);
}

static int dp_hdcp2p2_aux_read_message(struct dp_hdcp2p2_ctrl *ctrl,
	u8 *buf, int size, int offset, u32 timeout)
static int dp_hdcp2p2_aux_read_message(struct dp_hdcp2p2_ctrl *ctrl)
{
	int const max_size = 16;
	int rc = 0, read_size = 0, bytes_read = 0;
	int rc = 0, max_size = 16, read_size = 0, bytes_read = 0;
	int size = ctrl->request.length, offset = ctrl->msg_part->offset;
	u8 *buf = ctrl->request.data;

	if (atomic_read(&ctrl->auth_state) == HDCP_STATE_INACTIVE) {
		pr_err("hdcp is off\n");
		return -EINVAL;
		rc = -EINVAL;
		goto exit;
	}

	pr_debug("request: offset(0x%x), size(%d)\n", offset, size);

	do {
		read_size = min(size, max_size);

@@ -376,6 +377,7 @@ static int dp_hdcp2p2_aux_read_message(struct dp_hdcp2p2_ctrl *ctrl,
		size -= read_size;
	} while (size > 0);

exit:
	return rc;
}

@@ -407,7 +409,7 @@ static int dp_hdcp2p2_aux_write_message(struct dp_hdcp2p2_ctrl *ctrl,
static bool dp_hdcp2p2_feature_supported(void *input)
{
	struct dp_hdcp2p2_ctrl *ctrl = input;
	struct hdcp_txmtr_ops *lib = NULL;
	struct sde_hdcp_2x_ops *lib = NULL;
	bool supported = false;

	if (!ctrl) {
@@ -433,7 +435,7 @@ static void dp_hdcp2p2_send_msg_work(struct kthread_work *work)
	int rc = 0;
	struct dp_hdcp2p2_ctrl *ctrl = container_of(work,
		struct dp_hdcp2p2_ctrl, send_msg);
	struct hdcp_lib_wakeup_data cdata = {HDCP_LIB_WKUP_CMD_INVALID};
	struct sde_hdcp_2x_wakeup_data cdata = {HDCP_2X_CMD_INVALID};

	if (!ctrl) {
		pr_err("invalid input\n");
@@ -448,10 +450,14 @@ static void dp_hdcp2p2_send_msg_work(struct kthread_work *work)
		goto exit;
	}

	print_hex_dump(KERN_DEBUG, ": ",
		DUMP_PREFIX_NONE, 16, 1, ctrl->response.data,
		ctrl->response.length, false);

	mutex_lock(&ctrl->msg_lock);

	rc = dp_hdcp2p2_aux_write_message(ctrl, ctrl->msg_buf,
			ctrl->send_msg_len, ctrl->msg_part->offset,
	rc = dp_hdcp2p2_aux_write_message(ctrl, ctrl->response.data,
			ctrl->response.length, ctrl->msg_part->offset,
			ctrl->timeout);
	if (rc) {
		pr_err("Error sending msg to sink %d\n", rc);
@@ -459,15 +465,15 @@ static void dp_hdcp2p2_send_msg_work(struct kthread_work *work)
		goto exit;
	}

	cdata.cmd = HDCP_LIB_WKUP_CMD_MSG_SEND_SUCCESS;
	cdata.cmd = HDCP_2X_CMD_MSG_SEND_SUCCESS;
	cdata.timeout = ctrl->timeout;
	mutex_unlock(&ctrl->msg_lock);

exit:
	if (rc == -ETIMEDOUT)
		cdata.cmd = HDCP_LIB_WKUP_CMD_MSG_RECV_TIMEOUT;
		cdata.cmd = HDCP_2X_CMD_MSG_RECV_TIMEOUT;
	else if (rc)
		cdata.cmd = HDCP_LIB_WKUP_CMD_MSG_RECV_FAILED;
		cdata.cmd = HDCP_2X_CMD_MSG_RECV_FAILED;

	dp_hdcp2p2_wakeup_lib(ctrl, &cdata);
}
@@ -475,45 +481,34 @@ static void dp_hdcp2p2_send_msg_work(struct kthread_work *work)
static int dp_hdcp2p2_get_msg_from_sink(struct dp_hdcp2p2_ctrl *ctrl)
{
	int rc = 0;
	char *recvd_msg_buf = NULL;
	struct hdcp_lib_wakeup_data cdata = { HDCP_LIB_WKUP_CMD_INVALID };
	struct sde_hdcp_2x_wakeup_data cdata = { HDCP_2X_CMD_INVALID };

	cdata.context = ctrl->lib_ctx;

	recvd_msg_buf = kzalloc(ctrl->send_msg_len, GFP_KERNEL);
	if (!recvd_msg_buf) {
		rc = -ENOMEM;
		goto exit;
	}

	rc = dp_hdcp2p2_aux_read_message(ctrl, recvd_msg_buf,
		ctrl->send_msg_len, ctrl->msg_part->offset,
		ctrl->timeout);
	rc = dp_hdcp2p2_aux_read_message(ctrl);
	if (rc) {
		pr_err("error reading message %d\n", rc);
		goto exit;
	}

	cdata.recvd_msg_buf = recvd_msg_buf;
	cdata.recvd_msg_len = ctrl->send_msg_len;
	cdata.total_message_length = ctrl->total_message_length;
	cdata.timeout = ctrl->timeout;
exit:
	if (rc == -ETIMEDOUT)
		cdata.cmd = HDCP_LIB_WKUP_CMD_MSG_RECV_TIMEOUT;
		cdata.cmd = HDCP_2X_CMD_MSG_RECV_TIMEOUT;
	else if (rc)
		cdata.cmd = HDCP_LIB_WKUP_CMD_MSG_RECV_FAILED;
		cdata.cmd = HDCP_2X_CMD_MSG_RECV_FAILED;
	else
		cdata.cmd = HDCP_LIB_WKUP_CMD_MSG_RECV_SUCCESS;
		cdata.cmd = HDCP_2X_CMD_MSG_RECV_SUCCESS;

	dp_hdcp2p2_wakeup_lib(ctrl, &cdata);
	kfree(recvd_msg_buf);

	return rc;
}

static void dp_hdcp2p2_recv_msg_work(struct kthread_work *work)
{
	struct hdcp_lib_wakeup_data cdata = { HDCP_LIB_WKUP_CMD_INVALID };
	struct sde_hdcp_2x_wakeup_data cdata = { HDCP_2X_CMD_INVALID };
	struct dp_hdcp2p2_ctrl *ctrl = container_of(work,
		struct dp_hdcp2p2_ctrl, recv_msg);

@@ -571,7 +566,7 @@ static void dp_hdcp2p2_link_work(struct kthread_work *work)
	int rc = 0;
	struct dp_hdcp2p2_ctrl *ctrl = container_of(work,
		struct dp_hdcp2p2_ctrl, link);
	struct hdcp_lib_wakeup_data cdata = {HDCP_LIB_WKUP_CMD_INVALID};
	struct sde_hdcp_2x_wakeup_data cdata = {HDCP_2X_CMD_INVALID};

	if (!ctrl) {
		pr_err("invalid input\n");
@@ -598,7 +593,7 @@ static void dp_hdcp2p2_link_work(struct kthread_work *work)

		rc = -ENOLINK;

		cdata.cmd = HDCP_LIB_WKUP_CMD_LINK_FAILED;
		cdata.cmd = HDCP_2X_CMD_LINK_FAILED;
		atomic_set(&ctrl->auth_state, HDCP_STATE_AUTH_FAIL);
		goto exit;
	}
@@ -620,16 +615,16 @@ static void dp_hdcp2p2_link_work(struct kthread_work *work)

static void dp_hdcp2p2_auth_work(struct kthread_work *work)
{
	struct hdcp_lib_wakeup_data cdata = {HDCP_LIB_WKUP_CMD_INVALID};
	struct sde_hdcp_2x_wakeup_data cdata = {HDCP_2X_CMD_INVALID};
	struct dp_hdcp2p2_ctrl *ctrl = container_of(work,
		struct dp_hdcp2p2_ctrl, auth);

	cdata.context = ctrl->lib_ctx;

	if (atomic_read(&ctrl->auth_state) == HDCP_STATE_AUTHENTICATING)
		cdata.cmd = HDCP_LIB_WKUP_CMD_START;
		cdata.cmd = HDCP_2X_CMD_START;
	else
		cdata.cmd = HDCP_LIB_WKUP_CMD_STOP;
		cdata.cmd = HDCP_2X_CMD_STOP;

	dp_hdcp2p2_wakeup_lib(ctrl, &cdata);
}
@@ -757,14 +752,14 @@ static int dp_hdcp2p2_isr(void *input)
void sde_dp_hdcp2p2_deinit(void *input)
{
	struct dp_hdcp2p2_ctrl *ctrl = (struct dp_hdcp2p2_ctrl *)input;
	struct hdcp_lib_wakeup_data cdata = {HDCP_LIB_WKUP_CMD_INVALID};
	struct sde_hdcp_2x_wakeup_data cdata = {HDCP_2X_CMD_INVALID};

	if (!ctrl) {
		pr_err("invalid input\n");
		return;
	}

	cdata.cmd = HDCP_LIB_WKUP_CMD_STOP;
	cdata.cmd = HDCP_2X_CMD_STOP;
	cdata.context = ctrl->lib_ctx;
	dp_hdcp2p2_wakeup_lib(ctrl, &cdata);

@@ -773,7 +768,6 @@ void sde_dp_hdcp2p2_deinit(void *input)
	mutex_destroy(&ctrl->mutex);
	mutex_destroy(&ctrl->msg_lock);
	mutex_destroy(&ctrl->wakeup_mutex);
	kzfree(ctrl->msg_buf);
	kfree(ctrl);
}

@@ -781,8 +775,6 @@ void *sde_dp_hdcp2p2_init(struct sde_hdcp_init_data *init_data)
{
	int rc;
	struct dp_hdcp2p2_ctrl *ctrl;
	static struct hdcp_txmtr_ops txmtr_ops;
	struct hdcp_register_data register_data;
	static struct sde_hdcp_ops ops = {
		.isr = dp_hdcp2p2_isr,
		.reauthenticate = dp_hdcp2p2_reauthenticate,
@@ -792,7 +784,7 @@ void *sde_dp_hdcp2p2_init(struct sde_hdcp_init_data *init_data)
		.cp_irq = dp_hdcp2p2_cp_irq,
	};

	static struct hdcp_client_ops client_ops = {
	static struct hdcp_transport_ops client_ops = {
		.wakeup = dp_hdcp2p2_wakeup,
	};
	static struct dp_hdcp2p2_int_set int_set1[] = {
@@ -811,6 +803,8 @@ void *sde_dp_hdcp2p2_init(struct sde_hdcp_init_data *init_data)
		{DP_INTR_STATUS3, int_set2},
		{0}
	};
	static struct sde_hdcp_2x_ops hdcp2x_ops;
	struct sde_hdcp_2x_register_data register_data = {0};

	if (!init_data || !init_data->cb_data ||
			!init_data->notify_status || !init_data->drm_aux) {
@@ -823,8 +817,9 @@ void *sde_dp_hdcp2p2_init(struct sde_hdcp_init_data *init_data)
		return ERR_PTR(-ENOMEM);

	ctrl->init_data = *init_data;
	ctrl->lib = &txmtr_ops;
	ctrl->msg_buf = NULL;
	ctrl->lib = &hdcp2x_ops;
	ctrl->response.data = NULL;
	ctrl->request.data = NULL;

	ctrl->sink_status = SINK_DISCONNECTED;
	ctrl->intr = intr;
@@ -836,23 +831,17 @@ void *sde_dp_hdcp2p2_init(struct sde_hdcp_init_data *init_data)
	mutex_init(&ctrl->msg_lock);
	mutex_init(&ctrl->wakeup_mutex);

	register_data.hdcp_ctx = &ctrl->lib_ctx;
	register_data.hdcp_data = &ctrl->lib_ctx;
	register_data.client_ops = &client_ops;
	register_data.txmtr_ops = &txmtr_ops;
	register_data.ops = &hdcp2x_ops;
	register_data.device_type = HDCP_TXMTR_DP;
	register_data.client_ctx = ctrl;

	register_data.client_data = ctrl;

	if (IS_ENABLED(CONFIG_HDCP_QSEECOM)) {
		rc = hdcp_library_register(&register_data);
	rc = sde_hdcp_2x_register(&register_data);
	if (rc) {
		pr_err("Unable to register with HDCP 2.2 library\n");
		goto error;
	}
	} else {
		rc = 0;
		goto error;
	}

	if (IS_ENABLED(CONFIG_HDCP_QSEECOM))
		msm_hdcp_register_cb(init_data->msm_hdcp_dev, ctrl,
+1 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <linux/hdcp_qseecom.h>
#include "sde_kms.h"

enum sde_hdcp_client_id {
@@ -99,6 +100,5 @@ void sde_hdcp_1x_deinit(void *input);
struct sde_hdcp_ops *sde_hdcp_1x_start(void *input);
void *sde_dp_hdcp2p2_init(struct sde_hdcp_init_data *init_data);
void sde_dp_hdcp2p2_deinit(void *input);
const char *sde_hdcp_state_name(enum sde_hdcp_state hdcp_state);
struct sde_hdcp_ops *sde_dp_hdcp2p2_start(void *input);
#endif /* __SDE_HDCP_H__ */
+31 −15
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@
#include <linux/stat.h>
#include <linux/iopoll.h>
#include <linux/msm_hdcp.h>
#include <linux/hdcp_qseecom.h>
#include <drm/drm_dp_helper.h>
#include "sde_hdcp.h"
#include "hdmi.xml.h"
@@ -225,6 +224,7 @@ struct sde_hdcp_1x {
	struct sde_hdcp_int_set int_set;
	struct sde_hdcp_sink_addr_map sink_addr;
	struct workqueue_struct *workq;
	void *hdcp1_handle;
};

static int sde_hdcp_1x_count_one(u8 *array, u8 len)
@@ -269,16 +269,11 @@ static int sde_hdcp_1x_load_keys(void *input)
	dp_link = hdcp->init_data.dp_link;
	reg_set = &hdcp->reg_set;

	if (!IS_ENABLED(CONFIG_HDCP_QSEECOM)) {
		rc = -EINVAL;
		goto end;
	} else {
		if (hdcp1_set_keys(&aksv_msb, &aksv_lsb)) {
	if (hdcp1_set_keys(hdcp->hdcp1_handle, &aksv_msb, &aksv_lsb)) {
		pr_err("setting hdcp SW keys failed\n");
		rc = -EINVAL;
		goto end;
	}
	}

	pr_debug("%s: AKSV=%02x%08x\n", SDE_HDCP_STATE_NAME,
		aksv_msb, aksv_lsb);
@@ -1109,8 +1104,7 @@ static void sde_hdcp_1x_auth_work(struct work_struct *work)
	 * program hw to enable encryption as soon as
	 * authentication is successful.
	 */
	if (IS_ENABLED(CONFIG_HDCP_QSEECOM))
		hdcp1_set_enc(true);
	hdcp1_set_enc(hdcp->hdcp1_handle, true);

	rc = sde_hdcp_1x_authentication_part1(hdcp);
	if (rc)
@@ -1258,8 +1252,7 @@ static void sde_hdcp_1x_off(void *input)
		pr_debug("%s: Deleted hdcp auth work\n",
			SDE_HDCP_STATE_NAME);

	if (IS_ENABLED(CONFIG_HDCP_QSEECOM))
		hdcp1_set_enc(false);
	hdcp1_set_enc(hdcp->hdcp1_handle, false);

	reg = DSS_REG_R(io, reg_set->reset);
	DSS_REG_W(io, reg_set->reset, reg | reg_set->reset_bit);
@@ -1369,6 +1362,18 @@ static int sde_hdcp_1x_isr(void *input)
	return rc;
}

static bool sde_hdcp_1x_feature_supported(void *input)
{
	struct sde_hdcp_1x *hdcp = (struct sde_hdcp_1x *)input;

	if (!hdcp) {
		pr_err("invalid input\n");
		return -EINVAL;
	}

	return hdcp1_feature_supported(hdcp->hdcp1_handle);
}

void sde_hdcp_1x_deinit(void *input)
{
	struct sde_hdcp_1x *hdcp = (struct sde_hdcp_1x *)input;
@@ -1381,6 +1386,8 @@ void sde_hdcp_1x_deinit(void *input)
	if (hdcp->workq)
		destroy_workqueue(hdcp->workq);

	hdcp1_deinit(hdcp->hdcp1_handle);

	kfree(hdcp);
} /* hdcp_1x_deinit */

@@ -1484,6 +1491,7 @@ void *sde_hdcp_1x_init(struct sde_hdcp_init_data *init_data)
		.cp_irq = sde_hdcp_1x_cp_irq,
		.reauthenticate = sde_hdcp_1x_reauthenticate,
		.authenticate = sde_hdcp_1x_authenticate,
		.feature_supported = sde_hdcp_1x_feature_supported,
		.off = sde_hdcp_1x_off
	};

@@ -1511,8 +1519,13 @@ void *sde_hdcp_1x_init(struct sde_hdcp_init_data *init_data)
	hdcp->workq = create_workqueue(name);
	if (!hdcp->workq) {
		pr_err("Error creating workqueue\n");
		kfree(hdcp);
		goto error;
		goto workqueue_error;
	}

	hdcp->hdcp1_handle = hdcp1_init();
	if (!hdcp->hdcp1_handle) {
		pr_err("Error creating HDCP 1.x handle\n");
		goto hdcp1_handle_error;
	}

	sde_hdcp_1x_update_client_reg_set(hdcp);
@@ -1527,7 +1540,10 @@ void *sde_hdcp_1x_init(struct sde_hdcp_init_data *init_data)
		SDE_HDCP_STATE_NAME);

	return (void *)hdcp;

hdcp1_handle_error:
	destroy_workqueue(hdcp->workq);
workqueue_error:
	kfree(hdcp);
error:
	return NULL;
} /* hdcp_1x_init */
Loading