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

Commit 40af4300 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mdss: hdmi: add dynamic encryption enable support"

parents 65aa9393 4da7b6d7
Loading
Loading
Loading
Loading
+224 −141
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@
#define REPEATER_AUTH_STREAM_MANAGE_MESSAGE_ID 16
#define REPEATER_AUTH_STREAM_READY_MESSAGE_ID  17
#define HDCP1_SET_KEY_MESSAGE_ID       202
#define HDCP1_SET_ENC_MESSAGE_ID       205

#define BITS_8_IN_BYTES       1
#define BITS_16_IN_BYTES      2
@@ -126,11 +127,12 @@
/*This API calls the library deinit function */
#define HDCP_LIB_DEINIT                           SERVICE_TXMTR_CREATE_CMD(12)

enum hdcp_app_status {
	LOADED,
	UNLOADED,
	FAILED = -1,
};
#define HDCP_LIB_EXECUTE(x) {\
	if (handle->tethered)\
		hdcp_lib_##x(handle);\
	else\
		queue_kthread_work(&handle->worker, &handle->wk_##x);\
}

enum hdcp_state {
	HDCP_STATE_INIT = 0x00,
@@ -315,6 +317,16 @@ struct __attribute__ ((__packed__)) repeater_info_struct {
	uint32_t ReceiverIDListLen;
};

struct __attribute__ ((__packed__)) hdcp1_set_enc_req {
	uint32_t commandid;
	uint32_t enable;
};

struct __attribute__ ((__packed__)) hdcp1_set_enc_rsp {
	uint32_t commandid;
	uint32_t ret;
};

/*
 * struct hdcp_lib_handle - handle for hdcp client
 * @qseecom_handle - for sending commands to qseecom
@@ -337,12 +349,12 @@ struct hdcp_lib_handle {
	bool feature_supported;
	void *client_ctx;
	struct hdcp_client_ops *client_ops;
	struct mutex hdcp_lock;
	struct mutex msg_lock;
	struct mutex wakeup_mutex;
	enum hdcp_state hdcp_state;
	enum hdcp_lib_wakeup_cmd wakeup_cmd;
	bool repeater_flag;
	bool tethered;
	struct qseecom_handle *qseecom_handle;
	int last_msg_sent;
	char *last_msg_recvd_buf;
@@ -353,13 +365,13 @@ struct hdcp_lib_handle {
	struct completion topo_wait;

	struct kthread_worker worker;
	struct kthread_work init;
	struct kthread_work msg_sent;
	struct kthread_work msg_recvd;
	struct kthread_work timeout;
	struct kthread_work clean;
	struct kthread_work topology;
	struct kthread_work stream;
	struct kthread_work wk_init;
	struct kthread_work wk_msg_sent;
	struct kthread_work wk_msg_recvd;
	struct kthread_work wk_timeout;
	struct kthread_work wk_clean;
	struct kthread_work wk_topology;
	struct kthread_work wk_stream;
};

struct hdcp_lib_message_map {
@@ -367,6 +379,13 @@ struct hdcp_lib_message_map {
	const char *msg_name;
};

static void hdcp_lib_clean(struct hdcp_lib_handle *handle);
static void hdcp_lib_init(struct hdcp_lib_handle *handle);
static void hdcp_lib_msg_sent(struct hdcp_lib_handle *handle);
static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle);
static void hdcp_lib_timeout(struct hdcp_lib_handle *handle);
static void hdcp_lib_stream(struct hdcp_lib_handle *handle);

static struct qseecom_handle *hdcp1_handle;
static bool hdcp1_supported = true;

@@ -467,7 +486,7 @@ static int hdcp_lib_enable_encryption(struct hdcp_lib_handle *handle)
	return 0;
error:
	if (!atomic_read(&handle->hdcp_off))
		queue_kthread_work(&handle->worker, &handle->clean);
		HDCP_LIB_EXECUTE(clean);

	return rc;
}
@@ -678,21 +697,17 @@ exit:
	return rc;
}

static void hdcp_lib_query_stream_type_work(struct kthread_work *work)
static void hdcp_lib_stream(struct hdcp_lib_handle *handle)
{
	int rc = 0;
	struct hdcp_query_stream_type_req *req_buf;
	struct hdcp_query_stream_type_rsp *rsp_buf;
	struct hdcp_lib_handle *handle = container_of(work,
		struct hdcp_lib_handle, stream);

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

	mutex_lock(&handle->hdcp_lock);

	/* send command to TZ */
	req_buf = (struct hdcp_query_stream_type_req *)handle->
			qseecom_handle->sbuf;
@@ -724,12 +739,18 @@ static void hdcp_lib_query_stream_type_work(struct kthread_work *work)
	handle->hdcp_timeout = rsp_buf->timeout;
	handle->msglen = rsp_buf->msglen;
exit:
	mutex_unlock(&handle->hdcp_lock);

