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

Commit 8ac23627 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "disp: msm: dp: Enforce HDCP 2.3 timing requirements"

parents c11a1680 77d5354c
Loading
Loading
Loading
Loading
+21 −11
Original line number Diff line number Diff line
@@ -44,7 +44,8 @@ struct dp_hdcp2p2_ctrl {
	struct hdcp2_buffer response;
	struct hdcp2_buffer request;
	uint32_t total_message_length;
	uint32_t timeout;
	uint32_t transaction_delay;
	uint32_t transaction_timeout;
	struct sde_hdcp_2x_msg_part msg_part[HDCP_MAX_MESSAGE_PARTS];
	u8 sink_rx_status;
	u8 rx_status;
@@ -108,7 +109,6 @@ static int dp_hdcp2p2_copy_buf(struct dp_hdcp2p2_ctrl *ctrl,

	mutex_lock(&ctrl->msg_lock);

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

@@ -132,6 +132,9 @@ static int dp_hdcp2p2_copy_buf(struct dp_hdcp2p2_ctrl *ctrl,
	ctrl->request.data = data->buf;
	ctrl->request.length = ctrl->total_message_length;

	ctrl->transaction_delay = data->transaction_delay;
	ctrl->transaction_timeout = data->transaction_timeout;

	mutex_unlock(&ctrl->msg_lock);

	return 0;
@@ -170,7 +173,6 @@ static void dp_hdcp2p2_set_interrupts(struct dp_hdcp2p2_ctrl *ctrl, bool enable)
static int dp_hdcp2p2_wakeup(struct hdcp_transport_wakeup_data *data)
{
	struct dp_hdcp2p2_ctrl *ctrl;
	u32 const default_timeout_us = 500;

	if (!data) {
		DP_ERR("invalid input\n");
@@ -183,11 +185,6 @@ static int dp_hdcp2p2_wakeup(struct hdcp_transport_wakeup_data *data)
		return -EINVAL;
	}

	if (data->timeout)
		ctrl->timeout = (data->timeout) * 2;
	else
		ctrl->timeout = default_timeout_us;

	if (dp_hdcp2p2_copy_buf(ctrl, data))
		goto exit;

@@ -364,6 +361,8 @@ static int dp_hdcp2p2_aux_read_message(struct dp_hdcp2p2_ctrl *ctrl)
	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;
	s64 diff_ms;
	ktime_t start_read, finish_read;

	if (atomic_read(&ctrl->auth_state) == HDCP_STATE_INACTIVE ||
		atomic_read(&ctrl->auth_state) == HDCP_STATE_AUTH_FAIL) {
@@ -380,6 +379,7 @@ static int dp_hdcp2p2_aux_read_message(struct dp_hdcp2p2_ctrl *ctrl)

	DP_DEBUG("offset(0x%x), size(%d)\n", offset, size);

	start_read = ktime_get();
	do {
		read_size = min(size, max_size);

@@ -396,7 +396,14 @@ static int dp_hdcp2p2_aux_read_message(struct dp_hdcp2p2_ctrl *ctrl)
		offset += read_size;
		size -= read_size;
	} while (size > 0);
	finish_read = ktime_get();
	diff_ms = ktime_ms_delta(finish_read, start_read);

	if (ctrl->transaction_timeout && diff_ms > ctrl->transaction_timeout) {
		DP_ERR("HDCP read timeout exceeded (%dms > %dms)\n", diff_ms,
				ctrl->transaction_timeout);
		rc = -ETIMEDOUT;
	}
exit:
	return rc;
}
@@ -485,7 +492,7 @@ static void dp_hdcp2p2_send_msg(struct dp_hdcp2p2_ctrl *ctrl)

	rc = dp_hdcp2p2_aux_write_message(ctrl, ctrl->response.data,
			ctrl->response.length, ctrl->msg_part->offset,
			ctrl->timeout);
			ctrl->transaction_delay);
	if (rc) {
		DP_ERR("Error sending msg to sink %d\n", rc);
		mutex_unlock(&ctrl->msg_lock);
@@ -493,7 +500,7 @@ static void dp_hdcp2p2_send_msg(struct dp_hdcp2p2_ctrl *ctrl)
	}

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

exit:
@@ -519,7 +526,7 @@ static int dp_hdcp2p2_get_msg_from_sink(struct dp_hdcp2p2_ctrl *ctrl)
	}

	cdata.total_message_length = ctrl->total_message_length;
	cdata.timeout = ctrl->timeout;
	cdata.timeout = ctrl->transaction_delay;
exit:
	if (rc == -ETIMEDOUT)
		cdata.cmd = HDCP_2X_CMD_MSG_RECV_TIMEOUT;
@@ -544,6 +551,9 @@ static void dp_hdcp2p2_recv_msg(struct dp_hdcp2p2_ctrl *ctrl)
		return;
	}

	if (ctrl->transaction_delay)
		msleep(ctrl->transaction_delay);

	dp_hdcp2p2_get_msg_from_sink(ctrl);
}

