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 "dm_services.h" 27 #include "dm_helpers.h" 28 #include "include/hdcp_msg_types.h" 29 #include "include/signal_types.h" 30 #include "core_types.h" 31 #include "link_service.h" 32 #include "link_hwss.h" 33 #include "link/protocols/link_dpcd.h" 34 35 #define DC_LOGGER \ 36 link->ctx->logger 37 #define HDCP14_KSV_SIZE 5 38 #define HDCP14_MAX_KSV_FIFO_SIZE 127*HDCP14_KSV_SIZE 39 40 static const bool hdcp_cmd_is_read[HDCP_MESSAGE_ID_MAX] = { 41 [HDCP_MESSAGE_ID_READ_BKSV] = true, 42 [HDCP_MESSAGE_ID_READ_RI_R0] = true, 43 [HDCP_MESSAGE_ID_READ_PJ] = true, 44 [HDCP_MESSAGE_ID_WRITE_AKSV] = false, 45 [HDCP_MESSAGE_ID_WRITE_AINFO] = false, 46 [HDCP_MESSAGE_ID_WRITE_AN] = false, 47 [HDCP_MESSAGE_ID_READ_VH_X] = true, 48 [HDCP_MESSAGE_ID_READ_VH_0] = true, 49 [HDCP_MESSAGE_ID_READ_VH_1] = true, 50 [HDCP_MESSAGE_ID_READ_VH_2] = true, 51 [HDCP_MESSAGE_ID_READ_VH_3] = true, 52 [HDCP_MESSAGE_ID_READ_VH_4] = true, 53 [HDCP_MESSAGE_ID_READ_BCAPS] = true, 54 [HDCP_MESSAGE_ID_READ_BSTATUS] = true, 55 [HDCP_MESSAGE_ID_READ_KSV_FIFO] = true, 56 [HDCP_MESSAGE_ID_READ_BINFO] = true, 57 [HDCP_MESSAGE_ID_HDCP2VERSION] = true, 58 [HDCP_MESSAGE_ID_RX_CAPS] = true, 59 [HDCP_MESSAGE_ID_WRITE_AKE_INIT] = false, 60 [HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = true, 61 [HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = false, 62 [HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = false, 63 [HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = true, 64 [HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = true, 65 [HDCP_MESSAGE_ID_WRITE_LC_INIT] = false, 66 [HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = true, 67 [HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = false, 68 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = true, 69 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = false, 70 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = false, 71 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = true, 72 [HDCP_MESSAGE_ID_READ_RXSTATUS] = true, 73 [HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = false, 74 }; 75 76 static const uint8_t hdcp_i2c_offsets[HDCP_MESSAGE_ID_MAX] = { 77 [HDCP_MESSAGE_ID_READ_BKSV] = 0x0, 78 [HDCP_MESSAGE_ID_READ_RI_R0] = 0x8, 79 [HDCP_MESSAGE_ID_READ_PJ] = 0xA, 80 [HDCP_MESSAGE_ID_WRITE_AKSV] = 0x10, 81 [HDCP_MESSAGE_ID_WRITE_AINFO] = 0x15, 82 [HDCP_MESSAGE_ID_WRITE_AN] = 0x18, 83 [HDCP_MESSAGE_ID_READ_VH_X] = 0x20, 84 [HDCP_MESSAGE_ID_READ_VH_0] = 0x20, 85 [HDCP_MESSAGE_ID_READ_VH_1] = 0x24, 86 [HDCP_MESSAGE_ID_READ_VH_2] = 0x28, 87 [HDCP_MESSAGE_ID_READ_VH_3] = 0x2C, 88 [HDCP_MESSAGE_ID_READ_VH_4] = 0x30, 89 [HDCP_MESSAGE_ID_READ_BCAPS] = 0x40, 90 [HDCP_MESSAGE_ID_READ_BSTATUS] = 0x41, 91 [HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x43, 92 [HDCP_MESSAGE_ID_READ_BINFO] = 0xFF, 93 [HDCP_MESSAGE_ID_HDCP2VERSION] = 0x50, 94 [HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x60, 95 [HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x80, 96 [HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x60, 97 [HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x60, 98 [HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x80, 99 [HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x80, 100 [HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x60, 101 [HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x80, 102 [HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x60, 103 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x80, 104 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x60, 105 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x60, 106 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x80, 107 [HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x70, 108 [HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x0, 109 }; 110 111 struct protection_properties { 112 bool supported; 113 bool (*process_transaction)( 114 struct dc_link *link, 115 struct hdcp_protection_message *message_info); 116 }; 117 118 static const struct protection_properties non_supported_protection = { 119 .supported = false 120 }; 121 122 static bool hdmi_14_process_transaction( 123 struct dc_link *link, 124 struct hdcp_protection_message *message_info) 125 { 126 uint8_t *buff = NULL; 127 bool result; 128 const uint8_t hdcp_i2c_addr_link_primary = 0x3a; /* 0x74 >> 1*/ 129 const uint8_t hdcp_i2c_addr_link_secondary = 0x3b; /* 0x76 >> 1*/ 130 struct i2c_command i2c_command; 131 uint8_t offset; 132 struct i2c_payload i2c_payloads[] = { 133 { true, 0, 1, 0 }, 134 /* actual hdcp payload, will be filled later, zeroed for now*/ 135 { 0 } 136 }; 137 138 if (message_info->msg_id == HDCP_MESSAGE_ID_INVALID) { 139 DC_LOG_ERROR("%s: Invalid message_info msg_id - %d\n", __func__, message_info->msg_id); 140 return false; 141 } 142 143 offset = hdcp_i2c_offsets[message_info->msg_id]; 144 i2c_payloads[0].data = &offset; 145 146 switch (message_info->link) { 147 case HDCP_LINK_SECONDARY: 148 i2c_payloads[0].address = hdcp_i2c_addr_link_secondary; 149 i2c_payloads[1].address = hdcp_i2c_addr_link_secondary; 150 break; 151 case HDCP_LINK_PRIMARY: 152 default: 153 i2c_payloads[0].address = hdcp_i2c_addr_link_primary; 154 i2c_payloads[1].address = hdcp_i2c_addr_link_primary; 155 break; 156 } 157 158 if (hdcp_cmd_is_read[message_info->msg_id]) { 159 i2c_payloads[1].write = false; 160 i2c_command.number_of_payloads = ARRAY_SIZE(i2c_payloads); 161 i2c_payloads[1].length = message_info->length; 162 i2c_payloads[1].data = message_info->data; 163 } else { 164 i2c_command.number_of_payloads = 1; 165 buff = kzalloc(message_info->length + 1, GFP_KERNEL); 166 167 if (!buff) 168 return false; 169 170 buff[0] = offset; 171 memmove(&buff[1], message_info->data, message_info->length); 172 i2c_payloads[0].length = message_info->length + 1; 173 i2c_payloads[0].data = buff; 174 } 175 176 i2c_command.payloads = i2c_payloads; 177 i2c_command.engine = I2C_COMMAND_ENGINE_HW;//only HW 178 i2c_command.speed = link->ddc->ctx->dc->caps.i2c_speed_in_khz; 179 180 if (link->force_to_use_aux) 181 result = dm_helpers_submit_i2c_over_aux( 182 link->ddc, 183 hdcp_i2c_addr_link_primary, 184 offset, 185 message_info->data, 186 message_info->length, 187 hdcp_cmd_is_read[message_info->msg_id]); 188 else 189 result = dm_helpers_submit_i2c( 190 link->ctx, 191 link, 192 &i2c_command); 193 kfree(buff); 194 195 return result; 196 } 197 198 static const struct protection_properties hdmi_14_protection = { 199 .supported = true, 200 .process_transaction = hdmi_14_process_transaction 201 }; 202 203 static const uint32_t hdcp_dpcd_addrs[HDCP_MESSAGE_ID_MAX] = { 204 [HDCP_MESSAGE_ID_READ_BKSV] = 0x68000, 205 [HDCP_MESSAGE_ID_READ_RI_R0] = 0x68005, 206 [HDCP_MESSAGE_ID_READ_PJ] = 0xFFFFFFFF, 207 [HDCP_MESSAGE_ID_WRITE_AKSV] = 0x68007, 208 [HDCP_MESSAGE_ID_WRITE_AINFO] = 0x6803B, 209 [HDCP_MESSAGE_ID_WRITE_AN] = 0x6800c, 210 [HDCP_MESSAGE_ID_READ_VH_X] = 0x68014, 211 [HDCP_MESSAGE_ID_READ_VH_0] = 0x68014, 212 [HDCP_MESSAGE_ID_READ_VH_1] = 0x68018, 213 [HDCP_MESSAGE_ID_READ_VH_2] = 0x6801c, 214 [HDCP_MESSAGE_ID_READ_VH_3] = 0x68020, 215 [HDCP_MESSAGE_ID_READ_VH_4] = 0x68024, 216 [HDCP_MESSAGE_ID_READ_BCAPS] = 0x68028, 217 [HDCP_MESSAGE_ID_READ_BSTATUS] = 0x68029, 218 [HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x6802c, 219 [HDCP_MESSAGE_ID_READ_BINFO] = 0x6802a, 220 [HDCP_MESSAGE_ID_RX_CAPS] = 0x6921d, 221 [HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x69000, 222 [HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x6900b, 223 [HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x69220, 224 [HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x692a0, 225 [HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x692c0, 226 [HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x692e0, 227 [HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x692f0, 228 [HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x692f8, 229 [HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x69318, 230 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x69330, 231 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x693e0, 232 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x693f0, 233 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x69473, 234 [HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x69493, 235 [HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x69494 236 }; 237 238 static bool dpcd_access_helper( 239 struct dc_link *link, 240 uint32_t length, 241 uint8_t *data, 242 uint32_t dpcd_addr, 243 bool is_read) 244 { 245 enum dc_status status; 246 uint32_t cur_length = 0; 247 uint32_t offset = 0; 248 uint32_t ksv_read_size = 0x6803b - 0x6802c; 249 250 /* Read KSV, need repeatedly handle */ 251 if (dpcd_addr == 0x6802c) { 252 if (length % HDCP14_KSV_SIZE) { 253 DC_LOG_ERROR("%s: KsvFifo Size(%d) is not a multiple of HDCP14_KSV_SIZE(%d)\n", 254 __func__, 255 length, 256 HDCP14_KSV_SIZE); 257 } 258 if (length > HDCP14_MAX_KSV_FIFO_SIZE) { 259 DC_LOG_ERROR("%s: KsvFifo Size(%d) is greater than HDCP14_MAX_KSV_FIFO_SIZE(%d)\n", 260 __func__, 261 length, 262 HDCP14_MAX_KSV_FIFO_SIZE); 263 } 264 265 DC_LOG_ERROR("%s: Reading %d Ksv(s) from KsvFifo\n", 266 __func__, 267 length / HDCP14_KSV_SIZE); 268 269 while (length > 0) { 270 if (length > ksv_read_size) { 271 status = core_link_read_dpcd( 272 link, 273 dpcd_addr + offset, 274 data + offset, 275 ksv_read_size); 276 277 data += ksv_read_size; 278 length -= ksv_read_size; 279 } else { 280 status = core_link_read_dpcd( 281 link, 282 dpcd_addr + offset, 283 data + offset, 284 length); 285 286 data += length; 287 length = 0; 288 } 289 290 if (status != DC_OK) 291 return false; 292 } 293 } else { 294 while (length > 0) { 295 if (length > DEFAULT_AUX_MAX_DATA_SIZE) 296 cur_length = DEFAULT_AUX_MAX_DATA_SIZE; 297 else 298 cur_length = length; 299 300 if (is_read) { 301 status = core_link_read_dpcd( 302 link, 303 dpcd_addr + offset, 304 data + offset, 305 cur_length); 306 } else { 307 status = core_link_write_dpcd( 308 link, 309 dpcd_addr + offset, 310 data + offset, 311 cur_length); 312 } 313 314 if (status != DC_OK) 315 return false; 316 317 length -= cur_length; 318 offset += cur_length; 319 } 320 } 321 return true; 322 } 323 324 static bool dp_11_process_transaction( 325 struct dc_link *link, 326 struct hdcp_protection_message *message_info) 327 { 328 if (message_info->msg_id == HDCP_MESSAGE_ID_INVALID) { 329 DC_LOG_ERROR("%s: Invalid message_info msg_id - %d\n", __func__, message_info->msg_id); 330 return false; 331 } 332 333 return dpcd_access_helper( 334 link, 335 message_info->length, 336 message_info->data, 337 hdcp_dpcd_addrs[message_info->msg_id], 338 hdcp_cmd_is_read[message_info->msg_id]); 339 } 340 341 static const struct protection_properties dp_11_protection = { 342 .supported = true, 343 .process_transaction = dp_11_process_transaction 344 }; 345 346 static const struct protection_properties *get_protection_properties_by_signal( 347 struct dc_link *link, 348 enum signal_type st, 349 enum hdcp_version version) 350 { 351 switch (version) { 352 case HDCP_VERSION_14: 353 switch (st) { 354 case SIGNAL_TYPE_DVI_SINGLE_LINK: 355 case SIGNAL_TYPE_DVI_DUAL_LINK: 356 case SIGNAL_TYPE_HDMI_TYPE_A: 357 return &hdmi_14_protection; 358 case SIGNAL_TYPE_DISPLAY_PORT: 359 if (link && 360 (link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER || 361 link->dpcd_caps.dongle_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER)) { 362 return &non_supported_protection; 363 } 364 return &dp_11_protection; 365 case SIGNAL_TYPE_DISPLAY_PORT_MST: 366 case SIGNAL_TYPE_EDP: 367 return &dp_11_protection; 368 default: 369 return &non_supported_protection; 370 } 371 break; 372 case HDCP_VERSION_22: 373 switch (st) { 374 case SIGNAL_TYPE_DVI_SINGLE_LINK: 375 case SIGNAL_TYPE_DVI_DUAL_LINK: 376 case SIGNAL_TYPE_HDMI_TYPE_A: 377 case SIGNAL_TYPE_HDMI_FRL: 378 return &hdmi_14_protection; //todo version2.2 379 case SIGNAL_TYPE_DISPLAY_PORT: 380 case SIGNAL_TYPE_DISPLAY_PORT_MST: 381 case SIGNAL_TYPE_EDP: 382 return &dp_11_protection; //todo version2.2 383 default: 384 return &non_supported_protection; 385 } 386 break; 387 default: 388 return &non_supported_protection; 389 } 390 } 391 392 enum hdcp_message_status dc_process_hdcp_msg( 393 enum signal_type signal, 394 struct dc_link *link, 395 struct hdcp_protection_message *message_info) 396 { 397 enum hdcp_message_status status = HDCP_MESSAGE_FAILURE; 398 uint32_t i = 0; 399 400 const struct protection_properties *protection_props; 401 402 if (!message_info) 403 return HDCP_MESSAGE_UNSUPPORTED; 404 405 if (message_info->msg_id < HDCP_MESSAGE_ID_READ_BKSV || 406 message_info->msg_id >= HDCP_MESSAGE_ID_MAX) 407 return HDCP_MESSAGE_UNSUPPORTED; 408 409 protection_props = 410 get_protection_properties_by_signal( 411 link, 412 signal, 413 message_info->version); 414 415 if (!protection_props->supported) 416 return HDCP_MESSAGE_UNSUPPORTED; 417 418 if (protection_props->process_transaction( 419 link, 420 message_info)) { 421 status = HDCP_MESSAGE_SUCCESS; 422 } else { 423 for (i = 0; i < message_info->max_retries; i++) { 424 if (protection_props->process_transaction( 425 link, 426 message_info)) { 427 status = HDCP_MESSAGE_SUCCESS; 428 break; 429 } 430 } 431 } 432 433 return status; 434 } 435 436