xref: /linux/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
14c283fdaSBhawanpreet Lakha /*
24c283fdaSBhawanpreet Lakha  * Copyright 2019 Advanced Micro Devices, Inc.
34c283fdaSBhawanpreet Lakha  *
44c283fdaSBhawanpreet Lakha  * Permission is hereby granted, free of charge, to any person obtaining a
54c283fdaSBhawanpreet Lakha  * copy of this software and associated documentation files (the "Software"),
64c283fdaSBhawanpreet Lakha  * to deal in the Software without restriction, including without limitation
74c283fdaSBhawanpreet Lakha  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
84c283fdaSBhawanpreet Lakha  * and/or sell copies of the Software, and to permit persons to whom the
94c283fdaSBhawanpreet Lakha  * Software is furnished to do so, subject to the following conditions:
104c283fdaSBhawanpreet Lakha  *
114c283fdaSBhawanpreet Lakha  * The above copyright notice and this permission notice shall be included in
124c283fdaSBhawanpreet Lakha  * all copies or substantial portions of the Software.
134c283fdaSBhawanpreet Lakha  *
144c283fdaSBhawanpreet Lakha  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
154c283fdaSBhawanpreet Lakha  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
164c283fdaSBhawanpreet Lakha  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
174c283fdaSBhawanpreet Lakha  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
184c283fdaSBhawanpreet Lakha  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
194c283fdaSBhawanpreet Lakha  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
204c283fdaSBhawanpreet Lakha  * OTHER DEALINGS IN THE SOFTWARE.
214c283fdaSBhawanpreet Lakha  *
224c283fdaSBhawanpreet Lakha  * Authors: AMD
234c283fdaSBhawanpreet Lakha  *
244c283fdaSBhawanpreet Lakha  */
254c283fdaSBhawanpreet Lakha 
264c283fdaSBhawanpreet Lakha #include "hdcp.h"
274c283fdaSBhawanpreet Lakha 
284c283fdaSBhawanpreet Lakha #ifndef MIN
294c283fdaSBhawanpreet Lakha #define MIN(a, b) ((a) < (b) ? (a) : (b))
304c283fdaSBhawanpreet Lakha #endif
314c283fdaSBhawanpreet Lakha #define HDCP_I2C_ADDR 0x3a	/* 0x74 >> 1*/
324c283fdaSBhawanpreet Lakha #define KSV_READ_SIZE 0xf	/* 0x6803b - 0x6802c */
335cd04c48SHarmanprit Tatla #define HDCP_MAX_AUX_TRANSACTION_SIZE 16
345cd04c48SHarmanprit Tatla 
354c283fdaSBhawanpreet Lakha #define DP_CP_IRQ (1 << 2)
364c283fdaSBhawanpreet Lakha 
374c283fdaSBhawanpreet Lakha enum mod_hdcp_ddc_message_id {
384c283fdaSBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_INVALID = -1,
394c283fdaSBhawanpreet Lakha 
404c283fdaSBhawanpreet Lakha 	/* HDCP 1.4 */
414c283fdaSBhawanpreet Lakha 
424c283fdaSBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_BKSV = 0,
434c283fdaSBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_RI_R0,
444c283fdaSBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_WRITE_AKSV,
454c283fdaSBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_WRITE_AINFO,
464c283fdaSBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_WRITE_AN,
474c283fdaSBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_VH_X,
484c283fdaSBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_VH_0,
494c283fdaSBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_VH_1,
504c283fdaSBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_VH_2,
514c283fdaSBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_VH_3,
524c283fdaSBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_VH_4,
534c283fdaSBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_BCAPS,
544c283fdaSBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_BSTATUS,
554c283fdaSBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO,
56eff682f8SBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_BINFO,
57eff682f8SBhawanpreet Lakha 
58eff682f8SBhawanpreet Lakha 	/* HDCP 2.2 */
59eff682f8SBhawanpreet Lakha 
60eff682f8SBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_HDCP2VERSION,
61eff682f8SBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_RX_CAPS,
62eff682f8SBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT,
63eff682f8SBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,
64eff682f8SBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM,
65eff682f8SBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM,
66eff682f8SBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,
67eff682f8SBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,
68eff682f8SBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT,
69eff682f8SBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,
70d7ecf5e3SWenjing Liu 	MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,
71eff682f8SBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,
72eff682f8SBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2,
73eff682f8SBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,
74eff682f8SBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,
75eff682f8SBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,
76eff682f8SBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_READ_RXSTATUS,
774c283fdaSBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE,
784c283fdaSBhawanpreet Lakha 
794c283fdaSBhawanpreet Lakha 	MOD_HDCP_MESSAGE_ID_MAX
804c283fdaSBhawanpreet Lakha };
814c283fdaSBhawanpreet Lakha 
824c283fdaSBhawanpreet Lakha static const uint8_t hdcp_i2c_offsets[] = {
834c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_BKSV] = 0x0,
844c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_RI_R0] = 0x8,
854c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_AKSV] = 0x10,
864c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_AINFO] = 0x15,
874c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_AN] = 0x18,
884c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_VH_X] = 0x20,
894c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_VH_0] = 0x20,
904c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_VH_1] = 0x24,
914c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_VH_2] = 0x28,
924c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_VH_3] = 0x2C,
934c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_VH_4] = 0x30,
944c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_BCAPS] = 0x40,
954c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_BSTATUS] = 0x41,
96eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x43,
97eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_BINFO] = 0xFF,
98eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_HDCP2VERSION] = 0x50,
99eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x60,
100eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x80,
101eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x60,
102eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x60,
103eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x80,
104eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x80,
105eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x60,
106eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x80,
107d7ecf5e3SWenjing Liu 	[MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x60,
108eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x80,
109eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2] = 0x80,
110eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x60,
111eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x60,
112eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x80,
1134c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x70,
1144c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x0
1154c283fdaSBhawanpreet Lakha };
1164c283fdaSBhawanpreet Lakha 
1174c283fdaSBhawanpreet Lakha static const uint32_t hdcp_dpcd_addrs[] = {
1184c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_BKSV] = 0x68000,
1194c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_RI_R0] = 0x68005,
1204c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_AKSV] = 0x68007,
1214c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_AINFO] = 0x6803B,
1224c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_AN] = 0x6800c,
1234c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_VH_X] = 0x68014,
1244c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_VH_0] = 0x68014,
1254c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_VH_1] = 0x68018,
1264c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_VH_2] = 0x6801c,
1274c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_VH_3] = 0x68020,
1284c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_VH_4] = 0x68024,
1294c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_BCAPS] = 0x68028,
1304c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_BSTATUS] = 0x68029,
131eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x6802c,
132eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_BINFO] = 0x6802a,
133eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_RX_CAPS] = 0x6921d,
134eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x69000,
135eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x6900b,
136eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x69220,
137eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x692a0,
138eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x692c0,
139eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x692e0,
140eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x692f0,
141eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x692f8,
142d7ecf5e3SWenjing Liu 	[MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x69318,
143eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x69330,
144eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2] = 0x69340,
145eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x693e0,
146eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x693f0,
147eff682f8SBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x69473,
1484c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x69493,
1494c283fdaSBhawanpreet Lakha 	[MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x69494
1504c283fdaSBhawanpreet Lakha };
1514c283fdaSBhawanpreet Lakha 
read(struct mod_hdcp * hdcp,enum mod_hdcp_ddc_message_id msg_id,uint8_t * buf,uint32_t buf_len)1524c283fdaSBhawanpreet Lakha static enum mod_hdcp_status read(struct mod_hdcp *hdcp,
1534c283fdaSBhawanpreet Lakha 		enum mod_hdcp_ddc_message_id msg_id,
1544c283fdaSBhawanpreet Lakha 		uint8_t *buf,
1554c283fdaSBhawanpreet Lakha 		uint32_t buf_len)
1564c283fdaSBhawanpreet Lakha {
1574c283fdaSBhawanpreet Lakha 	bool success = true;
1584c283fdaSBhawanpreet Lakha 	uint32_t cur_size = 0;
1594e70c0f5SHersen Wu 	uint32_t data_offset = 0;
1604e70c0f5SHersen Wu 
16159d99debSAlex Hung 	if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID ||
16259d99debSAlex Hung 		msg_id >= MOD_HDCP_MESSAGE_ID_MAX)
1634c283fdaSBhawanpreet Lakha 		return MOD_HDCP_STATUS_DDC_FAILURE;
164*b72585f1SJiapeng Chong 
1654e70c0f5SHersen Wu 	if (is_dp_hdcp(hdcp)) {
1664e70c0f5SHersen Wu 		int num_dpcd_addrs = ARRAY_SIZE(hdcp_dpcd_addrs);
1674e70c0f5SHersen Wu 		if (msg_id >= num_dpcd_addrs)
1684c283fdaSBhawanpreet Lakha 			return MOD_HDCP_STATUS_DDC_FAILURE;
1694c283fdaSBhawanpreet Lakha 
1704c283fdaSBhawanpreet Lakha 		while (buf_len > 0) {
1714c283fdaSBhawanpreet Lakha 			cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE);
1724c283fdaSBhawanpreet Lakha 			success = hdcp->config.ddc.funcs.read_dpcd(hdcp->config.ddc.handle,
1734c283fdaSBhawanpreet Lakha 					hdcp_dpcd_addrs[msg_id] + data_offset,
1744c283fdaSBhawanpreet Lakha 					buf + data_offset,
1754c283fdaSBhawanpreet Lakha 					cur_size);
1764c283fdaSBhawanpreet Lakha 
1774c283fdaSBhawanpreet Lakha 			if (!success)
1784c283fdaSBhawanpreet Lakha 				break;
1794c283fdaSBhawanpreet Lakha 
1804c283fdaSBhawanpreet Lakha 			buf_len -= cur_size;
1814c283fdaSBhawanpreet Lakha 			data_offset += cur_size;
182*b72585f1SJiapeng Chong 		}
1834e70c0f5SHersen Wu 	} else {
1844e70c0f5SHersen Wu 		int num_i2c_offsets = ARRAY_SIZE(hdcp_i2c_offsets);
1854e70c0f5SHersen Wu 		if (msg_id >= num_i2c_offsets)
1864c283fdaSBhawanpreet Lakha 			return MOD_HDCP_STATUS_DDC_FAILURE;
1874c283fdaSBhawanpreet Lakha 
1884c283fdaSBhawanpreet Lakha 		success = hdcp->config.ddc.funcs.read_i2c(
1894c283fdaSBhawanpreet Lakha 				hdcp->config.ddc.handle,
1904c283fdaSBhawanpreet Lakha 				HDCP_I2C_ADDR,
1914c283fdaSBhawanpreet Lakha 				hdcp_i2c_offsets[msg_id],
1924c283fdaSBhawanpreet Lakha 				buf,
1934c283fdaSBhawanpreet Lakha 				(uint32_t)buf_len);
1944c283fdaSBhawanpreet Lakha 	}
1954c283fdaSBhawanpreet Lakha 
1964c283fdaSBhawanpreet Lakha 	return success ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE;
1974c283fdaSBhawanpreet Lakha }
1984c283fdaSBhawanpreet Lakha 
read_repeatedly(struct mod_hdcp * hdcp,enum mod_hdcp_ddc_message_id msg_id,uint8_t * buf,uint32_t buf_len,uint8_t read_size)1994c283fdaSBhawanpreet Lakha static enum mod_hdcp_status read_repeatedly(struct mod_hdcp *hdcp,
2004c283fdaSBhawanpreet Lakha 		enum mod_hdcp_ddc_message_id msg_id,
2014c283fdaSBhawanpreet Lakha 		uint8_t *buf,
2024c283fdaSBhawanpreet Lakha 		uint32_t buf_len,
2034c283fdaSBhawanpreet Lakha 		uint8_t read_size)
2044c283fdaSBhawanpreet Lakha {
2054c283fdaSBhawanpreet Lakha 	enum mod_hdcp_status status = MOD_HDCP_STATUS_DDC_FAILURE;
2064c283fdaSBhawanpreet Lakha 	uint32_t cur_size = 0;
2074c283fdaSBhawanpreet Lakha 	uint32_t data_offset = 0;
2084c283fdaSBhawanpreet Lakha 
2094c283fdaSBhawanpreet Lakha 	while (buf_len > 0) {
2104c283fdaSBhawanpreet Lakha 		cur_size = MIN(buf_len, read_size);
2114c283fdaSBhawanpreet Lakha 		status = read(hdcp, msg_id, buf + data_offset, cur_size);
2124c283fdaSBhawanpreet Lakha 
2134c283fdaSBhawanpreet Lakha 		if (status != MOD_HDCP_STATUS_SUCCESS)
2144c283fdaSBhawanpreet Lakha 			break;
2154c283fdaSBhawanpreet Lakha 
2164c283fdaSBhawanpreet Lakha 		buf_len -= cur_size;
2174c283fdaSBhawanpreet Lakha 		data_offset += cur_size;
2184c283fdaSBhawanpreet Lakha 	}
2194c283fdaSBhawanpreet Lakha 
2204c283fdaSBhawanpreet Lakha 	return status;
2214c283fdaSBhawanpreet Lakha }
2224c283fdaSBhawanpreet Lakha 
write(struct mod_hdcp * hdcp,enum mod_hdcp_ddc_message_id msg_id,uint8_t * buf,uint32_t buf_len)2234c283fdaSBhawanpreet Lakha static enum mod_hdcp_status write(struct mod_hdcp *hdcp,
2244c283fdaSBhawanpreet Lakha 		enum mod_hdcp_ddc_message_id msg_id,
2254c283fdaSBhawanpreet Lakha 		uint8_t *buf,
2264c283fdaSBhawanpreet Lakha 		uint32_t buf_len)
2274c283fdaSBhawanpreet Lakha {
2284c283fdaSBhawanpreet Lakha 	bool success = true;
2294c283fdaSBhawanpreet Lakha 	uint32_t cur_size = 0;
2304e70c0f5SHersen Wu 	uint32_t data_offset = 0;
2314e70c0f5SHersen Wu 
23259d99debSAlex Hung 	if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID ||
23359d99debSAlex Hung 		msg_id >= MOD_HDCP_MESSAGE_ID_MAX)
2344c283fdaSBhawanpreet Lakha 		return MOD_HDCP_STATUS_DDC_FAILURE;
235*b72585f1SJiapeng Chong 
2364e70c0f5SHersen Wu 	if (is_dp_hdcp(hdcp)) {
2374e70c0f5SHersen Wu 		int num_dpcd_addrs = ARRAY_SIZE(hdcp_dpcd_addrs);
2384e70c0f5SHersen Wu 		if (msg_id >= num_dpcd_addrs)
2394c283fdaSBhawanpreet Lakha 			return MOD_HDCP_STATUS_DDC_FAILURE;
2404c283fdaSBhawanpreet Lakha 
2414c283fdaSBhawanpreet Lakha 		while (buf_len > 0) {
2424c283fdaSBhawanpreet Lakha 			cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE);
2434c283fdaSBhawanpreet Lakha 			success = hdcp->config.ddc.funcs.write_dpcd(
2444c283fdaSBhawanpreet Lakha 					hdcp->config.ddc.handle,
2454c283fdaSBhawanpreet Lakha 					hdcp_dpcd_addrs[msg_id] + data_offset,
2464c283fdaSBhawanpreet Lakha 					buf + data_offset,
2474c283fdaSBhawanpreet Lakha 					cur_size);
2484c283fdaSBhawanpreet Lakha 
2494c283fdaSBhawanpreet Lakha 			if (!success)
2504c283fdaSBhawanpreet Lakha 				break;
2514c283fdaSBhawanpreet Lakha 
2524c283fdaSBhawanpreet Lakha 			buf_len -= cur_size;
2534c283fdaSBhawanpreet Lakha 			data_offset += cur_size;
254*b72585f1SJiapeng Chong 		}
2554e70c0f5SHersen Wu 	} else {
2564e70c0f5SHersen Wu 		int num_i2c_offsets = ARRAY_SIZE(hdcp_i2c_offsets);
2574e70c0f5SHersen Wu 		if (msg_id >= num_i2c_offsets)
2584c283fdaSBhawanpreet Lakha 			return MOD_HDCP_STATUS_DDC_FAILURE;
2594c283fdaSBhawanpreet Lakha 
2604c283fdaSBhawanpreet Lakha 		hdcp->buf[0] = hdcp_i2c_offsets[msg_id];
2614c283fdaSBhawanpreet Lakha 		memmove(&hdcp->buf[1], buf, buf_len);
2624c283fdaSBhawanpreet Lakha 		success = hdcp->config.ddc.funcs.write_i2c(
2634c283fdaSBhawanpreet Lakha 				hdcp->config.ddc.handle,
2644c283fdaSBhawanpreet Lakha 				HDCP_I2C_ADDR,
2654c283fdaSBhawanpreet Lakha 				hdcp->buf,
2664c283fdaSBhawanpreet Lakha 				(uint32_t)(buf_len+1));
2674c283fdaSBhawanpreet Lakha 	}
2684c283fdaSBhawanpreet Lakha 
2694c283fdaSBhawanpreet Lakha 	return success ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE;
2704c283fdaSBhawanpreet Lakha }
2714c283fdaSBhawanpreet Lakha 
mod_hdcp_read_bksv(struct mod_hdcp * hdcp)2724c283fdaSBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_read_bksv(struct mod_hdcp *hdcp)
2734c283fdaSBhawanpreet Lakha {
2744c283fdaSBhawanpreet Lakha 	return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BKSV,
2754c283fdaSBhawanpreet Lakha 			hdcp->auth.msg.hdcp1.bksv,
2764c283fdaSBhawanpreet Lakha 			sizeof(hdcp->auth.msg.hdcp1.bksv));
2774c283fdaSBhawanpreet Lakha }
2784c283fdaSBhawanpreet Lakha 
mod_hdcp_read_bcaps(struct mod_hdcp * hdcp)2794c283fdaSBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_read_bcaps(struct mod_hdcp *hdcp)
2804c283fdaSBhawanpreet Lakha {
2814c283fdaSBhawanpreet Lakha 	return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BCAPS,
2824c283fdaSBhawanpreet Lakha 			&hdcp->auth.msg.hdcp1.bcaps,
2834c283fdaSBhawanpreet Lakha 			sizeof(hdcp->auth.msg.hdcp1.bcaps));
2844c283fdaSBhawanpreet Lakha }
2854c283fdaSBhawanpreet Lakha 
mod_hdcp_read_bstatus(struct mod_hdcp * hdcp)2864c283fdaSBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_read_bstatus(struct mod_hdcp *hdcp)
2874c283fdaSBhawanpreet Lakha {
2884c283fdaSBhawanpreet Lakha 	enum mod_hdcp_status status;
2894c283fdaSBhawanpreet Lakha 
2904c283fdaSBhawanpreet Lakha 	if (is_dp_hdcp(hdcp))
2914c283fdaSBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BSTATUS,
2924c283fdaSBhawanpreet Lakha 					(uint8_t *)&hdcp->auth.msg.hdcp1.bstatus,
2934c283fdaSBhawanpreet Lakha 					1);
2944c283fdaSBhawanpreet Lakha 	else
2954c283fdaSBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BSTATUS,
2964c283fdaSBhawanpreet Lakha 				(uint8_t *)&hdcp->auth.msg.hdcp1.bstatus,
2974c283fdaSBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp1.bstatus));
2984c283fdaSBhawanpreet Lakha 	return status;
2994c283fdaSBhawanpreet Lakha }
3004c283fdaSBhawanpreet Lakha 
mod_hdcp_read_r0p(struct mod_hdcp * hdcp)3014c283fdaSBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_read_r0p(struct mod_hdcp *hdcp)
3024c283fdaSBhawanpreet Lakha {
3034c283fdaSBhawanpreet Lakha 	return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RI_R0,
3044c283fdaSBhawanpreet Lakha 			(uint8_t *)&hdcp->auth.msg.hdcp1.r0p,
3054c283fdaSBhawanpreet Lakha 			sizeof(hdcp->auth.msg.hdcp1.r0p));
3064c283fdaSBhawanpreet Lakha }
3074c283fdaSBhawanpreet Lakha 
3084c283fdaSBhawanpreet Lakha /* special case, reading repeatedly at the same address, don't use read() */
mod_hdcp_read_ksvlist(struct mod_hdcp * hdcp)3094c283fdaSBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_read_ksvlist(struct mod_hdcp *hdcp)
3104c283fdaSBhawanpreet Lakha {
3114c283fdaSBhawanpreet Lakha 	enum mod_hdcp_status status;
3124c283fdaSBhawanpreet Lakha 
3134c283fdaSBhawanpreet Lakha 	if (is_dp_hdcp(hdcp))
3144c283fdaSBhawanpreet Lakha 		status = read_repeatedly(hdcp, MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO,
3154c283fdaSBhawanpreet Lakha 				hdcp->auth.msg.hdcp1.ksvlist,
3164c283fdaSBhawanpreet Lakha 				hdcp->auth.msg.hdcp1.ksvlist_size,
3174c283fdaSBhawanpreet Lakha 				KSV_READ_SIZE);
3184c283fdaSBhawanpreet Lakha 	else
3194c283fdaSBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO,
3204c283fdaSBhawanpreet Lakha 				(uint8_t *)&hdcp->auth.msg.hdcp1.ksvlist,
3214c283fdaSBhawanpreet Lakha 				hdcp->auth.msg.hdcp1.ksvlist_size);
3224c283fdaSBhawanpreet Lakha 	return status;
3234c283fdaSBhawanpreet Lakha }
3244c283fdaSBhawanpreet Lakha 
mod_hdcp_read_vp(struct mod_hdcp * hdcp)3254c283fdaSBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_read_vp(struct mod_hdcp *hdcp)
3264c283fdaSBhawanpreet Lakha {
3274c283fdaSBhawanpreet Lakha 	enum mod_hdcp_status status;
3284c283fdaSBhawanpreet Lakha 
3294c283fdaSBhawanpreet Lakha 	status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_0,
3304c283fdaSBhawanpreet Lakha 			&hdcp->auth.msg.hdcp1.vp[0], 4);
3314c283fdaSBhawanpreet Lakha 	if (status != MOD_HDCP_STATUS_SUCCESS)
3324c283fdaSBhawanpreet Lakha 		goto out;
3334c283fdaSBhawanpreet Lakha 
3344c283fdaSBhawanpreet Lakha 	status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_1,
3354c283fdaSBhawanpreet Lakha 			&hdcp->auth.msg.hdcp1.vp[4], 4);
3364c283fdaSBhawanpreet Lakha 	if (status != MOD_HDCP_STATUS_SUCCESS)
3374c283fdaSBhawanpreet Lakha 		goto out;
3384c283fdaSBhawanpreet Lakha 
3394c283fdaSBhawanpreet Lakha 	status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_2,
3404c283fdaSBhawanpreet Lakha 			&hdcp->auth.msg.hdcp1.vp[8], 4);
3414c283fdaSBhawanpreet Lakha 	if (status != MOD_HDCP_STATUS_SUCCESS)
3424c283fdaSBhawanpreet Lakha 		goto out;
3434c283fdaSBhawanpreet Lakha 
3444c283fdaSBhawanpreet Lakha 	status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_3,
3454c283fdaSBhawanpreet Lakha 			&hdcp->auth.msg.hdcp1.vp[12], 4);
3464c283fdaSBhawanpreet Lakha 	if (status != MOD_HDCP_STATUS_SUCCESS)
3474c283fdaSBhawanpreet Lakha 		goto out;
3484c283fdaSBhawanpreet Lakha 
3494c283fdaSBhawanpreet Lakha 	status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_4,
3504c283fdaSBhawanpreet Lakha 			&hdcp->auth.msg.hdcp1.vp[16], 4);
3514c283fdaSBhawanpreet Lakha out:
3524c283fdaSBhawanpreet Lakha 	return status;
3534c283fdaSBhawanpreet Lakha }
3544c283fdaSBhawanpreet Lakha 
mod_hdcp_read_binfo(struct mod_hdcp * hdcp)3554c283fdaSBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_read_binfo(struct mod_hdcp *hdcp)
3564c283fdaSBhawanpreet Lakha {
3574c283fdaSBhawanpreet Lakha 	enum mod_hdcp_status status;
3584c283fdaSBhawanpreet Lakha 
3594c283fdaSBhawanpreet Lakha 	if (is_dp_hdcp(hdcp))
3604c283fdaSBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BINFO,
3614c283fdaSBhawanpreet Lakha 				(uint8_t *)&hdcp->auth.msg.hdcp1.binfo_dp,
3624c283fdaSBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp1.binfo_dp));
3634c283fdaSBhawanpreet Lakha 	else
3644c283fdaSBhawanpreet Lakha 		status = MOD_HDCP_STATUS_INVALID_OPERATION;
3654c283fdaSBhawanpreet Lakha 
3664c283fdaSBhawanpreet Lakha 	return status;
3674c283fdaSBhawanpreet Lakha }
3684c283fdaSBhawanpreet Lakha 
mod_hdcp_write_aksv(struct mod_hdcp * hdcp)3694c283fdaSBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_write_aksv(struct mod_hdcp *hdcp)
3704c283fdaSBhawanpreet Lakha {
3714c283fdaSBhawanpreet Lakha 	return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKSV,
3724c283fdaSBhawanpreet Lakha 			hdcp->auth.msg.hdcp1.aksv,
3734c283fdaSBhawanpreet Lakha 			sizeof(hdcp->auth.msg.hdcp1.aksv));
3744c283fdaSBhawanpreet Lakha }
3754c283fdaSBhawanpreet Lakha 
mod_hdcp_write_ainfo(struct mod_hdcp * hdcp)3764c283fdaSBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_write_ainfo(struct mod_hdcp *hdcp)
3774c283fdaSBhawanpreet Lakha {
3784c283fdaSBhawanpreet Lakha 	return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AINFO,
3794c283fdaSBhawanpreet Lakha 			&hdcp->auth.msg.hdcp1.ainfo,
3804c283fdaSBhawanpreet Lakha 			sizeof(hdcp->auth.msg.hdcp1.ainfo));
3814c283fdaSBhawanpreet Lakha }
3824c283fdaSBhawanpreet Lakha 
mod_hdcp_write_an(struct mod_hdcp * hdcp)3834c283fdaSBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_write_an(struct mod_hdcp *hdcp)
3844c283fdaSBhawanpreet Lakha {
3854c283fdaSBhawanpreet Lakha 	return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AN,
3864c283fdaSBhawanpreet Lakha 			hdcp->auth.msg.hdcp1.an,
387eff682f8SBhawanpreet Lakha 			sizeof(hdcp->auth.msg.hdcp1.an));
388eff682f8SBhawanpreet Lakha }
389eff682f8SBhawanpreet Lakha 
mod_hdcp_read_hdcp2version(struct mod_hdcp * hdcp)390eff682f8SBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_read_hdcp2version(struct mod_hdcp *hdcp)
391eff682f8SBhawanpreet Lakha {
392eff682f8SBhawanpreet Lakha 	enum mod_hdcp_status status;
393eff682f8SBhawanpreet Lakha 
394eff682f8SBhawanpreet Lakha 	if (is_dp_hdcp(hdcp))
395eff682f8SBhawanpreet Lakha 		status = MOD_HDCP_STATUS_INVALID_OPERATION;
396eff682f8SBhawanpreet Lakha 	else
397eff682f8SBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_HDCP2VERSION,
398eff682f8SBhawanpreet Lakha 				&hdcp->auth.msg.hdcp2.hdcp2version_hdmi,
399eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.hdcp2version_hdmi));
400eff682f8SBhawanpreet Lakha 
401eff682f8SBhawanpreet Lakha 	return status;
402eff682f8SBhawanpreet Lakha }
403eff682f8SBhawanpreet Lakha 
mod_hdcp_read_rxcaps(struct mod_hdcp * hdcp)404eff682f8SBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_read_rxcaps(struct mod_hdcp *hdcp)
405eff682f8SBhawanpreet Lakha {
406eff682f8SBhawanpreet Lakha 	enum mod_hdcp_status status;
407eff682f8SBhawanpreet Lakha 
408eff682f8SBhawanpreet Lakha 	if (!is_dp_hdcp(hdcp))
409eff682f8SBhawanpreet Lakha 		status = MOD_HDCP_STATUS_INVALID_OPERATION;
410eff682f8SBhawanpreet Lakha 	else
411eff682f8SBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_RX_CAPS,
412eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.rxcaps_dp,
413eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.rxcaps_dp));
414eff682f8SBhawanpreet Lakha 
415eff682f8SBhawanpreet Lakha 	return status;
416eff682f8SBhawanpreet Lakha }
417eff682f8SBhawanpreet Lakha 
mod_hdcp_read_rxstatus(struct mod_hdcp * hdcp)418eff682f8SBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_read_rxstatus(struct mod_hdcp *hdcp)
419eff682f8SBhawanpreet Lakha {
420eff682f8SBhawanpreet Lakha 	enum mod_hdcp_status status;
421eff682f8SBhawanpreet Lakha 
42230216900SBhawanpreet Lakha 	if (is_dp_hdcp(hdcp)) {
423eff682f8SBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RXSTATUS,
424eff682f8SBhawanpreet Lakha 				&hdcp->auth.msg.hdcp2.rxstatus_dp,
425eff682f8SBhawanpreet Lakha 				1);
426eff682f8SBhawanpreet Lakha 	} else {
427eff682f8SBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RXSTATUS,
428eff682f8SBhawanpreet Lakha 					(uint8_t *)&hdcp->auth.msg.hdcp2.rxstatus,
429eff682f8SBhawanpreet Lakha 					sizeof(hdcp->auth.msg.hdcp2.rxstatus));
430eff682f8SBhawanpreet Lakha 	}
431eff682f8SBhawanpreet Lakha 	return status;
432eff682f8SBhawanpreet Lakha }
433eff682f8SBhawanpreet Lakha 
mod_hdcp_read_ake_cert(struct mod_hdcp * hdcp)434eff682f8SBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_read_ake_cert(struct mod_hdcp *hdcp)
435eff682f8SBhawanpreet Lakha {
436eff682f8SBhawanpreet Lakha 	enum mod_hdcp_status status;
437201a9446SWenjing Liu 
438eff682f8SBhawanpreet Lakha 	if (is_dp_hdcp(hdcp)) {
439eff682f8SBhawanpreet Lakha 		hdcp->auth.msg.hdcp2.ake_cert[0] = HDCP_2_2_AKE_SEND_CERT;
440eff682f8SBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,
441eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.ake_cert+1,
442eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.ake_cert)-1);
443eff682f8SBhawanpreet Lakha 
444eff682f8SBhawanpreet Lakha 	} else {
445eff682f8SBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,
446eff682f8SBhawanpreet Lakha 					hdcp->auth.msg.hdcp2.ake_cert,
447eff682f8SBhawanpreet Lakha 					sizeof(hdcp->auth.msg.hdcp2.ake_cert));
448eff682f8SBhawanpreet Lakha 	}
449eff682f8SBhawanpreet Lakha 	return status;
450eff682f8SBhawanpreet Lakha }
451eff682f8SBhawanpreet Lakha 
mod_hdcp_read_h_prime(struct mod_hdcp * hdcp)452eff682f8SBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_read_h_prime(struct mod_hdcp *hdcp)
453eff682f8SBhawanpreet Lakha {
454eff682f8SBhawanpreet Lakha 	enum mod_hdcp_status status;
455201a9446SWenjing Liu 
456eff682f8SBhawanpreet Lakha 	if (is_dp_hdcp(hdcp)) {
457eff682f8SBhawanpreet Lakha 		hdcp->auth.msg.hdcp2.ake_h_prime[0] = HDCP_2_2_AKE_SEND_HPRIME;
458eff682f8SBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,
459eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.ake_h_prime+1,
460eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)-1);
461eff682f8SBhawanpreet Lakha 
462eff682f8SBhawanpreet Lakha 	} else {
463eff682f8SBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,
464eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.ake_h_prime,
465eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.ake_h_prime));
466eff682f8SBhawanpreet Lakha 	}
467eff682f8SBhawanpreet Lakha 	return status;
468eff682f8SBhawanpreet Lakha }
469eff682f8SBhawanpreet Lakha 
mod_hdcp_read_pairing_info(struct mod_hdcp * hdcp)470eff682f8SBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_read_pairing_info(struct mod_hdcp *hdcp)
471eff682f8SBhawanpreet Lakha {
472eff682f8SBhawanpreet Lakha 	enum mod_hdcp_status status;
473201a9446SWenjing Liu 
474eff682f8SBhawanpreet Lakha 	if (is_dp_hdcp(hdcp)) {
475eff682f8SBhawanpreet Lakha 		hdcp->auth.msg.hdcp2.ake_pairing_info[0] = HDCP_2_2_AKE_SEND_PAIRING_INFO;
476eff682f8SBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,
477eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.ake_pairing_info+1,
478eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info)-1);
479eff682f8SBhawanpreet Lakha 
480eff682f8SBhawanpreet Lakha 	} else {
481eff682f8SBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,
482eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.ake_pairing_info,
483eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info));
484eff682f8SBhawanpreet Lakha 	}
485eff682f8SBhawanpreet Lakha 	return status;
486eff682f8SBhawanpreet Lakha }
487eff682f8SBhawanpreet Lakha 
mod_hdcp_read_l_prime(struct mod_hdcp * hdcp)488eff682f8SBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_read_l_prime(struct mod_hdcp *hdcp)
489eff682f8SBhawanpreet Lakha {
490eff682f8SBhawanpreet Lakha 	enum mod_hdcp_status status;
491201a9446SWenjing Liu 
492eff682f8SBhawanpreet Lakha 	if (is_dp_hdcp(hdcp)) {
493eff682f8SBhawanpreet Lakha 		hdcp->auth.msg.hdcp2.lc_l_prime[0] = HDCP_2_2_LC_SEND_LPRIME;
494eff682f8SBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,
495eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.lc_l_prime+1,
496eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.lc_l_prime)-1);
497eff682f8SBhawanpreet Lakha 
498eff682f8SBhawanpreet Lakha 	} else {
499eff682f8SBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,
500eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.lc_l_prime,
501eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.lc_l_prime));
502eff682f8SBhawanpreet Lakha 	}
503eff682f8SBhawanpreet Lakha 	return status;
504eff682f8SBhawanpreet Lakha }
505eff682f8SBhawanpreet Lakha 
mod_hdcp_read_rx_id_list(struct mod_hdcp * hdcp)506d7ecf5e3SWenjing Liu enum mod_hdcp_status mod_hdcp_read_rx_id_list(struct mod_hdcp *hdcp)
507eff682f8SBhawanpreet Lakha {
508eff682f8SBhawanpreet Lakha 	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
509d7ecf5e3SWenjing Liu 
510d7ecf5e3SWenjing Liu 	if (is_dp_hdcp(hdcp)) {
511d7ecf5e3SWenjing Liu 		uint32_t device_count = 0;
512d7ecf5e3SWenjing Liu 		uint32_t rx_id_list_size = 0;
513201a9446SWenjing Liu 		uint32_t bytes_read = 0;
514eff682f8SBhawanpreet Lakha 
515eff682f8SBhawanpreet Lakha 		hdcp->auth.msg.hdcp2.rx_id_list[0] = HDCP_2_2_REP_SEND_RECVID_LIST;
516d7ecf5e3SWenjing Liu 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,
517d7ecf5e3SWenjing Liu 						hdcp->auth.msg.hdcp2.rx_id_list+1,
518d7ecf5e3SWenjing Liu 						HDCP_MAX_AUX_TRANSACTION_SIZE);
519d7ecf5e3SWenjing Liu 		if (status == MOD_HDCP_STATUS_SUCCESS) {
520d7ecf5e3SWenjing Liu 			bytes_read = HDCP_MAX_AUX_TRANSACTION_SIZE;
521d7ecf5e3SWenjing Liu 			device_count = HDCP_2_2_DEV_COUNT_LO(hdcp->auth.msg.hdcp2.rx_id_list[2]) +
522d7ecf5e3SWenjing Liu 					(HDCP_2_2_DEV_COUNT_HI(hdcp->auth.msg.hdcp2.rx_id_list[1]) << 4);
523d7ecf5e3SWenjing Liu 			rx_id_list_size = MIN((21 + 5 * device_count),
524d7ecf5e3SWenjing Liu 					(sizeof(hdcp->auth.msg.hdcp2.rx_id_list) - 1));
525d7ecf5e3SWenjing Liu 			status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2,
526d7ecf5e3SWenjing Liu 					hdcp->auth.msg.hdcp2.rx_id_list + 1 + bytes_read,
527eff682f8SBhawanpreet Lakha 					(rx_id_list_size - 1) / HDCP_MAX_AUX_TRANSACTION_SIZE * HDCP_MAX_AUX_TRANSACTION_SIZE);
528eff682f8SBhawanpreet Lakha 		}
529eff682f8SBhawanpreet Lakha 	} else {
530eff682f8SBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,
531eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.rx_id_list,
532eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.rx_id_list_size);
533eff682f8SBhawanpreet Lakha 	}
534eff682f8SBhawanpreet Lakha 	return status;
535eff682f8SBhawanpreet Lakha }
536eff682f8SBhawanpreet Lakha 
mod_hdcp_read_stream_ready(struct mod_hdcp * hdcp)537eff682f8SBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_read_stream_ready(struct mod_hdcp *hdcp)
538eff682f8SBhawanpreet Lakha {
539eff682f8SBhawanpreet Lakha 	enum mod_hdcp_status status;
540201a9446SWenjing Liu 
541eff682f8SBhawanpreet Lakha 	if (is_dp_hdcp(hdcp)) {
542eff682f8SBhawanpreet Lakha 		hdcp->auth.msg.hdcp2.repeater_auth_stream_ready[0] = HDCP_2_2_REP_STREAM_READY;
543eff682f8SBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,
544eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.repeater_auth_stream_ready+1,
545eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready)-1);
546eff682f8SBhawanpreet Lakha 
547eff682f8SBhawanpreet Lakha 	} else {
548eff682f8SBhawanpreet Lakha 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,
549eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.repeater_auth_stream_ready,
550eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready));
551eff682f8SBhawanpreet Lakha 	}
552eff682f8SBhawanpreet Lakha 	return status;
553eff682f8SBhawanpreet Lakha }
554eff682f8SBhawanpreet Lakha 
mod_hdcp_write_ake_init(struct mod_hdcp * hdcp)555eff682f8SBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_write_ake_init(struct mod_hdcp *hdcp)
556eff682f8SBhawanpreet Lakha {
557eff682f8SBhawanpreet Lakha 	enum mod_hdcp_status status;
558eff682f8SBhawanpreet Lakha 
559eff682f8SBhawanpreet Lakha 	if (is_dp_hdcp(hdcp))
560eff682f8SBhawanpreet Lakha 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT,
561eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.ake_init+1,
562eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.ake_init)-1);
563eff682f8SBhawanpreet Lakha 	else
564eff682f8SBhawanpreet Lakha 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT,
565eff682f8SBhawanpreet Lakha 					hdcp->auth.msg.hdcp2.ake_init,
566eff682f8SBhawanpreet Lakha 					sizeof(hdcp->auth.msg.hdcp2.ake_init));
567eff682f8SBhawanpreet Lakha 	return status;
568eff682f8SBhawanpreet Lakha }
569eff682f8SBhawanpreet Lakha 
mod_hdcp_write_no_stored_km(struct mod_hdcp * hdcp)570eff682f8SBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_write_no_stored_km(struct mod_hdcp *hdcp)
571eff682f8SBhawanpreet Lakha {
572eff682f8SBhawanpreet Lakha 	enum mod_hdcp_status status;
573eff682f8SBhawanpreet Lakha 
574eff682f8SBhawanpreet Lakha 	if (is_dp_hdcp(hdcp))
575eff682f8SBhawanpreet Lakha 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM,
576eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.ake_no_stored_km+1,
577eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)-1);
578eff682f8SBhawanpreet Lakha 	else
579eff682f8SBhawanpreet Lakha 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM,
580eff682f8SBhawanpreet Lakha 			hdcp->auth.msg.hdcp2.ake_no_stored_km,
581eff682f8SBhawanpreet Lakha 			sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km));
582eff682f8SBhawanpreet Lakha 	return status;
583eff682f8SBhawanpreet Lakha }
584eff682f8SBhawanpreet Lakha 
mod_hdcp_write_stored_km(struct mod_hdcp * hdcp)585eff682f8SBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_write_stored_km(struct mod_hdcp *hdcp)
586eff682f8SBhawanpreet Lakha {
587eff682f8SBhawanpreet Lakha 	enum mod_hdcp_status status;
588eff682f8SBhawanpreet Lakha 
589eff682f8SBhawanpreet Lakha 	if (is_dp_hdcp(hdcp))
590eff682f8SBhawanpreet Lakha 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM,
591eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.ake_stored_km+1,
592eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.ake_stored_km)-1);
593eff682f8SBhawanpreet Lakha 	else
594eff682f8SBhawanpreet Lakha 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM,
595eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.ake_stored_km,
596eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.ake_stored_km));
597eff682f8SBhawanpreet Lakha 	return status;
598eff682f8SBhawanpreet Lakha }
599eff682f8SBhawanpreet Lakha 
mod_hdcp_write_lc_init(struct mod_hdcp * hdcp)600eff682f8SBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_write_lc_init(struct mod_hdcp *hdcp)
601eff682f8SBhawanpreet Lakha {
602eff682f8SBhawanpreet Lakha 	enum mod_hdcp_status status;
603eff682f8SBhawanpreet Lakha 
604eff682f8SBhawanpreet Lakha 	if (is_dp_hdcp(hdcp))
605eff682f8SBhawanpreet Lakha 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT,
606eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.lc_init+1,
607eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.lc_init)-1);
608eff682f8SBhawanpreet Lakha 	else
609eff682f8SBhawanpreet Lakha 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT,
610eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.lc_init,
611eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.lc_init));
612eff682f8SBhawanpreet Lakha 	return status;
613eff682f8SBhawanpreet Lakha }
614eff682f8SBhawanpreet Lakha 
mod_hdcp_write_eks(struct mod_hdcp * hdcp)615eff682f8SBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_write_eks(struct mod_hdcp *hdcp)
616eff682f8SBhawanpreet Lakha {
617eff682f8SBhawanpreet Lakha 	enum mod_hdcp_status status;
618eff682f8SBhawanpreet Lakha 
619eff682f8SBhawanpreet Lakha 	if (is_dp_hdcp(hdcp))
620eff682f8SBhawanpreet Lakha 		status = write(hdcp,
621eff682f8SBhawanpreet Lakha 				MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,
622eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.ske_eks+1,
623eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.ske_eks)-1);
624eff682f8SBhawanpreet Lakha 	else
625eff682f8SBhawanpreet Lakha 		status = write(hdcp,
626eff682f8SBhawanpreet Lakha 			MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,
627eff682f8SBhawanpreet Lakha 			hdcp->auth.msg.hdcp2.ske_eks,
628eff682f8SBhawanpreet Lakha 			sizeof(hdcp->auth.msg.hdcp2.ske_eks));
629eff682f8SBhawanpreet Lakha 	return status;
630eff682f8SBhawanpreet Lakha }
631eff682f8SBhawanpreet Lakha 
mod_hdcp_write_repeater_auth_ack(struct mod_hdcp * hdcp)632eff682f8SBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_write_repeater_auth_ack(struct mod_hdcp *hdcp)
633eff682f8SBhawanpreet Lakha {
634eff682f8SBhawanpreet Lakha 	enum mod_hdcp_status status;
635eff682f8SBhawanpreet Lakha 
636eff682f8SBhawanpreet Lakha 	if (is_dp_hdcp(hdcp))
637eff682f8SBhawanpreet Lakha 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,
638eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.repeater_auth_ack+1,
639eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack)-1);
640eff682f8SBhawanpreet Lakha 	else
641eff682f8SBhawanpreet Lakha 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,
642eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.repeater_auth_ack,
643eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack));
644eff682f8SBhawanpreet Lakha 	return status;
645eff682f8SBhawanpreet Lakha }
646eff682f8SBhawanpreet Lakha 
mod_hdcp_write_stream_manage(struct mod_hdcp * hdcp)647eff682f8SBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_write_stream_manage(struct mod_hdcp *hdcp)
648eff682f8SBhawanpreet Lakha {
649eff682f8SBhawanpreet Lakha 	enum mod_hdcp_status status;
650eff682f8SBhawanpreet Lakha 
651eff682f8SBhawanpreet Lakha 	if (is_dp_hdcp(hdcp))
652eff682f8SBhawanpreet Lakha 		status = write(hdcp,
653eff682f8SBhawanpreet Lakha 				MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,
654eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.repeater_auth_stream_manage+1,
655eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.stream_manage_size-1);
656eff682f8SBhawanpreet Lakha 	else
657eff682f8SBhawanpreet Lakha 		status = write(hdcp,
658eff682f8SBhawanpreet Lakha 				MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,
659eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.repeater_auth_stream_manage,
660eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.stream_manage_size);
661eff682f8SBhawanpreet Lakha 	return status;
662eff682f8SBhawanpreet Lakha }
663eff682f8SBhawanpreet Lakha 
mod_hdcp_write_content_type(struct mod_hdcp * hdcp)664eff682f8SBhawanpreet Lakha enum mod_hdcp_status mod_hdcp_write_content_type(struct mod_hdcp *hdcp)
665eff682f8SBhawanpreet Lakha {
666eff682f8SBhawanpreet Lakha 	enum mod_hdcp_status status;
667eff682f8SBhawanpreet Lakha 
668eff682f8SBhawanpreet Lakha 	if (is_dp_hdcp(hdcp))
669eff682f8SBhawanpreet Lakha 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE,
670eff682f8SBhawanpreet Lakha 				hdcp->auth.msg.hdcp2.content_stream_type_dp+1,
671eff682f8SBhawanpreet Lakha 				sizeof(hdcp->auth.msg.hdcp2.content_stream_type_dp)-1);
672eff682f8SBhawanpreet Lakha 	else
673eff682f8SBhawanpreet Lakha 		status = MOD_HDCP_STATUS_INVALID_OPERATION;
674958000cbSHarmanprit Tatla 	return status;
675958000cbSHarmanprit Tatla }
676958000cbSHarmanprit Tatla 
mod_hdcp_clear_cp_irq_status(struct mod_hdcp * hdcp)6775cd04c48SHarmanprit Tatla enum mod_hdcp_status mod_hdcp_clear_cp_irq_status(struct mod_hdcp *hdcp)
678958000cbSHarmanprit Tatla {
679958000cbSHarmanprit Tatla 	uint8_t clear_cp_irq_bit = DP_CP_IRQ;
680958000cbSHarmanprit Tatla 	uint32_t size = 1;
6815cd04c48SHarmanprit Tatla 
6825cd04c48SHarmanprit Tatla 	if (is_dp_hdcp(hdcp)) {
6835cd04c48SHarmanprit Tatla 		uint32_t cp_irq_addrs = (hdcp->connection.link.dp.rev >= 0x14)
6845cd04c48SHarmanprit Tatla 				? DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0:DP_DEVICE_SERVICE_IRQ_VECTOR;
685958000cbSHarmanprit Tatla 		return hdcp->config.ddc.funcs.write_dpcd(hdcp->config.ddc.handle, cp_irq_addrs,
686958000cbSHarmanprit Tatla 				&clear_cp_irq_bit, size) ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE;
687958000cbSHarmanprit Tatla 	}
688958000cbSHarmanprit Tatla 
689 	return MOD_HDCP_STATUS_INVALID_OPERATION;
690 }
691