	if (!rc && !atomic_read(&handle->hdcp_off))
		hdcp_lib_send_message(handle);
}

static void hdcp_lib_query_stream_work(struct kthread_work *work)
{
	struct hdcp_lib_handle *handle = container_of(work,
		struct hdcp_lib_handle, wk_stream);

	hdcp_lib_stream(handle);
}

static bool hdcp_lib_client_feature_supported(void *phdcpcontext)
{
	int rc = 0;
@@ -759,46 +780,46 @@ exit:

static void hdcp_lib_check_worker_status(struct hdcp_lib_handle *handle)
{
	if (!list_empty(&handle->init.node))
	if (!list_empty(&handle->wk_init.node))
		pr_debug("init work queued\n");

	if (handle->worker.current_work == &handle->init)
	if (handle->worker.current_work == &handle->wk_init)
		pr_debug("init work executing\n");

	if (!list_empty(&handle->msg_sent.node))
	if (!list_empty(&handle->wk_msg_sent.node))
		pr_debug("msg_sent work queued\n");

	if (handle->worker.current_work == &handle->msg_sent)
	if (handle->worker.current_work == &handle->wk_msg_sent)
		pr_debug("msg_sent work executing\n");

	if (!list_empty(&handle->msg_recvd.node))
	if (!list_empty(&handle->wk_msg_recvd.node))
		pr_debug("msg_recvd work queued\n");

	if (handle->worker.current_work == &handle->msg_recvd)
	if (handle->worker.current_work == &handle->wk_msg_recvd)
		pr_debug("msg_recvd work executing\n");

	if (!list_empty(&handle->timeout.node))
	if (!list_empty(&handle->wk_timeout.node))
		pr_debug("timeout work queued\n");

	if (handle->worker.current_work == &handle->timeout)
	if (handle->worker.current_work == &handle->wk_timeout)
		pr_debug("timeout work executing\n");

	if (!list_empty(&handle->clean.node))
	if (!list_empty(&handle->wk_clean.node))
		pr_debug("clean work queued\n");

	if (handle->worker.current_work == &handle->clean)
	if (handle->worker.current_work == &handle->wk_clean)
		pr_debug("clean work executing\n");

	if (!list_empty(&handle->topology.node))
	if (!list_empty(&handle->wk_topology.node))
		pr_debug("topology work queued\n");

	if (handle->worker.current_work == &handle->topology)
	if (handle->worker.current_work == &handle->wk_topology)
		pr_debug("topology work executing\n");

	if (!list_empty(&handle->stream.node))
	if (!list_empty(&handle->wk_stream.node))
		pr_debug("stream work queued\n");

	if (handle->worker.current_work == &handle->stream)
	if (handle->worker.current_work == &handle->wk_stream)
		pr_debug("stream work executing\n");
}

@@ -829,6 +850,28 @@ exit:
	return rc;
}

