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