disp: msm: dp: Enforce HDCP 2.3 timing requirements

The HDCP 2.3 specification added new timing
requirements for message read duration. Ensure
that these requirements are enforced in the DP
display layer.

Delay for a specification-allowed amount of time
before reading messages to ensure that sinks have
enough time to process messages and make their
replies available to read.

Change-Id: I40b210823a7cbaca6efc12abc4c8e8b98a10e071
Signed-off-by: Fuad Hossain <fhossain@codeaurora.org>
Signed-off-by: Tatenda Chipeperekwa <tatendac@codeaurora.org>
This commit is contained in:
Tatenda Chipeperekwa
2019-11-05 12:25:18 -05:00
parent 3e26909b0a
commit f7de094233
3 changed files with 87 additions and 44 deletions

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/delay.h>
@@ -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);
}