static void hdcp_lib_update_exec_type(void *ctx, bool tethered)
{
	struct hdcp_lib_handle *handle = ctx;

	if (!handle)
		return;

	mutex_lock(&handle->wakeup_mutex);

	if (handle->tethered == tethered) {
		pr_debug("exec mode same as %s\n",
			tethered ? "tethered" : "threaded");
	} else {
		handle->tethered = tethered;

		pr_debug("exec mode changed to %s\n",
			tethered ? "tethered" : "threaded");
	}

	mutex_unlock(&handle->wakeup_mutex);
}

static int hdcp_lib_wakeup(struct hdcp_lib_wakeup_data *data)
{
	struct hdcp_lib_handle *handle;
@@ -846,9 +889,9 @@ static int hdcp_lib_wakeup(struct hdcp_lib_wakeup_data *data)
	handle->wakeup_cmd = data->cmd;
	handle->timeout_left = data->timeout;

	pr_debug("%s, timeout left: %dms\n",
	pr_debug("%s, timeout left: %dms, tethered %d\n",
		hdcp_lib_cmd_to_str(handle->wakeup_cmd),
		handle->timeout_left);
		handle->timeout_left, handle->tethered);

	rc = hdcp_lib_check_valid_state(handle);
	if (rc)
@@ -885,42 +928,42 @@ static int hdcp_lib_wakeup(struct hdcp_lib_wakeup_data *data)
		atomic_set(&handle->hdcp_off, 0);
		handle->hdcp_state = HDCP_STATE_INIT;

		queue_kthread_work(&handle->worker, &handle->init);
		HDCP_LIB_EXECUTE(init);
		break;
	case HDCP_LIB_WKUP_CMD_STOP:
		atomic_set(&handle->hdcp_off, 1);
		queue_kthread_work(&handle->worker, &handle->clean);

		HDCP_LIB_EXECUTE(clean);
		break;
	case HDCP_LIB_WKUP_CMD_MSG_SEND_SUCCESS:
		handle->last_msg_sent = handle->listener_buf[0];

		queue_kthread_work(&handle->worker, &handle->msg_sent);
		HDCP_LIB_EXECUTE(msg_sent);
		break;
	case HDCP_LIB_WKUP_CMD_MSG_SEND_FAILED:
	case HDCP_LIB_WKUP_CMD_MSG_RECV_FAILED:
		queue_kthread_work(&handle->worker, &handle->clean);
		HDCP_LIB_EXECUTE(clean);
		break;
	case HDCP_LIB_WKUP_CMD_MSG_RECV_SUCCESS:
		queue_kthread_work(&handle->worker, &handle->msg_recvd);
		HDCP_LIB_EXECUTE(msg_recvd);
		break;
	case HDCP_LIB_WKUP_CMD_MSG_RECV_TIMEOUT:
		queue_kthread_work(&handle->worker, &handle->timeout);
		HDCP_LIB_EXECUTE(timeout);
		break;
	case HDCP_LIB_WKUP_CMD_QUERY_STREAM_TYPE:
		queue_kthread_work(&handle->worker, &handle->stream);
		HDCP_LIB_EXECUTE(stream);
		break;
	default:
		pr_err("invalid wakeup command %d\n", handle->wakeup_cmd);
	}
exit:
	mutex_unlock(&handle->wakeup_mutex);

	return rc;
}

