hdcp_msg.c (12485B)
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 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; /* 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 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 /* 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 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; //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 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