]> Git Repo - J-linux.git/blob - drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / gpu / drm / amd / display / modules / hdcp / hdcp_ddc.c
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 "hdcp.h"
27
28 #ifndef MIN
29 #define MIN(a, b) ((a) < (b) ? (a) : (b))
30 #endif
31 #define HDCP_I2C_ADDR 0x3a      /* 0x74 >> 1*/
32 #define KSV_READ_SIZE 0xf       /* 0x6803b - 0x6802c */
33 #define HDCP_MAX_AUX_TRANSACTION_SIZE 16
34
35 #define DP_CP_IRQ (1 << 2)
36
37 enum mod_hdcp_ddc_message_id {
38         MOD_HDCP_MESSAGE_ID_INVALID = -1,
39
40         /* HDCP 1.4 */
41
42         MOD_HDCP_MESSAGE_ID_READ_BKSV = 0,
43         MOD_HDCP_MESSAGE_ID_READ_RI_R0,
44         MOD_HDCP_MESSAGE_ID_WRITE_AKSV,
45         MOD_HDCP_MESSAGE_ID_WRITE_AINFO,
46         MOD_HDCP_MESSAGE_ID_WRITE_AN,
47         MOD_HDCP_MESSAGE_ID_READ_VH_X,
48         MOD_HDCP_MESSAGE_ID_READ_VH_0,
49         MOD_HDCP_MESSAGE_ID_READ_VH_1,
50         MOD_HDCP_MESSAGE_ID_READ_VH_2,
51         MOD_HDCP_MESSAGE_ID_READ_VH_3,
52         MOD_HDCP_MESSAGE_ID_READ_VH_4,
53         MOD_HDCP_MESSAGE_ID_READ_BCAPS,
54         MOD_HDCP_MESSAGE_ID_READ_BSTATUS,
55         MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO,
56         MOD_HDCP_MESSAGE_ID_READ_BINFO,
57
58         /* HDCP 2.2 */
59
60         MOD_HDCP_MESSAGE_ID_HDCP2VERSION,
61         MOD_HDCP_MESSAGE_ID_RX_CAPS,
62         MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT,
63         MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,
64         MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM,
65         MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM,
66         MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,
67         MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,
68         MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT,
69         MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,
70         MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,
71         MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,
72         MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2,
73         MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,
74         MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,
75         MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,
76         MOD_HDCP_MESSAGE_ID_READ_RXSTATUS,
77         MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE,
78
79         MOD_HDCP_MESSAGE_ID_MAX
80 };
81
82 static const uint8_t hdcp_i2c_offsets[] = {
83         [MOD_HDCP_MESSAGE_ID_READ_BKSV] = 0x0,
84         [MOD_HDCP_MESSAGE_ID_READ_RI_R0] = 0x8,
85         [MOD_HDCP_MESSAGE_ID_WRITE_AKSV] = 0x10,
86         [MOD_HDCP_MESSAGE_ID_WRITE_AINFO] = 0x15,
87         [MOD_HDCP_MESSAGE_ID_WRITE_AN] = 0x18,
88         [MOD_HDCP_MESSAGE_ID_READ_VH_X] = 0x20,
89         [MOD_HDCP_MESSAGE_ID_READ_VH_0] = 0x20,
90         [MOD_HDCP_MESSAGE_ID_READ_VH_1] = 0x24,
91         [MOD_HDCP_MESSAGE_ID_READ_VH_2] = 0x28,
92         [MOD_HDCP_MESSAGE_ID_READ_VH_3] = 0x2C,
93         [MOD_HDCP_MESSAGE_ID_READ_VH_4] = 0x30,
94         [MOD_HDCP_MESSAGE_ID_READ_BCAPS] = 0x40,
95         [MOD_HDCP_MESSAGE_ID_READ_BSTATUS] = 0x41,
96         [MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x43,
97         [MOD_HDCP_MESSAGE_ID_READ_BINFO] = 0xFF,
98         [MOD_HDCP_MESSAGE_ID_HDCP2VERSION] = 0x50,
99         [MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x60,
100         [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x80,
101         [MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x60,
102         [MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x60,
103         [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x80,
104         [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x80,
105         [MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x60,
106         [MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x80,
107         [MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x60,
108         [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x80,
109         [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2] = 0x80,
110         [MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x60,
111         [MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x60,
112         [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x80,
113         [MOD_HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x70,
114         [MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x0
115 };
116
117 static const uint32_t hdcp_dpcd_addrs[] = {
118         [MOD_HDCP_MESSAGE_ID_READ_BKSV] = 0x68000,
119         [MOD_HDCP_MESSAGE_ID_READ_RI_R0] = 0x68005,
120         [MOD_HDCP_MESSAGE_ID_WRITE_AKSV] = 0x68007,
121         [MOD_HDCP_MESSAGE_ID_WRITE_AINFO] = 0x6803B,
122         [MOD_HDCP_MESSAGE_ID_WRITE_AN] = 0x6800c,
123         [MOD_HDCP_MESSAGE_ID_READ_VH_X] = 0x68014,
124         [MOD_HDCP_MESSAGE_ID_READ_VH_0] = 0x68014,
125         [MOD_HDCP_MESSAGE_ID_READ_VH_1] = 0x68018,
126         [MOD_HDCP_MESSAGE_ID_READ_VH_2] = 0x6801c,
127         [MOD_HDCP_MESSAGE_ID_READ_VH_3] = 0x68020,
128         [MOD_HDCP_MESSAGE_ID_READ_VH_4] = 0x68024,
129         [MOD_HDCP_MESSAGE_ID_READ_BCAPS] = 0x68028,
130         [MOD_HDCP_MESSAGE_ID_READ_BSTATUS] = 0x68029,
131         [MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x6802c,
132         [MOD_HDCP_MESSAGE_ID_READ_BINFO] = 0x6802a,
133         [MOD_HDCP_MESSAGE_ID_RX_CAPS] = 0x6921d,
134         [MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x69000,
135         [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x6900b,
136         [MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x69220,
137         [MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x692a0,
138         [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x692c0,
139         [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x692e0,
140         [MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x692f0,
141         [MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x692f8,
142         [MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x69318,
143         [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x69330,
144         [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2] = 0x69340,
145         [MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x693e0,
146         [MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x693f0,
147         [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x69473,
148         [MOD_HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x69493,
149         [MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x69494
150 };
151
152 static enum mod_hdcp_status read(struct mod_hdcp *hdcp,
153                 enum mod_hdcp_ddc_message_id msg_id,
154                 uint8_t *buf,
155                 uint32_t buf_len)
156 {
157         bool success = true;
158         uint32_t cur_size = 0;
159         uint32_t data_offset = 0;
160
161         if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID ||
162                 msg_id >= MOD_HDCP_MESSAGE_ID_MAX)
163                 return MOD_HDCP_STATUS_DDC_FAILURE;
164
165         if (is_dp_hdcp(hdcp)) {
166                 int num_dpcd_addrs = ARRAY_SIZE(hdcp_dpcd_addrs);
167                 if (msg_id >= num_dpcd_addrs)
168                         return MOD_HDCP_STATUS_DDC_FAILURE;
169
170                 while (buf_len > 0) {
171                         cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE);
172                         success = hdcp->config.ddc.funcs.read_dpcd(hdcp->config.ddc.handle,
173                                         hdcp_dpcd_addrs[msg_id] + data_offset,
174                                         buf + data_offset,
175                                         cur_size);
176
177                         if (!success)
178                                 break;
179
180                         buf_len -= cur_size;
181                         data_offset += cur_size;
182                 }
183         } else {
184                 int num_i2c_offsets = ARRAY_SIZE(hdcp_i2c_offsets);
185                 if (msg_id >= num_i2c_offsets)
186                         return MOD_HDCP_STATUS_DDC_FAILURE;
187
188                 success = hdcp->config.ddc.funcs.read_i2c(
189                                 hdcp->config.ddc.handle,
190                                 HDCP_I2C_ADDR,
191                                 hdcp_i2c_offsets[msg_id],
192                                 buf,
193                                 (uint32_t)buf_len);
194         }
195
196         return success ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE;
197 }
198
199 static enum mod_hdcp_status read_repeatedly(struct mod_hdcp *hdcp,
200                 enum mod_hdcp_ddc_message_id msg_id,
201                 uint8_t *buf,
202                 uint32_t buf_len,
203                 uint8_t read_size)
204 {
205         enum mod_hdcp_status status = MOD_HDCP_STATUS_DDC_FAILURE;
206         uint32_t cur_size = 0;
207         uint32_t data_offset = 0;
208
209         while (buf_len > 0) {
210                 cur_size = MIN(buf_len, read_size);
211                 status = read(hdcp, msg_id, buf + data_offset, cur_size);
212
213                 if (status != MOD_HDCP_STATUS_SUCCESS)
214                         break;
215
216                 buf_len -= cur_size;
217                 data_offset += cur_size;
218         }
219
220         return status;
221 }
222
223 static enum mod_hdcp_status write(struct mod_hdcp *hdcp,
224                 enum mod_hdcp_ddc_message_id msg_id,
225                 uint8_t *buf,
226                 uint32_t buf_len)
227 {
228         bool success = true;
229         uint32_t cur_size = 0;
230         uint32_t data_offset = 0;
231
232         if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID ||
233                 msg_id >= MOD_HDCP_MESSAGE_ID_MAX)
234                 return MOD_HDCP_STATUS_DDC_FAILURE;
235
236         if (is_dp_hdcp(hdcp)) {
237                 int num_dpcd_addrs = ARRAY_SIZE(hdcp_dpcd_addrs);
238                 if (msg_id >= num_dpcd_addrs)
239                         return MOD_HDCP_STATUS_DDC_FAILURE;
240
241                 while (buf_len > 0) {
242                         cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE);
243                         success = hdcp->config.ddc.funcs.write_dpcd(
244                                         hdcp->config.ddc.handle,
245                                         hdcp_dpcd_addrs[msg_id] + data_offset,
246                                         buf + data_offset,
247                                         cur_size);
248
249                         if (!success)
250                                 break;
251
252                         buf_len -= cur_size;
253                         data_offset += cur_size;
254                 }
255         } else {
256                 int num_i2c_offsets = ARRAY_SIZE(hdcp_i2c_offsets);
257                 if (msg_id >= num_i2c_offsets)
258                         return MOD_HDCP_STATUS_DDC_FAILURE;
259
260                 hdcp->buf[0] = hdcp_i2c_offsets[msg_id];
261                 memmove(&hdcp->buf[1], buf, buf_len);
262                 success = hdcp->config.ddc.funcs.write_i2c(
263                                 hdcp->config.ddc.handle,
264                                 HDCP_I2C_ADDR,
265                                 hdcp->buf,
266                                 (uint32_t)(buf_len+1));
267         }
268
269         return success ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE;
270 }
271
272 enum mod_hdcp_status mod_hdcp_read_bksv(struct mod_hdcp *hdcp)
273 {
274         return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BKSV,
275                         hdcp->auth.msg.hdcp1.bksv,
276                         sizeof(hdcp->auth.msg.hdcp1.bksv));
277 }
278
279 enum mod_hdcp_status mod_hdcp_read_bcaps(struct mod_hdcp *hdcp)
280 {
281         return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BCAPS,
282                         &hdcp->auth.msg.hdcp1.bcaps,
283                         sizeof(hdcp->auth.msg.hdcp1.bcaps));
284 }
285
286 enum mod_hdcp_status mod_hdcp_read_bstatus(struct mod_hdcp *hdcp)
287 {
288         enum mod_hdcp_status status;
289
290         if (is_dp_hdcp(hdcp))
291                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BSTATUS,
292                                         (uint8_t *)&hdcp->auth.msg.hdcp1.bstatus,
293                                         1);
294         else
295                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BSTATUS,
296                                 (uint8_t *)&hdcp->auth.msg.hdcp1.bstatus,
297                                 sizeof(hdcp->auth.msg.hdcp1.bstatus));
298         return status;
299 }
300
301 enum mod_hdcp_status mod_hdcp_read_r0p(struct mod_hdcp *hdcp)
302 {
303         return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RI_R0,
304                         (uint8_t *)&hdcp->auth.msg.hdcp1.r0p,
305                         sizeof(hdcp->auth.msg.hdcp1.r0p));
306 }
307
308 /* special case, reading repeatedly at the same address, don't use read() */
309 enum mod_hdcp_status mod_hdcp_read_ksvlist(struct mod_hdcp *hdcp)
310 {
311         enum mod_hdcp_status status;
312
313         if (is_dp_hdcp(hdcp))
314                 status = read_repeatedly(hdcp, MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO,
315                                 hdcp->auth.msg.hdcp1.ksvlist,
316                                 hdcp->auth.msg.hdcp1.ksvlist_size,
317                                 KSV_READ_SIZE);
318         else
319                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO,
320                                 (uint8_t *)&hdcp->auth.msg.hdcp1.ksvlist,
321                                 hdcp->auth.msg.hdcp1.ksvlist_size);
322         return status;
323 }
324
325 enum mod_hdcp_status mod_hdcp_read_vp(struct mod_hdcp *hdcp)
326 {
327         enum mod_hdcp_status status;
328
329         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_0,
330                         &hdcp->auth.msg.hdcp1.vp[0], 4);
331         if (status != MOD_HDCP_STATUS_SUCCESS)
332                 goto out;
333
334         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_1,
335                         &hdcp->auth.msg.hdcp1.vp[4], 4);
336         if (status != MOD_HDCP_STATUS_SUCCESS)
337                 goto out;
338
339         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_2,
340                         &hdcp->auth.msg.hdcp1.vp[8], 4);
341         if (status != MOD_HDCP_STATUS_SUCCESS)
342                 goto out;
343
344         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_3,
345                         &hdcp->auth.msg.hdcp1.vp[12], 4);
346         if (status != MOD_HDCP_STATUS_SUCCESS)
347                 goto out;
348
349         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_4,
350                         &hdcp->auth.msg.hdcp1.vp[16], 4);
351 out:
352         return status;
353 }
354
355 enum mod_hdcp_status mod_hdcp_read_binfo(struct mod_hdcp *hdcp)
356 {
357         enum mod_hdcp_status status;
358
359         if (is_dp_hdcp(hdcp))
360                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BINFO,
361                                 (uint8_t *)&hdcp->auth.msg.hdcp1.binfo_dp,
362                                 sizeof(hdcp->auth.msg.hdcp1.binfo_dp));
363         else
364                 status = MOD_HDCP_STATUS_INVALID_OPERATION;
365
366         return status;
367 }
368
369 enum mod_hdcp_status mod_hdcp_write_aksv(struct mod_hdcp *hdcp)
370 {
371         return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKSV,
372                         hdcp->auth.msg.hdcp1.aksv,
373                         sizeof(hdcp->auth.msg.hdcp1.aksv));
374 }
375
376 enum mod_hdcp_status mod_hdcp_write_ainfo(struct mod_hdcp *hdcp)
377 {
378         return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AINFO,
379                         &hdcp->auth.msg.hdcp1.ainfo,
380                         sizeof(hdcp->auth.msg.hdcp1.ainfo));
381 }
382
383 enum mod_hdcp_status mod_hdcp_write_an(struct mod_hdcp *hdcp)
384 {
385         return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AN,
386                         hdcp->auth.msg.hdcp1.an,
387                         sizeof(hdcp->auth.msg.hdcp1.an));
388 }
389
390 enum mod_hdcp_status mod_hdcp_read_hdcp2version(struct mod_hdcp *hdcp)
391 {
392         enum mod_hdcp_status status;
393
394         if (is_dp_hdcp(hdcp))
395                 status = MOD_HDCP_STATUS_INVALID_OPERATION;
396         else
397                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_HDCP2VERSION,
398                                 &hdcp->auth.msg.hdcp2.hdcp2version_hdmi,
399                                 sizeof(hdcp->auth.msg.hdcp2.hdcp2version_hdmi));
400
401         return status;
402 }
403
404 enum mod_hdcp_status mod_hdcp_read_rxcaps(struct mod_hdcp *hdcp)
405 {
406         enum mod_hdcp_status status;
407
408         if (!is_dp_hdcp(hdcp))
409                 status = MOD_HDCP_STATUS_INVALID_OPERATION;
410         else
411                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_RX_CAPS,
412                                 hdcp->auth.msg.hdcp2.rxcaps_dp,
413                                 sizeof(hdcp->auth.msg.hdcp2.rxcaps_dp));
414
415         return status;
416 }
417
418 enum mod_hdcp_status mod_hdcp_read_rxstatus(struct mod_hdcp *hdcp)
419 {
420         enum mod_hdcp_status status;
421
422         if (is_dp_hdcp(hdcp)) {
423                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RXSTATUS,
424                                 &hdcp->auth.msg.hdcp2.rxstatus_dp,
425                                 1);
426         } else {
427                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RXSTATUS,
428                                         (uint8_t *)&hdcp->auth.msg.hdcp2.rxstatus,
429                                         sizeof(hdcp->auth.msg.hdcp2.rxstatus));
430         }
431         return status;
432 }
433
434 enum mod_hdcp_status mod_hdcp_read_ake_cert(struct mod_hdcp *hdcp)
435 {
436         enum mod_hdcp_status status;
437
438         if (is_dp_hdcp(hdcp)) {
439                 hdcp->auth.msg.hdcp2.ake_cert[0] = HDCP_2_2_AKE_SEND_CERT;
440                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,
441                                 hdcp->auth.msg.hdcp2.ake_cert+1,
442                                 sizeof(hdcp->auth.msg.hdcp2.ake_cert)-1);
443
444         } else {
445                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,
446                                         hdcp->auth.msg.hdcp2.ake_cert,
447                                         sizeof(hdcp->auth.msg.hdcp2.ake_cert));
448         }
449         return status;
450 }
451
452 enum mod_hdcp_status mod_hdcp_read_h_prime(struct mod_hdcp *hdcp)
453 {
454         enum mod_hdcp_status status;
455
456         if (is_dp_hdcp(hdcp)) {
457                 hdcp->auth.msg.hdcp2.ake_h_prime[0] = HDCP_2_2_AKE_SEND_HPRIME;
458                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,
459                                 hdcp->auth.msg.hdcp2.ake_h_prime+1,
460                                 sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)-1);
461
462         } else {
463                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,
464                                 hdcp->auth.msg.hdcp2.ake_h_prime,
465                                 sizeof(hdcp->auth.msg.hdcp2.ake_h_prime));
466         }
467         return status;
468 }
469
470 enum mod_hdcp_status mod_hdcp_read_pairing_info(struct mod_hdcp *hdcp)
471 {
472         enum mod_hdcp_status status;
473
474         if (is_dp_hdcp(hdcp)) {
475                 hdcp->auth.msg.hdcp2.ake_pairing_info[0] = HDCP_2_2_AKE_SEND_PAIRING_INFO;
476                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,
477                                 hdcp->auth.msg.hdcp2.ake_pairing_info+1,
478                                 sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info)-1);
479
480         } else {
481                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,
482                                 hdcp->auth.msg.hdcp2.ake_pairing_info,
483                                 sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info));
484         }
485         return status;
486 }
487
488 enum mod_hdcp_status mod_hdcp_read_l_prime(struct mod_hdcp *hdcp)
489 {
490         enum mod_hdcp_status status;
491
492         if (is_dp_hdcp(hdcp)) {
493                 hdcp->auth.msg.hdcp2.lc_l_prime[0] = HDCP_2_2_LC_SEND_LPRIME;
494                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,
495                                 hdcp->auth.msg.hdcp2.lc_l_prime+1,
496                                 sizeof(hdcp->auth.msg.hdcp2.lc_l_prime)-1);
497
498         } else {
499                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,
500                                 hdcp->auth.msg.hdcp2.lc_l_prime,
501                                 sizeof(hdcp->auth.msg.hdcp2.lc_l_prime));
502         }
503         return status;
504 }
505
506 enum mod_hdcp_status mod_hdcp_read_rx_id_list(struct mod_hdcp *hdcp)
507 {
508         enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
509
510         if (is_dp_hdcp(hdcp)) {
511                 uint32_t device_count = 0;
512                 uint32_t rx_id_list_size = 0;
513                 uint32_t bytes_read = 0;
514
515                 hdcp->auth.msg.hdcp2.rx_id_list[0] = HDCP_2_2_REP_SEND_RECVID_LIST;
516                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,
517                                                 hdcp->auth.msg.hdcp2.rx_id_list+1,
518                                                 HDCP_MAX_AUX_TRANSACTION_SIZE);
519                 if (status == MOD_HDCP_STATUS_SUCCESS) {
520                         bytes_read = HDCP_MAX_AUX_TRANSACTION_SIZE;
521                         device_count = HDCP_2_2_DEV_COUNT_LO(hdcp->auth.msg.hdcp2.rx_id_list[2]) +
522                                         (HDCP_2_2_DEV_COUNT_HI(hdcp->auth.msg.hdcp2.rx_id_list[1]) << 4);
523                         rx_id_list_size = MIN((21 + 5 * device_count),
524                                         (sizeof(hdcp->auth.msg.hdcp2.rx_id_list) - 1));
525                         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2,
526                                         hdcp->auth.msg.hdcp2.rx_id_list + 1 + bytes_read,
527                                         (rx_id_list_size - 1) / HDCP_MAX_AUX_TRANSACTION_SIZE * HDCP_MAX_AUX_TRANSACTION_SIZE);
528                 }
529         } else {
530                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,
531                                 hdcp->auth.msg.hdcp2.rx_id_list,
532                                 hdcp->auth.msg.hdcp2.rx_id_list_size);
533         }
534         return status;
535 }
536
537 enum mod_hdcp_status mod_hdcp_read_stream_ready(struct mod_hdcp *hdcp)
538 {
539         enum mod_hdcp_status status;
540
541         if (is_dp_hdcp(hdcp)) {
542                 hdcp->auth.msg.hdcp2.repeater_auth_stream_ready[0] = HDCP_2_2_REP_STREAM_READY;
543                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,
544                                 hdcp->auth.msg.hdcp2.repeater_auth_stream_ready+1,
545                                 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready)-1);
546
547         } else {
548                 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,
549                                 hdcp->auth.msg.hdcp2.repeater_auth_stream_ready,
550                                 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready));
551         }
552         return status;
553 }
554
555 enum mod_hdcp_status mod_hdcp_write_ake_init(struct mod_hdcp *hdcp)
556 {
557         enum mod_hdcp_status status;
558
559         if (is_dp_hdcp(hdcp))
560                 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT,
561                                 hdcp->auth.msg.hdcp2.ake_init+1,
562                                 sizeof(hdcp->auth.msg.hdcp2.ake_init)-1);
563         else
564                 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT,
565                                         hdcp->auth.msg.hdcp2.ake_init,
566                                         sizeof(hdcp->auth.msg.hdcp2.ake_init));
567         return status;
568 }
569
570 enum mod_hdcp_status mod_hdcp_write_no_stored_km(struct mod_hdcp *hdcp)
571 {
572         enum mod_hdcp_status status;
573
574         if (is_dp_hdcp(hdcp))
575                 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM,
576                                 hdcp->auth.msg.hdcp2.ake_no_stored_km+1,
577                                 sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)-1);
578         else
579                 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM,
580                         hdcp->auth.msg.hdcp2.ake_no_stored_km,
581                         sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km));
582         return status;
583 }
584
585 enum mod_hdcp_status mod_hdcp_write_stored_km(struct mod_hdcp *hdcp)
586 {
587         enum mod_hdcp_status status;
588
589         if (is_dp_hdcp(hdcp))
590                 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM,
591                                 hdcp->auth.msg.hdcp2.ake_stored_km+1,
592                                 sizeof(hdcp->auth.msg.hdcp2.ake_stored_km)-1);
593         else
594                 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM,
595                                 hdcp->auth.msg.hdcp2.ake_stored_km,
596                                 sizeof(hdcp->auth.msg.hdcp2.ake_stored_km));
597         return status;
598 }
599
600 enum mod_hdcp_status mod_hdcp_write_lc_init(struct mod_hdcp *hdcp)
601 {
602         enum mod_hdcp_status status;
603
604         if (is_dp_hdcp(hdcp))
605                 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT,
606                                 hdcp->auth.msg.hdcp2.lc_init+1,
607                                 sizeof(hdcp->auth.msg.hdcp2.lc_init)-1);
608         else
609                 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT,
610                                 hdcp->auth.msg.hdcp2.lc_init,
611                                 sizeof(hdcp->auth.msg.hdcp2.lc_init));
612         return status;
613 }
614
615 enum mod_hdcp_status mod_hdcp_write_eks(struct mod_hdcp *hdcp)
616 {
617         enum mod_hdcp_status status;
618
619         if (is_dp_hdcp(hdcp))
620                 status = write(hdcp,
621                                 MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,
622                                 hdcp->auth.msg.hdcp2.ske_eks+1,
623                                 sizeof(hdcp->auth.msg.hdcp2.ske_eks)-1);
624         else
625                 status = write(hdcp,
626                         MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,
627                         hdcp->auth.msg.hdcp2.ske_eks,
628                         sizeof(hdcp->auth.msg.hdcp2.ske_eks));
629         return status;
630 }
631
632 enum mod_hdcp_status mod_hdcp_write_repeater_auth_ack(struct mod_hdcp *hdcp)
633 {
634         enum mod_hdcp_status status;
635
636         if (is_dp_hdcp(hdcp))
637                 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,
638                                 hdcp->auth.msg.hdcp2.repeater_auth_ack+1,
639                                 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack)-1);
640         else
641                 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,
642                                 hdcp->auth.msg.hdcp2.repeater_auth_ack,
643                                 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack));
644         return status;
645 }
646
647 enum mod_hdcp_status mod_hdcp_write_stream_manage(struct mod_hdcp *hdcp)
648 {
649         enum mod_hdcp_status status;
650
651         if (is_dp_hdcp(hdcp))
652                 status = write(hdcp,
653                                 MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,
654                                 hdcp->auth.msg.hdcp2.repeater_auth_stream_manage+1,
655                                 hdcp->auth.msg.hdcp2.stream_manage_size-1);
656         else
657                 status = write(hdcp,
658                                 MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,
659                                 hdcp->auth.msg.hdcp2.repeater_auth_stream_manage,
660                                 hdcp->auth.msg.hdcp2.stream_manage_size);
661         return status;
662 }
663
664 enum mod_hdcp_status mod_hdcp_write_content_type(struct mod_hdcp *hdcp)
665 {
666         enum mod_hdcp_status status;
667
668         if (is_dp_hdcp(hdcp))
669                 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE,
670                                 hdcp->auth.msg.hdcp2.content_stream_type_dp+1,
671                                 sizeof(hdcp->auth.msg.hdcp2.content_stream_type_dp)-1);
672         else
673                 status = MOD_HDCP_STATUS_INVALID_OPERATION;
674         return status;
675 }
676
677 enum mod_hdcp_status mod_hdcp_clear_cp_irq_status(struct mod_hdcp *hdcp)
678 {
679         uint8_t clear_cp_irq_bit = DP_CP_IRQ;
680         uint32_t size = 1;
681
682         if (is_dp_hdcp(hdcp)) {
683                 uint32_t cp_irq_addrs = (hdcp->connection.link.dp.rev >= 0x14)
684                                 ? DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0:DP_DEVICE_SERVICE_IRQ_VECTOR;
685                 return hdcp->config.ddc.funcs.write_dpcd(hdcp->config.ddc.handle, cp_irq_addrs,
686                                 &clear_cp_irq_bit, size) ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE;
687         }
688
689         return MOD_HDCP_STATUS_INVALID_OPERATION;
690 }
This page took 0.065842 seconds and 4 git commands to generate.