static void hdcp_lib_msg_sent_work(struct kthread_work *work)
static void hdcp_lib_msg_sent(struct hdcp_lib_handle *handle)
{
	struct hdcp_lib_handle *handle = container_of(work,
		struct hdcp_lib_handle, msg_sent);
	struct hdmi_hdcp_wakeup_data cdata = {HDMI_HDCP_WKUP_CMD_INVALID};

	if (!handle) {
@@ -928,13 +971,6 @@ static void hdcp_lib_msg_sent_work(struct kthread_work *work)
		return;
	}

	if (handle->wakeup_cmd != HDCP_LIB_WKUP_CMD_MSG_SEND_SUCCESS) {
		pr_err("invalid wakeup command %d\n", handle->wakeup_cmd);
		return;
	}

	mutex_lock(&handle->hdcp_lock);

	cdata.context = handle->client_ctx;

	switch (handle->last_msg_sent) {
@@ -942,15 +978,15 @@ static void hdcp_lib_msg_sent_work(struct kthread_work *work)
		if (handle->repeater_flag) {
			if (!atomic_read(&handle->hdcp_off))
				queue_kthread_work(&handle->worker,
					&handle->topology);
					&handle->wk_topology);
		}

		if (!hdcp_lib_enable_encryption(handle))
		if (!hdcp_lib_enable_encryption(handle)) {
			cdata.cmd = HDMI_HDCP_WKUP_CMD_STATUS_SUCCESS;
		else
		} else {
			if (!atomic_read(&handle->hdcp_off))
				queue_kthread_work(&handle->worker,
					&handle->clean);
				HDCP_LIB_EXECUTE(clean);
		}
		break;
	case REPEATER_AUTH_SEND_ACK_MESSAGE_ID:
		pr_debug("Repeater authentication successful\n");
@@ -960,26 +996,36 @@ static void hdcp_lib_msg_sent_work(struct kthread_work *work)
		cdata.timeout = handle->timeout_left;
	}

	mutex_unlock(&handle->hdcp_lock);

	hdcp_lib_wakeup_client(handle, &cdata);
}

static void hdcp_lib_init_work(struct kthread_work *work)
static void hdcp_lib_msg_sent_work(struct kthread_work *work)
{
	int rc = 0;
	bool send_msg = false;
	struct hdcp_lib_handle *handle = container_of(work,
		struct hdcp_lib_handle, init);
		struct hdcp_lib_handle, wk_msg_sent);

	if (handle->wakeup_cmd != HDCP_LIB_WKUP_CMD_MSG_SEND_SUCCESS) {
		pr_err("invalid wakeup command %d\n", handle->wakeup_cmd);
		return;
	}

	hdcp_lib_msg_sent(handle);
}

static void hdcp_lib_init(struct hdcp_lib_handle *handle)
{
	int rc = 0;

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

	mutex_lock(&handle->hdcp_lock);
	if (handle->wakeup_cmd != HDCP_LIB_WKUP_CMD_START) {
		pr_err("invalid wakeup command %d\n", handle->wakeup_cmd);
		return;
	}

	if (handle->wakeup_cmd == HDCP_LIB_WKUP_CMD_START) {
	rc = hdcp_lib_library_load(handle);
	if (rc)
		goto exit;
@@ -988,44 +1034,32 @@ static void hdcp_lib_init_work(struct kthread_work *work)
	if (rc)
		goto exit;

		send_msg = true;
	} else if (handle->wakeup_cmd == HDCP_LIB_WKUP_CMD_STOP) {
		rc = hdcp_lib_txmtr_deinit(handle);
		if (rc)
			goto exit;
	hdcp_lib_send_message(handle);

		rc = hdcp_lib_library_unload(handle);
		if (rc)
			goto exit;
	} else {
		pr_err("invalid wakeup cmd: %d\n", handle->wakeup_cmd);
	}
	return;
exit:
	mutex_unlock(&handle->hdcp_lock);
	HDCP_LIB_EXECUTE(clean);
}

	if (send_msg)
		hdcp_lib_send_message(handle);
static void hdcp_lib_init_work(struct kthread_work *work)
{
	struct hdcp_lib_handle *handle = container_of(work,
		struct hdcp_lib_handle, wk_init);

	if (rc && !atomic_read(&handle->hdcp_off))
		queue_kthread_work(&handle->worker, &handle->clean);
	hdcp_lib_init(handle);
}

