1 /*
2  * Copyright 2019 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25 
26 #include <linux/slab.h>
27 
28 #include "dm_services.h"
29 #include "dm_helpers.h"
30 #include "include/hdcp_types.h"
31 #include "include/i2caux_interface.h"
32 #include "include/signal_types.h"
33 #include "core_types.h"
34 #include "dc_link_ddc.h"
35 #include "link_hwss.h"
36 #include "inc/link_dpcd.h"
37 
38 #define DC_LOGGER \
39 	link->ctx->logger
40 #define HDCP14_KSV_SIZE 5
41 #define HDCP14_MAX_KSV_FIFO_SIZE 127*HDCP14_KSV_SIZE
42 
43 static const bool hdcp_cmd_is_read[HDCP_MESSAGE_ID_MAX] = {
44 	[HDCP_MESSAGE_ID_READ_BKSV] = true,
45 	[HDCP_MESSAGE_ID_READ_RI_R0] = true,
46 	[HDCP_MESSAGE_ID_READ_PJ] = true,
47 	[HDCP_MESSAGE_ID_WRITE_AKSV] = false,
48 	[HDCP_MESSAGE_ID_WRITE_AINFO] = false,
49 	[HDCP_MESSAGE_ID_WRITE_AN] = false,
50 	[HDCP_MESSAGE_ID_READ_VH_X] = true,
51 	[HDCP_MESSAGE_ID_READ_VH_0] = true,
52 	[HDCP_MESSAGE_ID_READ_VH_1] = true,
53 	[HDCP_MESSAGE_ID_READ_VH_2] = true,
54 	[HDCP_MESSAGE_ID_READ_VH_3] = true,
55 	[HDCP_MESSAGE_ID_READ_VH_4] = true,
56 	[HDCP_MESSAGE_ID_READ_BCAPS] = true,
57 	[HDCP_MESSAGE_ID_READ_BSTATUS] = true,
58 	[HDCP_MESSAGE_ID_READ_KSV_FIFO] = true,
59 	[HDCP_MESSAGE_ID_READ_BINFO] = true,
60 	[HDCP_MESSAGE_ID_HDCP2VERSION] = true,
61 	[HDCP_MESSAGE_ID_RX_CAPS] = true,
62 	[HDCP_MESSAGE_ID_WRITE_AKE_INIT] = false,
63 	[HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = true,
64 	[HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = false,
65 	[HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = false,
66 	[HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = true,
67 	[HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = true,
68 	[HDCP_MESSAGE_ID_WRITE_LC_INIT] = false,
69 	[HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = true,
70 	[HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = false,
71 	[HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = true,
72 	[HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = false,
73 	[HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = false,
74 	[HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = true,
75 	[HDCP_MESSAGE_ID_READ_RXSTATUS] = true,
76 	[HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = false
77 };
78 
79 static const uint8_t hdcp_i2c_offsets[HDCP_MESSAGE_ID_MAX] = {
80 	[HDCP_MESSAGE_ID_READ_BKSV] = 0x0,
81 	[HDCP_MESSAGE_ID_READ_RI_R0] = 0x8,
82 	[HDCP_MESSAGE_ID_READ_PJ] = 0xA,
83 	[HDCP_MESSAGE_ID_WRITE_AKSV] = 0x10,
84 	[HDCP_MESSAGE_ID_WRITE_AINFO] = 0x15,
85 	[HDCP_MESSAGE_ID_WRITE_AN] = 0x18,
86 	[HDCP_MESSAGE_ID_READ_VH_X] = 0x20,
87 	[HDCP_MESSAGE_ID_READ_VH_0] = 0x20,
88 	[HDCP_MESSAGE_ID_READ_VH_1] = 0x24,
89 	[HDCP_MESSAGE_ID_READ_VH_2] = 0x28,
90 	[HDCP_MESSAGE_ID_READ_VH_3] = 0x2C,
91 	[HDCP_MESSAGE_ID_READ_VH_4] = 0x30,
92 	[HDCP_MESSAGE_ID_READ_BCAPS] = 0x40,
93 	[HDCP_MESSAGE_ID_READ_BSTATUS] = 0x41,
94 	[HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x43,
95 	[HDCP_MESSAGE_ID_READ_BINFO] = 0xFF,
96 	[HDCP_MESSAGE_ID_HDCP2VERSION] = 0x50,
97 	[HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x60,
98 	[HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x80,
99 	[HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x60,
100 	[HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x60,
101 	[HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x80,
102 	[HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x80,
103 	[HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x60,
104 	[HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x80,
105 	[HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x60,
106 	[HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x80,
107 	[HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x60,
108 	[HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x60,
109 	[HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x80,
110 	[HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x70,
111 	[HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x0,
112 };
113 
114 struct protection_properties {
115 	bool supported;
116 	bool (*process_transaction)(
117 		struct dc_link *link,
118 		struct hdcp_protection_message *message_info);
119 };
120 
121 static const struct protection_properties non_supported_protection = {
122 	.supported = false
123 };
124 
hdmi_14_process_transaction(struct dc_link * link,struct hdcp_protection_message * message_info)125 static bool hdmi_14_process_transaction(
126 	struct dc_link *link,
127 	struct hdcp_protection_message *message_info)
128 {
129 	uint8_t *buff = NULL;
130 	bool result;
131 	const uint8_t hdcp_i2c_addr_link_primary = 0x3a; /* 0x74 >> 1*/
132 	const uint8_t hdcp_i2c_addr_link_secondary = 0x3b; /* 0x76 >> 1*/
133 	struct i2c_command i2c_command;
134 	uint8_t offset = hdcp_i2c_offsets[message_info->msg_id];
135 	struct i2c_payload i2c_payloads[] = {
136 		{ true, 0, 1, &offset },
137 		/* actual hdcp payload, will be filled later, zeroed for now*/
138 		{ 0 }
139 	};
140 
141 	switch (message_info->link) {
142 	case HDCP_LINK_SECONDARY:
143 		i2c_payloads[0].address = hdcp_i2c_addr_link_secondary;
144 		i2c_payloads[1].address = hdcp_i2c_addr_link_secondary;
145 		break;
146 	case HDCP_LINK_PRIMARY:
147 	default:
148 		i2c_payloads[0].address = hdcp_i2c_addr_link_primary;
149 		i2c_payloads[1].address = hdcp_i2c_addr_link_primary;
150 		break;
151 	}
152 
153 	if (hdcp_cmd_is_read[message_info->msg_id]) {
154 		i2c_payloads[1].write = false;
155 		i2c_command.number_of_payloads = ARRAY_SIZE(i2c_payloads);
156 		i2c_payloads[1].length = message_info->length;
157 		i2c_payloads[1].data = message_info->data;
158 	} else {
159 		i2c_command.number_of_payloads = 1;
160 		buff = kzalloc(message_info->length + 1, GFP_KERNEL);
161 
162 		if (!buff)
163 			return false;
164 
165 		buff[0] = offset;
166 		memmove(&buff[1], message_info->data, message_info->length);
167 		i2c_payloads[0].length = message_info->length + 1;
168 		i2c_payloads[0].data = buff;
169 	}
170 
171 	i2c_command.payloads = i2c_payloads;
172 	i2c_command.engine = I2C_COMMAND_ENGINE_HW;//only HW
173 	i2c_command.speed = link->ddc->ctx->dc->caps.i2c_speed_in_khz;
174 
175 	result = dm_helpers_submit_i2c(
176 			link->ctx,
177 			link,
178 			&i2c_command);
179 	kfree(buff);
180 
181 	return result;
182 }
183 
184 static const struct protection_properties hdmi_14_protection = {
185 	.supported = true,
186 	.process_transaction = hdmi_14_process_transaction
187 };
188 
189 static const uint32_t hdcp_dpcd_addrs[HDCP_MESSAGE_ID_MAX] = {
190 	[HDCP_MESSAGE_ID_READ_BKSV] = 0x68000,
191 	[HDCP_MESSAGE_ID_READ_RI_R0] = 0x68005,
192 	[HDCP_MESSAGE_ID_READ_PJ] = 0xFFFFFFFF,
193 	[HDCP_MESSAGE_ID_WRITE_AKSV] = 0x68007,
194 	[HDCP_MESSAGE_ID_WRITE_AINFO] = 0x6803B,
195 	[HDCP_MESSAGE_ID_WRITE_AN] = 0x6800c,
196 	[HDCP_MESSAGE_ID_READ_VH_X] = 0x68014,
197 	[HDCP_MESSAGE_ID_READ_VH_0] = 0x68014,
198 	[HDCP_MESSAGE_ID_READ_VH_1] = 0x68018,
199 	[HDCP_MESSAGE_ID_READ_VH_2] = 0x6801c,
200 	[HDCP_MESSAGE_ID_READ_VH_3] = 0x68020,
201 	[HDCP_MESSAGE_ID_READ_VH_4] = 0x68024,
202 	[HDCP_MESSAGE_ID_READ_BCAPS] = 0x68028,
203 	[HDCP_MESSAGE_ID_READ_BSTATUS] = 0x68029,
204 	[HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x6802c,
205 	[HDCP_MESSAGE_ID_READ_BINFO] = 0x6802a,
206 	[HDCP_MESSAGE_ID_RX_CAPS] = 0x6921d,
207 	[HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x69000,
208 	[HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x6900b,
209 	[HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x69220,
210 	[HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x692a0,
211 	[HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x692c0,
212 	[HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x692e0,
213 	[HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x692f0,
214 	[HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x692f8,
215 	[HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x69318,
216 	[HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x69330,
217 	[HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x693e0,
218 	[HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x693f0,
219 	[HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x69473,
220 	[HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x69493,
221 	[HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x69494
222 };
223 
dpcd_access_helper(struct dc_link * link,uint32_t length,uint8_t * data,uint32_t dpcd_addr,bool is_read)224 static bool dpcd_access_helper(
225 	struct dc_link *link,
226 	uint32_t length,
227 	uint8_t *data,
228 	uint32_t dpcd_addr,
229 	bool is_read)
230 {
231 	enum dc_status status;
232 	uint32_t cur_length = 0;
233 	uint32_t offset = 0;
234 	uint32_t ksv_read_size = 0x6803b - 0x6802c;
235 
236 	/* Read KSV, need repeatedly handle */
237 	if (dpcd_addr == 0x6802c) {
238 		if (length % HDCP14_KSV_SIZE) {
239 			DC_LOG_ERROR("%s: KsvFifo Size(%d) is not a multiple of HDCP14_KSV_SIZE(%d)\n",
240 				__func__,
241 				length,
242 				HDCP14_KSV_SIZE);
243 		}
244 		if (length > HDCP14_MAX_KSV_FIFO_SIZE) {
245 			DC_LOG_ERROR("%s: KsvFifo Size(%d) is greater than HDCP14_MAX_KSV_FIFO_SIZE(%d)\n",
246 				__func__,
247 				length,
248 				HDCP14_MAX_KSV_FIFO_SIZE);
249 		}
250 
251 		DC_LOG_ERROR("%s: Reading %d Ksv(s) from KsvFifo\n",
252 			__func__,
253 			length / HDCP14_KSV_SIZE);
254 
255 		while (length > 0) {
256 			if (length > ksv_read_size) {
257 				status = core_link_read_dpcd(
258 					link,
259 					dpcd_addr + offset,
260 					data + offset,
261 					ksv_read_size);
262 
263 				data += ksv_read_size;
264 				length -= ksv_read_size;
265 			} else {
266 				status = core_link_read_dpcd(
267 					link,
268 					dpcd_addr + offset,
269 					data + offset,
270 					length);
271 
272 				data += length;
273 				length = 0;
274 			}
275 
276 			if (status != DC_OK)
277 				return false;
278 		}
279 	} else {
280 		while (length > 0) {
281 			if (length > DEFAULT_AUX_MAX_DATA_SIZE)
282 				cur_length = DEFAULT_AUX_MAX_DATA_SIZE;
283 			else
284 				cur_length = length;
285 
286 			if (is_read) {
287 				status = core_link_read_dpcd(
288 					link,
289 					dpcd_addr + offset,
290 					data + offset,
291 					cur_length);
292 			} else {
293 				status = core_link_write_dpcd(
294 					link,
295 					dpcd_addr + offset,
296 					data + offset,
297 					cur_length);
298 			}
299 
300 			if (status != DC_OK)
301 				return false;
302 
303 			length -= cur_length;
304 			offset += cur_length;
305 		}
306 	}
307 	return true;
308 }
309 
dp_11_process_transaction(struct dc_link * link,struct hdcp_protection_message * message_info)310 static bool dp_11_process_transaction(
311 	struct dc_link *link,
312 	struct hdcp_protection_message *message_info)
313 {
314 	return dpcd_access_helper(
315 		link,
316 		message_info->length,
317 		message_info->data,
318 		hdcp_dpcd_addrs[message_info->msg_id],
319 		hdcp_cmd_is_read[message_info->msg_id]);
320 }
321 
322 static const struct protection_properties dp_11_protection = {
323 	.supported = true,
324 	.process_transaction = dp_11_process_transaction
325 };
326 
get_protection_properties_by_signal(struct dc_link * link,enum signal_type st,enum hdcp_version version)327 static const struct protection_properties *get_protection_properties_by_signal(
328 	struct dc_link *link,
329 	enum signal_type st,
330 	enum hdcp_version version)
331 {
332 	switch (version) {
333 	case HDCP_VERSION_14:
334 		switch (st) {
335 		case SIGNAL_TYPE_DVI_SINGLE_LINK:
336 		case SIGNAL_TYPE_DVI_DUAL_LINK:
337 		case SIGNAL_TYPE_HDMI_TYPE_A:
338 			return &hdmi_14_protection;
339 		case SIGNAL_TYPE_DISPLAY_PORT:
340 			if (link &&
341 				(link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER ||
342 				link->dpcd_caps.dongle_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER)) {
343 				return &non_supported_protection;
344 			}
345 			return &dp_11_protection;
346 		case SIGNAL_TYPE_DISPLAY_PORT_MST:
347 		case SIGNAL_TYPE_EDP:
348 			return &dp_11_protection;
349 		default:
350 			return &non_supported_protection;
351 		}
352 		break;
353 	case HDCP_VERSION_22:
354 		switch (st) {
355 		case SIGNAL_TYPE_DVI_SINGLE_LINK:
356 		case SIGNAL_TYPE_DVI_DUAL_LINK:
357 		case SIGNAL_TYPE_HDMI_TYPE_A:
358 			return &hdmi_14_protection; //todo version2.2
359 		case SIGNAL_TYPE_DISPLAY_PORT:
360 		case SIGNAL_TYPE_DISPLAY_PORT_MST:
361 		case SIGNAL_TYPE_EDP:
362 			return &dp_11_protection;  //todo version2.2
363 		default:
364 			return &non_supported_protection;
365 		}
366 		break;
367 	default:
368 		return &non_supported_protection;
369 	}
370 }
371 
dc_process_hdcp_msg(enum signal_type signal,struct dc_link * link,struct hdcp_protection_message * message_info)372 enum hdcp_message_status dc_process_hdcp_msg(
373 	enum signal_type signal,
374 	struct dc_link *link,
375 	struct hdcp_protection_message *message_info)
376 {
377 	enum hdcp_message_status status = HDCP_MESSAGE_FAILURE;
378 	uint32_t i = 0;
379 
380 	const struct protection_properties *protection_props;
381 
382 	if (!message_info)
383 		return HDCP_MESSAGE_UNSUPPORTED;
384 
385 	if (message_info->msg_id < HDCP_MESSAGE_ID_READ_BKSV ||
386 		message_info->msg_id >= HDCP_MESSAGE_ID_MAX)
387 		return HDCP_MESSAGE_UNSUPPORTED;
388 
389 	protection_props =
390 		get_protection_properties_by_signal(
391 			link,
392 			signal,
393 			message_info->version);
394 
395 	if (!protection_props->supported)
396 		return HDCP_MESSAGE_UNSUPPORTED;
397 
398 	if (protection_props->process_transaction(
399 		link,
400 		message_info)) {
401 		status = HDCP_MESSAGE_SUCCESS;
402 	} else {
403 		for (i = 0; i < message_info->max_retries; i++) {
404 			if (protection_props->process_transaction(
405 						link,
406 						message_info)) {
407 				status = HDCP_MESSAGE_SUCCESS;
408 				break;
409 			}
410 		}
411 	}
412 
413 	return status;
414 }
415 
416