+46 −19
Original line number Diff line number Diff line
@@ -42,6 +42,9 @@
#define REAUTH_REQ BIT(3)
#define LINK_INTEGRITY_FAILURE BIT(4)

/* Temporary define to override wrong TZ value */
#define AKE_SEND_CERT_MSG_DELAY 100

struct sde_hdcp_2x_ctrl {
	DECLARE_KFIFO(cmd_q, enum sde_hdcp_2x_wakeup_cmd, 8);
	wait_queue_head_t wait_q;
@@ -100,49 +103,49 @@ static const struct sde_hdcp_2x_msg_data
				hdcp_msg_lookup[HDCP2P2_MAX_MESSAGES] = {
	[AKE_INIT] = { 2,
		{ {"rtx", 0x69000, 8}, {"TxCaps", 0x69008, 3} },
		0 },
		0, 0 },
	[AKE_SEND_CERT] = { 3,
		{ {"cert-rx", 0x6900B, 522}, {"rrx", 0x69215, 8},
			{"RxCaps", 0x6921D, 3} },
		0 },
		0, 110 },
	[AKE_NO_STORED_KM] = { 1,
		{ {"Ekpub_km", 0x69220, 128} },
		0 },
		0, 0 },
	[AKE_STORED_KM] = { 2,
		{ {"Ekh_km", 0x692A0, 16}, {"m", 0x692B0, 16} },
		0 },
		0, 0 },
	[AKE_SEND_H_PRIME] = { 1,
		{ {"H'", 0x692C0, 32} },
		(1 << 1) },
		(1 << 1), 7 },
	[AKE_SEND_PAIRING_INFO] =  { 1,
		{ {"Ekh_km", 0x692E0, 16} },
		(1 << 2) },
		(1 << 2), 5 },
	[LC_INIT] = { 1,
		{ {"rn", 0x692F0, 8} },
		0 },
		0, 0 },
	[LC_SEND_L_PRIME] = { 1,
		{ {"L'", 0x692F8, 32} },
		0 },
		0, 0 },
	[SKE_SEND_EKS] = { 2,
		{ {"Edkey_ks", 0x69318, 16}, {"riv", 0x69328, 8} },
		0 },
		0, 0 },
	[SKE_SEND_TYPE_ID] = { 1,
		{ {"type", 0x69494, 1} },
		0 },
		0, 0 },
	[REP_SEND_RECV_ID_LIST] = { 4,
		{ {"RxInfo", 0x69330, 2}, {"seq_num_V", 0x69332, 3},
			{"V'", 0x69335, 16}, {"ridlist", 0x69345, 155} },
		(1 << 0) },
		(1 << 0), 0 },
	[REP_SEND_ACK] = { 1,
		{ {"V", 0x693E0, 16} },
		0 },
		0, 0 },
	[REP_STREAM_MANAGE] = { 3,
		{ {"seq_num_M", 0x693F0, 3}, {"k", 0x693F3, 2},
			{"streamID_Type", 0x693F5, 126} },
		0 },
		0, 0 },
	[REP_STREAM_READY] = { 1,
		{ {"M'", 0x69473, 32} },
		0 },
		0, 7 },
};

static int sde_hdcp_2x_get_next_message(struct sde_hdcp_2x_ctrl *hdcp,
@@ -247,6 +250,28 @@ static void sde_hdcp_2x_wait_for_response(struct sde_hdcp_2x_ctrl *hdcp)
	hdcp->wait_timeout_ms = 0;
}

static void sde_hdcp_2x_adjust_transaction_params(
		struct sde_hdcp_2x_ctrl *hdcp,
		struct hdcp_transport_wakeup_data *data)
{
	switch (hdcp->last_msg) {
	case AKE_SEND_CERT:
		data->transaction_delay = AKE_SEND_CERT_MSG_DELAY;
	case REP_STREAM_READY:
		break;
	default:
		data->transaction_delay = 0;
		break;
	}

	data->transaction_timeout =
			hdcp_msg_lookup[hdcp->last_msg].transaction_timeout;

	pr_debug("%s: transaction delay: %ums, transaction timeout: %ums\n",
			sde_hdcp_2x_message_name(hdcp->last_msg),
			data->transaction_delay, data->transaction_timeout);
}