static void hdcp_lib_manage_timeout_work(struct kthread_work *work)
static void hdcp_lib_timeout(struct hdcp_lib_handle *handle)
{
	int rc = 0;
	bool send_msg = false;
	struct hdcp_send_timeout_req *req_buf;
	struct hdcp_send_timeout_rsp *rsp_buf;
	struct hdcp_lib_handle *handle = container_of(work,
		struct hdcp_lib_handle, timeout);

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

	mutex_lock(&handle->hdcp_lock);

	req_buf = (struct hdcp_send_timeout_req *)
		(handle->qseecom_handle->sbuf);
	req_buf->commandid = HDCP_TXMTR_SEND_MESSAGE_TIMEOUT;
@@ -1068,23 +1102,24 @@ static void hdcp_lib_manage_timeout_work(struct kthread_work *work)
			handle->hdcp_timeout = rsp_buf->timeout;
			handle->msglen = rsp_buf->msglen;

			send_msg = true;
			hdcp_lib_send_message(handle);
		}
	}
error:
	mutex_unlock(&handle->hdcp_lock);
	if (!atomic_read(&handle->hdcp_off))
		HDCP_LIB_EXECUTE(clean);
}

	if (send_msg)
		hdcp_lib_send_message(handle);
static void hdcp_lib_manage_timeout_work(struct kthread_work *work)
{
	struct hdcp_lib_handle *handle = container_of(work,
		struct hdcp_lib_handle, wk_timeout);

	if (rc && !atomic_read(&handle->hdcp_off))
		queue_kthread_work(&handle->worker, &handle->clean);
	hdcp_lib_timeout(handle);
}

static void hdcp_lib_cleanup_work(struct kthread_work *work)
static void hdcp_lib_clean(struct hdcp_lib_handle *handle)
{
	struct hdcp_lib_handle *handle = container_of(work,
		struct hdcp_lib_handle, clean);
	struct hdmi_hdcp_wakeup_data cdata = {HDMI_HDCP_WKUP_CMD_INVALID};

	if (!handle) {
@@ -1092,15 +1127,11 @@ static void hdcp_lib_cleanup_work(struct kthread_work *work)
		return;
	};

	mutex_lock(&handle->hdcp_lock);

	cdata.context = handle->client_ctx;
	cdata.cmd = HDMI_HDCP_WKUP_CMD_STATUS_FAILED;

	hdcp_lib_txmtr_deinit(handle);
	hdcp_lib_library_unload(handle);

	mutex_unlock(&handle->hdcp_lock);
	cdata.context = handle->client_ctx;
	cdata.cmd = HDMI_HDCP_WKUP_CMD_STATUS_FAILED;

	if (!atomic_read(&handle->hdcp_off))
		hdcp_lib_wakeup_client(handle, &cdata);
@@ -1108,23 +1139,29 @@ static void hdcp_lib_cleanup_work(struct kthread_work *work)
	atomic_set(&handle->hdcp_off, 1);
}

static void hdcp_lib_msg_recvd_work(struct kthread_work *work)

static void hdcp_lib_cleanup_work(struct kthread_work *work)
{
	struct hdcp_lib_handle *handle = container_of(work,
		struct hdcp_lib_handle, wk_clean);

	hdcp_lib_clean(handle);
}

static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle)
{
	int rc = 0;
	struct hdmi_hdcp_wakeup_data cdata = {HDMI_HDCP_WKUP_CMD_INVALID};
	struct hdcp_rcvd_msg_req *req_buf;
	struct hdcp_rcvd_msg_rsp *rsp_buf;
	uint32_t msglen;
	char *msg;
	struct hdcp_lib_handle *handle = container_of(work,
		struct hdcp_lib_handle, msg_recvd);
	struct hdmi_hdcp_wakeup_data cdata = {HDMI_HDCP_WKUP_CMD_INVALID};

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

	mutex_lock(&handle->hdcp_lock);
	cdata.context = handle->client_ctx;

	mutex_lock(&handle->msg_lock);
@@ -1233,19 +1270,26 @@ static void hdcp_lib_msg_recvd_work(struct kthread_work *work)

exit:
	kzfree(msg);
	mutex_unlock(&handle->hdcp_lock);

	hdcp_lib_wakeup_client(handle, &cdata);

	if (rc && !atomic_read(&handle->hdcp_off))
		queue_kthread_work(&handle->worker, &handle->clean);
		HDCP_LIB_EXECUTE(clean);
}

