Răsfoiți Sursa

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

qctecmdr 5 ani în urmă
părinte
comite
f30a033ad5

+ 7 - 1
msm/dp/dp_audio.c

@@ -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);

+ 2 - 2
msm/dp/dp_aux.c

@@ -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,

+ 1 - 1
msm/dp/dp_aux.h

@@ -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);

+ 4 - 1
msm/dp/dp_catalog_v420.c

@@ -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];

+ 2 - 2
msm/dp/dp_ctrl.c

@@ -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)

+ 2 - 2
msm/dp/dp_ctrl.h

@@ -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);

+ 2 - 2
msm/dp/dp_debug.c

@@ -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;

+ 27 - 7
msm/dp/dp_debug.h

@@ -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

Fișier diff suprimat deoarece este prea mare
+ 424 - 140
msm/dp/dp_display.c


+ 34 - 17
msm/dp/dp_hdcp2p2.c

@@ -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,

+ 5 - 0
msm/dp/dp_panel.c

@@ -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);
 }

+ 12 - 2
msm/sde_dbg.h

@@ -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

+ 2 - 1
msm/sde_hdcp.h

@@ -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);

+ 15 - 1
msm/sde_hdcp_1x.c

@@ -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
 	};
 

+ 52 - 22
msm/sde_hdcp_2x.c

@@ -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);

+ 17 - 12
msm/sde_hdcp_2x.h

@@ -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;
 };

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff