1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
43static 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
79static 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
114struct protection_properties {
115 bool supported;
116 bool (*process_transaction)(
117 struct dc_link *link,
118 struct hdcp_protection_message *message_info);
119};
120
121static const struct protection_properties non_supported_protection = {
122 .supported = false
123};
124
125static 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;
132 const uint8_t hdcp_i2c_addr_link_secondary = 0x3b;
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
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;
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
184static const struct protection_properties hdmi_14_protection = {
185 .supported = true,
186 .process_transaction = hdmi_14_process_transaction
187};
188
189static 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
224static 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
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
310static 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
322static const struct protection_properties dp_11_protection = {
323 .supported = true,
324 .process_transaction = dp_11_process_transaction
325};
326
327static 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;
359 case SIGNAL_TYPE_DISPLAY_PORT:
360 case SIGNAL_TYPE_DISPLAY_PORT_MST:
361 case SIGNAL_TYPE_EDP:
362 return &dp_11_protection;
363 default:
364 return &non_supported_protection;
365 }
366 break;
367 default:
368 return &non_supported_protection;
369 }
370}
371
372enum 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