Merge "disp: msm: hdcp: abort queued tasks while processing PM suspend"

This commit is contained in:
qctecmdr 2020-04-06 21:56:42 -07:00 • committed by Gerrit - the friendly Code Review server
commit f30a033ad5
16 changed files with 728 additions and 243 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/of_platform.h>
@ -766,6 +766,12 @@ static int dp_audio_off(struct dp_audio *dp_audio)
}
audio = container_of(dp_audio, struct dp_audio_private, dp_audio);
if (!atomic_read(&audio->session_on)) {
DP_DEBUG("audio already off\n");
return rc;
}
ext = &audio->ext_audio_data;
work_pending = cancel_delayed_work_sync(&audio->notify_delayed_work);

View file

@ -310,7 +310,7 @@ static void dp_aux_reconfig(struct dp_aux *dp_aux)
aux->catalog->reset(aux->catalog);
}
static void dp_aux_abort_transaction(struct dp_aux *dp_aux)
static void dp_aux_abort_transaction(struct dp_aux *dp_aux, bool abort)
{
struct dp_aux_private *aux;
@ -321,7 +321,7 @@ static void dp_aux_abort_transaction(struct dp_aux *dp_aux)
aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
atomic_set(&aux->aborted, 1);
atomic_set(&aux->aborted, abort);
}
static void dp_aux_update_offset_and_segment(struct dp_aux_private *aux,

View file

@ -50,7 +50,7 @@ struct dp_aux {
void (*init)(struct dp_aux *aux, struct dp_aux_cfg *aux_cfg);
void (*deinit)(struct dp_aux *aux);
void (*reconfig)(struct dp_aux *aux);
void (*abort)(struct dp_aux *aux);
void (*abort)(struct dp_aux *aux, bool abort);
void (*dpcd_updated)(struct dp_aux *aux);
void (*set_sim_mode)(struct dp_aux *aux, bool en, u8 *edid, u8 *dpcd);
int (*aux_switch)(struct dp_aux *aux, bool enable, int orientation);

View file

@ -247,7 +247,10 @@ static void dp_catalog_ctrl_update_vx_px_v420(struct dp_catalog_ctrl *ctrl,
io_data = catalog->io->dp_ahb;
version = dp_read(DP_HW_VERSION);
if (version == 0x10020003) {
/*
* For DP controller versions 1.2.3 and 1.2.4
*/
if ((version == 0x10020003) || (version == 0x10020004)) {
if (high) {
value0 = dp_swing_hbr2_hbr3[v_level][p_level];
value1 = dp_pre_emp_hbr2_hbr3[v_level][p_level];

View file

@ -102,7 +102,7 @@ static void dp_ctrl_video_ready(struct dp_ctrl_private *ctrl)
complete(&ctrl->video_comp);
}
static void dp_ctrl_abort(struct dp_ctrl *dp_ctrl)
static void dp_ctrl_abort(struct dp_ctrl *dp_ctrl, bool abort)
{
struct dp_ctrl_private *ctrl;
@ -113,7 +113,7 @@ static void dp_ctrl_abort(struct dp_ctrl *dp_ctrl)
ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
atomic_set(&ctrl->aborted, 1);
atomic_set(&ctrl->aborted, abort);
}
static void dp_ctrl_state_ctrl(struct dp_ctrl_private *ctrl, u32 state)

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _DP_CTRL_H_
@ -19,7 +19,7 @@ struct dp_ctrl {
int (*on)(struct dp_ctrl *dp_ctrl, bool mst_mode, bool fec_en,
bool dsc_en, bool shallow);
void (*off)(struct dp_ctrl *dp_ctrl);
void (*abort)(struct dp_ctrl *dp_ctrl);
void (*abort)(struct dp_ctrl *dp_ctrl, bool abort);
void (*isr)(struct dp_ctrl *dp_ctrl);
bool (*handle_sink_request)(struct dp_ctrl *dp_ctrl);
void (*process_phy_test_request)(struct dp_ctrl *dp_ctrl);

View file

@ -1596,8 +1596,8 @@ static void dp_debug_set_sim_mode(struct dp_debug_private *debug, bool sim)
debug->hpd->simulate_connect(debug->hpd, false);
debug->hotplug = false;
}
debug->aux->abort(debug->aux);
debug->ctrl->abort(debug->ctrl);
debug->aux->abort(debug->aux, true);
debug->ctrl->abort(debug->ctrl, true);
debug->aux->set_sim_mode(debug->aux, false, NULL, NULL);
debug->dp_debug.sim_mode = false;

View file

@ -13,13 +13,33 @@
#include "dp_display.h"
#include "dp_pll.h"
#define DP_WARN(fmt, ...) DRM_WARN("[msm-dp-warn] "fmt, ##__VA_ARGS__)
#define DP_ERR(fmt, ...) DRM_DEV_ERROR(NULL, "[msm-dp-error]" fmt, \
##__VA_ARGS__)
#define DP_INFO(fmt, ...) DRM_DEV_INFO(NULL, "[msm-dp-info] "fmt, \
##__VA_ARGS__)
#define DP_DEBUG(fmt, ...) DRM_DEV_DEBUG_DP(NULL, "[msm-dp-debug] "fmt, \
##__VA_ARGS__)
#define DP_DEBUG(fmt, ...) \
do { \
if (unlikely(drm_debug & DRM_UT_KMS)) \
DRM_DEBUG("[msm-dp-debug][%-4d]"fmt, current->pid, \
##__VA_ARGS__); \
else \
pr_debug("[drm:%s][msm-dp-debug][%-4d]"fmt, __func__,\
current->pid, ##__VA_ARGS__); \
} while (0)
#define DP_INFO(fmt, ...) \
do { \
if (unlikely(drm_debug & DRM_UT_KMS)) \
DRM_INFO("[msm-dp-info][%-4d]"fmt, current->pid, \
##__VA_ARGS__); \
else \
pr_info("[drm:%s][msm-dp-info][%-4d]"fmt, __func__, \
current->pid, ##__VA_ARGS__); \
} while (0)
#define DP_WARN(fmt, ...) \
pr_warn("[drm:%s][msm-dp-warn][%-4d]"fmt, __func__, \
current->pid, ##__VA_ARGS__)
#define DP_ERR(fmt, ...) \
pr_err("[drm:%s][msm-dp-err][%-4d]"fmt, __func__, \
current->pid, ##__VA_ARGS__)
/**
* struct dp_debug

File diff suppressed because it is too large Load diff

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>
@ -31,6 +31,7 @@ struct dp_hdcp2p2_ctrl {
DECLARE_KFIFO(cmd_q, enum hdcp_transport_wakeup_cmd, 8);
wait_queue_head_t wait_q;
atomic_t auth_state;
atomic_t abort;
enum dp_hdcp2p2_sink_status sink_status; /* Is sink connected */
struct dp_hdcp2p2_interrupts *intr;
struct sde_hdcp_init_data init_data;
@ -44,7 +45,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 +110,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 +133,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;
@ -148,6 +152,9 @@ static void dp_hdcp2p2_set_interrupts(struct dp_hdcp2p2_ctrl *ctrl, bool enable)
void __iomem *base = ctrl->init_data.dp_ahb->base;
struct dp_hdcp2p2_interrupts *intr = ctrl->intr;
if (atomic_read(&ctrl->abort))
return;
while (intr && intr->reg) {
struct dp_hdcp2p2_int_set *int_set = intr->int_set;
u32 interrupts = 0;
@ -170,7 +177,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 +189,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;
@ -349,11 +350,6 @@ static void dp_hdcp2p2_min_level_change(void *client_ctx,
return;
}
if (!dp_hdcp2p2_is_valid_state(ctrl)) {
DP_ERR("invalid state\n");
return;
}
cdata.context = ctrl->lib_ctx;
cdata.min_enc_level = min_enc_level;
dp_hdcp2p2_wakeup_lib(ctrl, &cdata);
@ -364,6 +360,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 +378,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 +395,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 +491,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 +499,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 +525,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 +550,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);
}
@ -877,6 +886,13 @@ static int dp_hdcp2p2_main(void *data)
return 0;
}
static void dp_hdcp2p2_abort(void *input, bool abort)
{
struct dp_hdcp2p2_ctrl *ctrl = input;
atomic_set(&ctrl->abort, abort);
}
void *sde_dp_hdcp2p2_init(struct sde_hdcp_init_data *init_data)
{
int rc;
@ -891,6 +907,7 @@ void *sde_dp_hdcp2p2_init(struct sde_hdcp_init_data *init_data)
.set_mode = dp_hdcp2p2_register,
.on = dp_hdcp2p2_on,
.off = dp_hdcp2p2_off,
.abort = dp_hdcp2p2_abort,
.cp_irq = dp_hdcp2p2_cp_irq,
.register_streams = dp_hdcp2p2_register_streams,
.deregister_streams = dp_hdcp2p2_deregister_streams,

View file

@ -3069,6 +3069,7 @@ error:
void dp_panel_put(struct dp_panel *dp_panel)
{
struct dp_panel_private *panel;
struct sde_connector *sde_conn;
if (!dp_panel)
return;
@ -3076,5 +3077,9 @@ void dp_panel_put(struct dp_panel *dp_panel)
panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
dp_panel_edid_deregister(panel);
sde_conn = to_sde_connector(dp_panel->connector);
if (sde_conn)
sde_conn->drv_panel = NULL;
devm_kfree(panel->dev, panel);
}

View file

@ -34,6 +34,7 @@ enum sde_dbg_evtlog_flag {
SDE_EVTLOG_CRITICAL = BIT(0),
SDE_EVTLOG_IRQ = BIT(1),
SDE_EVTLOG_VERBOSE = BIT(2),
SDE_EVTLOG_EXTERNAL = BIT(3),
SDE_EVTLOG_ALWAYS = -1
};
@ -48,7 +49,8 @@ enum sde_dbg_dump_context {
SDE_DBG_DUMP_CLK_ENABLED_CTX,
};
#define SDE_EVTLOG_DEFAULT_ENABLE (SDE_EVTLOG_CRITICAL | SDE_EVTLOG_IRQ)
#define SDE_EVTLOG_DEFAULT_ENABLE (SDE_EVTLOG_CRITICAL | SDE_EVTLOG_IRQ | \
SDE_EVTLOG_EXTERNAL)
/*
* evtlog will print this number of entries when it is called through
@ -62,7 +64,7 @@ enum sde_dbg_dump_context {
* number must be greater than print entry to prevent out of bound evtlog
* entry array access.
*/
#define SDE_EVTLOG_ENTRY (SDE_EVTLOG_PRINT_ENTRY * 8)
#define SDE_EVTLOG_ENTRY (SDE_EVTLOG_PRINT_ENTRY * 32)
#define SDE_EVTLOG_MAX_DATA 15
#define SDE_EVTLOG_BUF_MAX 512
#define SDE_EVTLOG_BUF_ALIGN 32
@ -125,6 +127,14 @@ extern struct sde_dbg_evtlog *sde_dbg_base_evtlog;
__LINE__, SDE_EVTLOG_IRQ, ##__VA_ARGS__, \
SDE_EVTLOG_DATA_LIMITER)
/**
* SDE_EVT32_EXTERNAL - Write a list of 32bit values for external display events
* ... - variable arguments
*/
#define SDE_EVT32_EXTERNAL(...) sde_evtlog_log(sde_dbg_base_evtlog, __func__, \
__LINE__, SDE_EVTLOG_EXTERNAL, ##__VA_ARGS__, \
SDE_EVTLOG_DATA_LIMITER)
/**
* SDE_DBG_DUMP - trigger dumping of all sde_dbg facilities
* @va_args: list of named register dump ranges and regions to dump, as

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012, 2014-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2012, 2014-2020, The Linux Foundation. All rights reserved.
*/
#ifndef __SDE_HDCP_H__
@ -81,6 +81,7 @@ struct sde_hdcp_ops {
bool (*feature_supported)(void *input);
void (*force_encryption)(void *input, bool enable);
bool (*sink_support)(void *input);
void (*abort)(void *input, bool abort);
int (*set_mode)(void *input, bool mst_enabled);
int (*on)(void *input);
void (*off)(void *hdcp_ctrl);

View file

@ -207,6 +207,7 @@ struct sde_hdcp_1x {
bool reauth;
bool ksv_ready;
bool force_encryption;
atomic_t abort;
enum sde_hdcp_state hdcp_state;
struct HDCP_V2V1_MSG_TOPOLOGY current_tp;
struct delayed_work hdcp_auth_work;
@ -1040,7 +1041,7 @@ static void sde_hdcp_1x_update_auth_status(struct sde_hdcp_1x *hdcp)
static void sde_hdcp_1x_auth_work(struct work_struct *work)
{
int rc;
int rc = 0;
struct delayed_work *dw = to_delayed_work(work);
struct sde_hdcp_1x *hdcp = container_of(dw,
struct sde_hdcp_1x, hdcp_auth_work);
@ -1056,6 +1057,9 @@ static void sde_hdcp_1x_auth_work(struct work_struct *work)
return;
}
if (atomic_read(&hdcp->abort))
goto end;
hdcp->sink_r0_ready = false;
hdcp->reauth = false;
hdcp->ksv_ready = false;
@ -1484,6 +1488,15 @@ irq_not_handled:
return -EINVAL;
}
static void sde_hdcp_1x_abort(void *data, bool abort)
{
struct sde_hdcp_1x *hdcp = data;
atomic_set(&hdcp->abort, abort);
cancel_delayed_work_sync(&hdcp->hdcp_auth_work);
flush_workqueue(hdcp->workq);
}
void *sde_hdcp_1x_init(struct sde_hdcp_init_data *init_data)
{
struct sde_hdcp_1x *hdcp = NULL;
@ -1496,6 +1509,7 @@ void *sde_hdcp_1x_init(struct sde_hdcp_init_data *init_data)
.feature_supported = sde_hdcp_1x_feature_supported,
.force_encryption = sde_hdcp_1x_force_encryption,
.sink_support = sde_hdcp_1x_sink_support,
.abort = sde_hdcp_1x_abort,
.off = sde_hdcp_1x_off
};

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
*/
#define pr_fmt(fmt) "[sde-hdcp-2x] %s: " fmt, __func__
@ -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,29 @@ 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;
break;
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 +297,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 +313,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 +464,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 +520,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 +621,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 +681,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);
@ -876,8 +904,10 @@ static int sde_hdcp_2x_wakeup(struct sde_hdcp_2x_wakeup_data *data)
break;
case HDCP_2X_CMD_MIN_ENC_LEVEL:
hdcp->min_enc_level = data->min_enc_level;
kfifo_put(&hdcp->cmd_q, data->cmd);
wake_up(&hdcp->wait_q);
if (hdcp->authenticated) {
kfifo_put(&hdcp->cmd_q, data->cmd);
wake_up(&hdcp->wait_q);
}
break;
default:
kfifo_put(&hdcp->cmd_q, data->cmd);

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
*/
#ifndef __SDE_HDCP_2X_H__
@ -114,32 +114,37 @@ struct sde_hdcp_2x_msg_part {
/**
* struct sde_hdcp_2x_msg_data - HDCP 2.2 message containing one or more parts
* @num_messages: total number of parts in a full message
* @messages: array containing num_messages parts
* @rx_status: value of rx_status register
* @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;
};
/**
* struct hdcp_transport_wakeup_data - data sent to display transport layer
* @cmd: command type
* @context: void pointer to the display transport layer
* @send_msg_buf: buffer containing message to be sent to sink
* @send_msg_len: length of the message to be sent to sink
* @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
* @cmd: command type
* @context: void pointer to the display transport layer
* @send_msg_buf: buffer containing message to be sent to sink
* @send_msg_len: length of the message to be sent to sink
* @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;
};