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 37 #define DC_LOGGER \ 38 link->ctx->logger 39 #define HDCP14_KSV_SIZE 5 40 #define HDCP14_MAX_KSV_FIFO_SIZE 127*HDCP14_KSV_SIZE 41 42 static const bool hdcp_cmd_is_read[] = { 43 [HDCP_MESSAGE_ID_READ_BKSV] = true, 44 [HDCP_MESSAGE_ID_READ_RI_R0] = true, 45 [HDCP_MESSAGE_ID_READ_PJ] = true, 46 [HDCP_MESSAGE_ID_WRITE_AKSV] = false, 47 [HDCP_MESSAGE_ID_WRITE_AINFO] = false, 48 [HDCP_MESSAGE_ID_WRITE_AN] = false, 49 [HDCP_MESSAGE_ID_READ_VH_X] = true, 50 [HDCP_MESSAGE_ID_READ_VH_0] = true, 51 [HDCP_MESSAGE_ID_READ_VH_1] = true, 52 [HDCP_MESSAGE_ID_READ_VH_2] = true, 53 [HDCP_MESSAGE_ID_READ_VH_3] = true, 54 [HDCP_MESSAGE_ID_READ_VH_4] = true, 55 [HDCP_MESSAGE_ID_READ_BCAPS] = true, 56 [HDCP_MESSAGE_ID_READ_BSTATUS] = true, 57 [HDCP_MESSAGE_ID_READ_KSV_FIFO] = true, 58 [HDCP_MESSAGE_ID_READ_BINFO] = true, 59 [HDCP_MESSAGE_ID_HDCP2VERSION] = true, 60 [HDCP_MESSAGE_ID_RX_CAPS] = true, 61 [HDCP_MESSAGE_ID_WRITE_AKE_INIT] = false, 62 [HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = true, 63 [HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = false, 64 [HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = false, 65 [HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = true, 66 [HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = true, 67 [HDCP_MESSAGE_ID_WRITE_LC_INIT] = false, 68 [HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = true, 69 [HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = false, 70 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = true, 71 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = false, 72 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = false, 73 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = true, 74 [HDCP_MESSAGE_ID_READ_RXSTATUS] = true, 75 [HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = false 76 }; 77 78 static const uint8_t hdcp_i2c_offsets[] = { 79 [HDCP_MESSAGE_ID_READ_BKSV] = 0x0, 80 [HDCP_MESSAGE_ID_READ_RI_R0] = 0x8, 81 [HDCP_MESSAGE_ID_READ_PJ] = 0xA, 82 [HDCP_MESSAGE_ID_WRITE_AKSV] = 0x10, 83 [HDCP_MESSAGE_ID_WRITE_AINFO] = 0x15, 84 [HDCP_MESSAGE_ID_WRITE_AN] = 0x18, 85 [HDCP_MESSAGE_ID_READ_VH_X] = 0x20, 86 [HDCP_MESSAGE_ID_READ_VH_0] = 0x20, 87 [HDCP_MESSAGE_ID_READ_VH_1] = 0x24, 88 [HDCP_MESSAGE_ID_READ_VH_2] = 0x28, 89 [HDCP_MESSAGE_ID_READ_VH_3] = 0x2C, 90 [HDCP_MESSAGE_ID_READ_VH_4] = 0x30, 91 [HDCP_MESSAGE_ID_READ_BCAPS] = 0x40, 92 [HDCP_MESSAGE_ID_READ_BSTATUS] = 0x41, 93 [HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x43, 94 [HDCP_MESSAGE_ID_READ_BINFO] = 0xFF, 95 [HDCP_MESSAGE_ID_HDCP2VERSION] = 0x50, 96 [HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x60, 97 [HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x80, 98 [HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x60, 99 [HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x60, 100 [HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x80, 101 [HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x80, 102 [HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x60, 103 [HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x80, 104 [HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x60, 105 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x80, 106 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x60, 107 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x60, 108 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x80, 109 [HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x70 110 }; 111 112 struct protection_properties { 113 bool supported; 114 bool (*process_transaction)( 115 struct dc_link *link, 116 struct hdcp_protection_message *message_info); 117 }; 118 119 static const struct protection_properties non_supported_protection = { 120 .supported = false 121 }; 122 123 static bool hdmi_14_process_transaction( 124 struct dc_link *link, 125 struct hdcp_protection_message *message_info) 126 { 127 uint8_t *buff = NULL; 128 bool result; 129 const uint8_t hdcp_i2c_addr_link_primary = 0x3a; /* 0x74 >> 1*/ 130 const uint8_t hdcp_i2c_addr_link_secondary = 0x3b; /* 0x76 >> 1*/ 131 struct i2c_command i2c_command; 132 uint8_t offset = hdcp_i2c_offsets[message_info->msg_id]; 133 struct i2c_payload i2c_payloads[] = { 134 { true, 0, 1, &offset }, 135 /* actual hdcp payload, will be filled later, zeroed for now*/ 136 { 0 } 137 }; 138 139 switch (message_info->link) { 140 case HDCP_LINK_SECONDARY: 141 i2c_payloads[0].address = hdcp_i2c_addr_link_secondary; 142 i2c_payloads[1].address = hdcp_i2c_addr_link_secondary; 143 break; 144 case HDCP_LINK_PRIMARY: 145 default: 146 i2c_payloads[0].address = hdcp_i2c_addr_link_primary; 147 i2c_payloads[1].address = hdcp_i2c_addr_link_primary; 148 break; 149 } 150 151 if (hdcp_cmd_is_read[message_info->msg_id]) { 152 i2c_payloads[1].write = false; 153 i2c_command.number_of_payloads = ARRAY_SIZE(i2c_payloads); 154 i2c_payloads[1].length = message_info->length; 155 i2c_payloads[1].data = message_info->data; 156 } else { 157 i2c_command.number_of_payloads = 1; 158 buff = kzalloc(message_info->length + 1, GFP_KERNEL); 159 160 if (!buff) 161 return false; 162 163 buff[0] = offset; 164 memmove(&buff[1], message_info->data, message_info->length); 165 i2c_payloads[0].length = message_info->length + 1; 166 i2c_payloads[0].data = buff; 167 } 168 169 i2c_command.payloads = i2c_payloads; 170 i2c_command.engine = I2C_COMMAND_ENGINE_HW;//only HW 171 i2c_command.speed = link->ddc->ctx->dc->caps.i2c_speed_in_khz; 172 173 result = dm_helpers_submit_i2c( 174 link->ctx, 175 link, 176 &i2c_command); 177 kfree(buff); 178 179 return result; 180 } 181 182 static const struct protection_properties hdmi_14_protection = { 183 .supported = true, 184 .process_transaction = hdmi_14_process_transaction 185 }; 186 187 static const uint32_t hdcp_dpcd_addrs[] = { 188 [HDCP_MESSAGE_ID_READ_BKSV] = 0x68000, 189 [HDCP_MESSAGE_ID_READ_RI_R0] = 0x68005, 190 [HDCP_MESSAGE_ID_READ_PJ] = 0xFFFFFFFF, 191 [HDCP_MESSAGE_ID_WRITE_AKSV] = 0x68007, 192 [HDCP_MESSAGE_ID_WRITE_AINFO] = 0x6803B, 193 [HDCP_MESSAGE_ID_WRITE_AN] = 0x6800c, 194 [HDCP_MESSAGE_ID_READ_VH_X] = 0x68014, 195 [HDCP_MESSAGE_ID_READ_VH_0] = 0x68014, 196 [HDCP_MESSAGE_ID_READ_VH_1] = 0x68018, 197 [HDCP_MESSAGE_ID_READ_VH_2] = 0x6801c, 198 [HDCP_MESSAGE_ID_READ_VH_3] = 0x68020, 199 [HDCP_MESSAGE_ID_READ_VH_4] = 0x68024, 200 [HDCP_MESSAGE_ID_READ_BCAPS] = 0x68028, 201 [HDCP_MESSAGE_ID_READ_BSTATUS] = 0x68029, 202 [HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x6802c, 203 [HDCP_MESSAGE_ID_READ_BINFO] = 0x6802a, 204 [HDCP_MESSAGE_ID_RX_CAPS] = 0x6921d, 205 [HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x69000, 206 [HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x6900b, 207 [HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x69220, 208 [HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x692a0, 209 [HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x692c0, 210 [HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x692e0, 211 [HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x692f0, 212 [HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x692f8, 213 [HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x69318, 214 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x69330, 215 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x693e0, 216 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x693f0, 217 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x69473, 218 [HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x69493, 219 [HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x69494 220 }; 221 222 static bool dpcd_access_helper( 223 struct dc_link *link, 224 uint32_t length, 225 uint8_t *data, 226 uint32_t dpcd_addr, 227 bool is_read) 228 { 229 enum dc_status status; 230 uint32_t cur_length = 0; 231 uint32_t offset = 0; 232 uint32_t ksv_read_size = 0x6803b - 0x6802c; 233 234 /* Read KSV, need repeatedly handle */ 235 if (dpcd_addr == 0x6802c) { 236 if (length % HDCP14_KSV_SIZE) { 237 DC_LOG_ERROR("%s: KsvFifo Size(%d) is not a multiple of HDCP14_KSV_SIZE(%d)\n", 238 __func__, 239 length, 240 HDCP14_KSV_SIZE); 241 } 242 if (length > HDCP14_MAX_KSV_FIFO_SIZE) { 243 DC_LOG_ERROR("%s: KsvFifo Size(%d) is greater than HDCP14_MAX_KSV_FIFO_SIZE(%d)\n", 244 __func__, 245 length, 246 HDCP14_MAX_KSV_FIFO_SIZE); 247 } 248 249 DC_LOG_ERROR("%s: Reading %d Ksv(s) from KsvFifo\n", 250 __func__, 251 length / HDCP14_KSV_SIZE); 252 253 while (length > 0) { 254 if (length > ksv_read_size) { 255 status = core_link_read_dpcd( 256 link, 257 dpcd_addr + offset, 258 data + offset, 259 ksv_read_size); 260 261 data += ksv_read_size; 262 length -= ksv_read_size; 263 } else { 264 status = core_link_read_dpcd( 265 link, 266 dpcd_addr + offset, 267 data + offset, 268 length); 269 270 data += length; 271 length = 0; 272 } 273 274 if (status != DC_OK) 275 return false; 276 } 277 } else { 278 while (length > 0) { 279 if (length > DEFAULT_AUX_MAX_DATA_SIZE) 280 cur_length = DEFAULT_AUX_MAX_DATA_SIZE; 281 else 282 cur_length = length; 283 284 if (is_read) { 285 status = core_link_read_dpcd( 286 link, 287 dpcd_addr + offset, 288 data + offset, 289 cur_length); 290 } else { 291 status = core_link_write_dpcd( 292 link, 293 dpcd_addr + offset, 294 data + offset, 295 cur_length); 296 } 297 298 if (status != DC_OK) 299 return false; 300 301 length -= cur_length; 302 offset += cur_length; 303 } 304 } 305 return true; 306 } 307 308 static bool dp_11_process_transaction( 309 struct dc_link *link, 310 struct hdcp_protection_message *message_info) 311 { 312 return dpcd_access_helper( 313 link, 314 message_info->length, 315 message_info->data, 316 hdcp_dpcd_addrs[message_info->msg_id], 317 hdcp_cmd_is_read[message_info->msg_id]); 318 } 319 320 static const struct protection_properties dp_11_protection = { 321 .supported = true, 322 .process_transaction = dp_11_process_transaction 323 }; 324 325