static void hdcp_lib_msg_recvd_work(struct kthread_work *work)
{
	struct hdcp_lib_handle *handle = container_of(work,
		struct hdcp_lib_handle, wk_msg_recvd);

	hdcp_lib_msg_recvd(handle);
}

static void hdcp_lib_topology_work(struct kthread_work *work)
{
	u32 timeout;
	struct hdcp_lib_handle *handle = container_of(work,
		struct hdcp_lib_handle, topology);
		struct hdcp_lib_handle, wk_topology);

	if (!handle) {
		pr_err("invalid input\n");
@@ -1258,7 +1302,7 @@ static void hdcp_lib_topology_work(struct kthread_work *work)
		pr_err("topology receiver id list timeout\n");

		if (!atomic_read(&handle->hdcp_off))
			queue_kthread_work(&handle->worker, &handle->clean);
			HDCP_LIB_EXECUTE(clean);
	}
}

@@ -1329,32 +1373,70 @@ int hdcp1_set_keys(uint32_t *aksv_msb, uint32_t *aksv_lsb)
	return 0;
}

int hdcp_library_register(void **pphdcpcontext,
	struct hdcp_client_ops *client_ops,
	struct hdcp_txmtr_ops *txmtr_ops,
	void *client_ctx)
int hdcp1_set_enc(bool enable)
{
	int rc = 0;
	struct hdcp1_set_enc_req *set_enc_req;
	struct hdcp1_set_enc_rsp *set_enc_rsp;

	if (!hdcp1_supported || !hdcp1_handle)
		return -EINVAL;

	/* set keys and request aksv */
	set_enc_req = (struct hdcp1_set_enc_req *)hdcp1_handle->sbuf;
	set_enc_req->commandid = HDCP1_SET_ENC_MESSAGE_ID;
	set_enc_req->enable = enable;
	set_enc_rsp = (struct hdcp1_set_enc_rsp *)(hdcp1_handle->sbuf +
			QSEECOM_ALIGN(sizeof(struct hdcp1_set_enc_req)));
	rc = qseecom_send_command(hdcp1_handle,
		set_enc_req, QSEECOM_ALIGN(sizeof(struct hdcp1_set_enc_req)),
		set_enc_rsp, QSEECOM_ALIGN(sizeof(struct hdcp1_set_enc_rsp)));

	if (rc < 0) {
		pr_err("qseecom cmd failed err=%d\n", rc);
		return -EINVAL;
	}

	rc = set_enc_rsp->ret;
	if (rc) {
		pr_err("enc cmd failed, rsp=%d\n",
			set_enc_rsp->ret);
		return -EINVAL;
	}

	pr_debug("success\n");
	return 0;
}