static void sde_hdcp_2x_wakeup_client(struct sde_hdcp_2x_ctrl *hdcp,
				struct hdcp_transport_wakeup_data *data)
{
@@ -271,6 +296,8 @@ static void sde_hdcp_2x_wakeup_client(struct sde_hdcp_2x_ctrl *hdcp,
		data->message_data = &hdcp_msg_lookup[hdcp->last_msg];
	}

	sde_hdcp_2x_adjust_transaction_params(hdcp, data);

	rc = hdcp->client_ops->wakeup(data);
	if (rc)
		pr_err("error sending %s to client\n",
@@ -285,7 +312,7 @@ static inline void sde_hdcp_2x_send_message(struct sde_hdcp_2x_ctrl *hdcp)
					HDCP_TRANSPORT_CMD_SEND_MESSAGE };

	cdata.context = hdcp->client_data;
	cdata.timeout = hdcp->app_data.timeout;
	cdata.transaction_delay = hdcp->app_data.timeout;
	cdata.buf_len = hdcp->app_data.response.length;

	/* ignore the first byte as it contains the message id */
@@ -436,7 +463,7 @@ static void sde_hdcp_2x_initialize_command(struct sde_hdcp_2x_ctrl *hdcp,
		struct hdcp_transport_wakeup_data *cdata)
{
		cdata->cmd = cmd;
		cdata->timeout = hdcp->timeout_left;
		cdata->transaction_delay = hdcp->timeout_left;
		cdata->buf = hdcp->app_data.request.data + 1;
}

@@ -492,7 +519,7 @@ static void sde_hdcp_2x_msg_sent(struct sde_hdcp_2x_ctrl *hdcp)
		break;
	default:
		cdata.cmd = HDCP_TRANSPORT_CMD_RECV_MESSAGE;
		cdata.timeout = hdcp->timeout_left;
		cdata.transaction_delay = hdcp->app_data.timeout;
		cdata.buf = hdcp->app_data.request.data + 1;
	}

@@ -593,7 +620,7 @@ static void sde_hdcp_2x_msg_recvd(struct sde_hdcp_2x_ctrl *hdcp)

	if (msg[0] == AKE_SEND_H_PRIME && hdcp->no_stored_km) {
		cdata.cmd = HDCP_TRANSPORT_CMD_RECV_MESSAGE;
		cdata.timeout = hdcp->app_data.timeout;
		cdata.transaction_delay = hdcp->app_data.timeout;
		cdata.buf = hdcp->app_data.request.data + 1;
		goto exit;
	}
@@ -653,7 +680,7 @@ static void sde_hdcp_2x_msg_recvd(struct sde_hdcp_2x_ctrl *hdcp)
		cdata.cmd = HDCP_TRANSPORT_CMD_SEND_MESSAGE;
		cdata.buf = hdcp->app_data.response.data + 1;
		cdata.buf_len = hdcp->app_data.response.length;
		cdata.timeout = hdcp->app_data.timeout;
		cdata.transaction_delay = hdcp->app_data.timeout;
	}
exit:
	sde_hdcp_2x_wakeup_client(hdcp, &cdata);
+16 −11
Original line number Diff line number Diff line
@@ -117,11 +117,13 @@ struct sde_hdcp_2x_msg_part {
 * @num_messages:          total number of parts in a full message
 * @messages:              array containing num_messages parts
 * @rx_status:             value of rx_status register
 * @transaction_timeout:   maximum duration to read/write message from/to sink
 */
struct sde_hdcp_2x_msg_data {
	uint32_t num_messages;
	struct sde_hdcp_2x_msg_part messages[HDCP_MAX_MESSAGE_PARTS];
	uint8_t rx_status;
	uint32_t transaction_timeout;
};

/**
@@ -133,13 +135,16 @@ struct sde_hdcp_2x_msg_data {
 * @timeout:              timeout value for timed transactions
 * @abort_mask:           mask used to determine whether HDCP link is valid
 * @message_data:         a pointer to the message description
 * @transaction_delay:    amount of time to delay before performing transaction
 * @transaction_timeout:  maximum duration to read/write message from/to sink
 */
struct hdcp_transport_wakeup_data {
	enum hdcp_transport_wakeup_cmd cmd;
	void *context;
	unsigned char *buf;
	u32 buf_len;
	u32 timeout;
	u32 transaction_delay;
	u32 transaction_timeout;
	u8 abort_mask;
	const struct sde_hdcp_2x_msg_data *message_data;
};