int hdcp_library_register(struct hdcp_register_data *data)
{
	int rc = 0;
	struct hdcp_lib_handle *handle = NULL;

	if (!pphdcpcontext) {
		pr_err("invalid input: context passed\n");
	if (!data) {
		pr_err("invalid input\n");
		return -EINVAL;
	}

	if (!txmtr_ops) {
	if (!data->txmtr_ops) {
		pr_err("invalid input: txmtr context\n");
		return -EINVAL;
	}

	if (!client_ops) {
	if (!data->client_ops) {
		pr_err("invalid input: client_ops\n");
		return -EINVAL;
	}

	if (!data->hdcp_ctx) {
		pr_err("invalid input: hdcp_ctx\n");
		return -EINVAL;
	}

	/* populate ops to be called by client */
	txmtr_ops->feature_supported = hdcp_lib_client_feature_supported;
	txmtr_ops->wakeup = hdcp_lib_wakeup;
	data->txmtr_ops->feature_supported = hdcp_lib_client_feature_supported;
	data->txmtr_ops->wakeup = hdcp_lib_wakeup;
	data->txmtr_ops->update_exec_type = hdcp_lib_update_exec_type;

	handle = kzalloc(sizeof(*handle), GFP_KERNEL);
	if (!handle) {
@@ -1362,24 +1444,26 @@ int hdcp_library_register(void **pphdcpcontext,
		goto unlock;
	}

	handle->client_ctx = client_ctx;
	handle->client_ops = client_ops;
	handle->client_ctx = data->client_ctx;
	handle->client_ops = data->client_ops;
	handle->tethered = data->tethered;

	pr_debug("tethered %d\n", handle->tethered);

	atomic_set(&handle->hdcp_off, 0);

	mutex_init(&handle->hdcp_lock);
	mutex_init(&handle->msg_lock);
	mutex_init(&handle->wakeup_mutex);

	init_kthread_worker(&handle->worker);

	init_kthread_work(&handle->init,      hdcp_lib_init_work);
	init_kthread_work(&handle->msg_sent,  hdcp_lib_msg_sent_work);
	init_kthread_work(&handle->msg_recvd, hdcp_lib_msg_recvd_work);
	init_kthread_work(&handle->timeout,   hdcp_lib_manage_timeout_work);
	init_kthread_work(&handle->clean,     hdcp_lib_cleanup_work);
	init_kthread_work(&handle->topology,  hdcp_lib_topology_work);
	init_kthread_work(&handle->stream,    hdcp_lib_query_stream_type_work);
	init_kthread_work(&handle->wk_init,      hdcp_lib_init_work);
	init_kthread_work(&handle->wk_msg_sent,  hdcp_lib_msg_sent_work);
	init_kthread_work(&handle->wk_msg_recvd, hdcp_lib_msg_recvd_work);
	init_kthread_work(&handle->wk_timeout,   hdcp_lib_manage_timeout_work);
	init_kthread_work(&handle->wk_clean,     hdcp_lib_cleanup_work);
	init_kthread_work(&handle->wk_topology,  hdcp_lib_topology_work);
	init_kthread_work(&handle->wk_stream,    hdcp_lib_query_stream_work);

	init_completion(&handle->topo_wait);

@@ -1389,7 +1473,7 @@ int hdcp_library_register(void **pphdcpcontext,
		goto error;
	}

	*((struct hdcp_lib_handle **)pphdcpcontext) = handle;
	*data->hdcp_ctx = handle;

	handle->thread = kthread_run(kthread_worker_fn,
		&handle->worker, "hdcp_tz_lib");
@@ -1423,7 +1507,6 @@ void hdcp_library_deregister(void *phdcpcontext)
	kzfree(handle->qseecom_handle);
	kzfree(handle->last_msg_recvd_buf);

	mutex_destroy(&handle->hdcp_lock);
	mutex_destroy(&handle->wakeup_mutex);

	kzfree(handle->listener_buf);
+2 −7
Original line number Diff line number Diff line
@@ -372,7 +372,6 @@ static int hdmi_hdcp_authentication_part1(struct hdmi_hdcp_ctrl *hdcp_ctrl)
	ddc_data.request_len = 1;
	ddc_data.retry = 5;
	ddc_data.what = "Bcaps";
	ddc_data.no_align = true;

	hdcp_ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;

@@ -574,7 +573,6 @@ static int hdmi_hdcp_authentication_part1(struct hdmi_hdcp_ctrl *hdcp_ctrl)
	ddc_data.request_len = 5;
	ddc_data.retry = 5;
	ddc_data.what = "Bksv";
	ddc_data.no_align = true;

	hdcp_ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;

@@ -649,7 +647,6 @@ static int hdmi_hdcp_authentication_part1(struct hdmi_hdcp_ctrl *hdcp_ctrl)
	ddc_data.request_len = 2;
	ddc_data.retry = 5;
	ddc_data.what = "R0'";
	ddc_data.no_align = true;

	hdcp_ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;

@@ -758,7 +755,6 @@ static int hdmi_hdcp_transfer_v_h(struct hdmi_hdcp_ctrl *hdcp_ctrl)
	ddc_data.request_len = 4;
	ddc_data.retry = 5;
	ddc_data.what = what;
	ddc_data.no_align = true;

	if (hdcp_ctrl->tz_hdcp) {
		memset(scm_buf, 0x00, sizeof(scm_buf));
@@ -888,7 +884,7 @@ static int hdmi_hdcp_authentication_part2(struct hdmi_hdcp_ctrl *hdcp_ctrl)
		ddc_data.request_len = 1;
		ddc_data.retry = 5;
		ddc_data.what = "Bcaps";
		ddc_data.no_align = false;
		ddc_data.retry_align = true;

		hdcp_ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;

@@ -910,7 +906,7 @@ static int hdmi_hdcp_authentication_part2(struct hdmi_hdcp_ctrl *hdcp_ctrl)
	ddc_data.request_len = 2;
	ddc_data.retry = 5;
	ddc_data.what = "Bstatuss";
	ddc_data.no_align = false;
	ddc_data.retry_align = true;

	hdcp_ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;

@@ -1005,7 +1001,6 @@ static int hdmi_hdcp_authentication_part2(struct hdmi_hdcp_ctrl *hdcp_ctrl)
	ddc_data.request_len = ksv_bytes;
	ddc_data.retry = 5;
	ddc_data.what = "KSV FIFO";
	ddc_data.no_align = true;

	hdcp_ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;

+1 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ struct hdmi_hdcp_init_data {
	u32 phy_addr;
	u32 hdmi_tx_ver;
	struct msm_hdmi_mode_timing_info *timing;
	bool tethered;
};

struct hdmi_hdcp_ops {
+236 −97

File changed.

Preview size limit exceeded, changes collapsed.

+14 −4
Original line number Diff line number Diff line
@@ -1318,8 +1318,16 @@ static void hdmi_tx_hdcp_cb_work(struct work_struct *work)
			rc = hdmi_tx_config_avmute(hdmi_ctrl, false);
			hdmi_tx_set_audio_switch_node(hdmi_ctrl, 1);
		}

		if (hdmi_ctrl->hdcp1_use_sw_keys && hdmi_ctrl->hdcp14_present)
			hdcp1_set_enc(true);
		break;
	case HDCP_STATE_AUTH_FAIL:
		if (hdmi_ctrl->hdcp1_use_sw_keys && hdmi_ctrl->hdcp14_present) {
			if (hdmi_ctrl->auth_state)
				hdcp1_set_enc(false);
		}

		hdmi_ctrl->auth_state = false;

		if (hdmi_tx_is_encryption_set(hdmi_ctrl) ||
@@ -1394,7 +1402,7 @@ static u32 hdmi_tx_ddc_read(struct hdmi_tx_ddc_ctrl *ddc_ctrl,
			ddc_data.request_len = block_size;
			ddc_data.retry       = 1;
			ddc_data.what        = "EDID";
			ddc_data.no_align    = false;
			ddc_data.retry_align = true;

			ddc_ctrl->ddc_data = ddc_data;

@@ -1522,9 +1530,9 @@ end:
static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl,
	struct fb_info *fbi)
{
	struct hdmi_edid_init_data edid_init_data;
	struct hdmi_hdcp_init_data hdcp_init_data;
	struct hdmi_cec_init_data cec_init_data;
	struct hdmi_edid_init_data edid_init_data = {0};
	struct hdmi_hdcp_init_data hdcp_init_data = {0};
	struct hdmi_cec_init_data cec_init_data = {0};
	struct resource *res = NULL;
	void *fd = NULL;

@@ -4240,6 +4248,8 @@ static int hdmi_tx_panel_event_handler(struct mdss_panel_data *panel_data,

	case MDSS_EVENT_BLANK:
		if (hdmi_tx_is_hdcp_enabled(hdmi_ctrl)) {
			flush_delayed_work(&hdmi_ctrl->hdcp_cb_work);

			DEV_DBG("%s: Turning off HDCP\n", __func__);
			hdmi_ctrl->hdcp_ops->hdmi_hdcp_off(
				hdmi_ctrl->hdcp_data);
Loading