0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <linux/slab.h>
0027
0028 #include "dm_services.h"
0029 #include "dm_helpers.h"
0030 #include "include/hdcp_types.h"
0031 #include "include/i2caux_interface.h"
0032 #include "include/signal_types.h"
0033 #include "core_types.h"
0034 #include "dc_link_ddc.h"
0035 #include "link_hwss.h"
0036 #include "inc/link_dpcd.h"
0037
0038 #define DC_LOGGER \
0039 link->ctx->logger
0040 #define HDCP14_KSV_SIZE 5
0041 #define HDCP14_MAX_KSV_FIFO_SIZE 127*HDCP14_KSV_SIZE
0042
0043 static const bool hdcp_cmd_is_read[HDCP_MESSAGE_ID_MAX] = {
0044 [HDCP_MESSAGE_ID_READ_BKSV] = true,
0045 [HDCP_MESSAGE_ID_READ_RI_R0] = true,
0046 [HDCP_MESSAGE_ID_READ_PJ] = true,
0047 [HDCP_MESSAGE_ID_WRITE_AKSV] = false,
0048 [HDCP_MESSAGE_ID_WRITE_AINFO] = false,
0049 [HDCP_MESSAGE_ID_WRITE_AN] = false,
0050 [HDCP_MESSAGE_ID_READ_VH_X] = true,
0051 [HDCP_MESSAGE_ID_READ_VH_0] = true,
0052 [HDCP_MESSAGE_ID_READ_VH_1] = true,
0053 [HDCP_MESSAGE_ID_READ_VH_2] = true,
0054 [HDCP_MESSAGE_ID_READ_VH_3] = true,
0055 [HDCP_MESSAGE_ID_READ_VH_4] = true,
0056 [HDCP_MESSAGE_ID_READ_BCAPS] = true,
0057 [HDCP_MESSAGE_ID_READ_BSTATUS] = true,
0058 [HDCP_MESSAGE_ID_READ_KSV_FIFO] = true,
0059 [HDCP_MESSAGE_ID_READ_BINFO] = true,
0060 [HDCP_MESSAGE_ID_HDCP2VERSION] = true,
0061 [HDCP_MESSAGE_ID_RX_CAPS] = true,
0062 [HDCP_MESSAGE_ID_WRITE_AKE_INIT] = false,
0063 [HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = true,
0064 [HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = false,
0065 [HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = false,
0066 [HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = true,
0067 [HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = true,
0068 [HDCP_MESSAGE_ID_WRITE_LC_INIT] = false,
0069 [HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = true,
0070 [HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = false,
0071 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = true,
0072 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = false,
0073 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = false,
0074 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = true,
0075 [HDCP_MESSAGE_ID_READ_RXSTATUS] = true,
0076 [HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = false
0077 };
0078
0079 static const uint8_t hdcp_i2c_offsets[HDCP_MESSAGE_ID_MAX] = {
0080 [HDCP_MESSAGE_ID_READ_BKSV] = 0x0,
0081 [HDCP_MESSAGE_ID_READ_RI_R0] = 0x8,
0082 [HDCP_MESSAGE_ID_READ_PJ] = 0xA,
0083 [HDCP_MESSAGE_ID_WRITE_AKSV] = 0x10,
0084 [HDCP_MESSAGE_ID_WRITE_AINFO] = 0x15,
0085 [HDCP_MESSAGE_ID_WRITE_AN] = 0x18,
0086 [HDCP_MESSAGE_ID_READ_VH_X] = 0x20,
0087 [HDCP_MESSAGE_ID_READ_VH_0] = 0x20,
0088 [HDCP_MESSAGE_ID_READ_VH_1] = 0x24,
0089 [HDCP_MESSAGE_ID_READ_VH_2] = 0x28,
0090 [HDCP_MESSAGE_ID_READ_VH_3] = 0x2C,
0091 [HDCP_MESSAGE_ID_READ_VH_4] = 0x30,
0092 [HDCP_MESSAGE_ID_READ_BCAPS] = 0x40,
0093 [HDCP_MESSAGE_ID_READ_BSTATUS] = 0x41,
0094 [HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x43,
0095 [HDCP_MESSAGE_ID_READ_BINFO] = 0xFF,
0096 [HDCP_MESSAGE_ID_HDCP2VERSION] = 0x50,
0097 [HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x60,
0098 [HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x80,
0099 [HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x60,
0100 [HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x60,
0101 [HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x80,
0102 [HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x80,
0103 [HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x60,
0104 [HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x80,
0105 [HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x60,
0106 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x80,
0107 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x60,
0108 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x60,
0109 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x80,
0110 [HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x70,
0111 [HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x0,
0112 };
0113
0114 struct protection_properties {
0115 bool supported;
0116 bool (*process_transaction)(
0117 struct dc_link *link,
0118 struct hdcp_protection_message *message_info);
0119 };
0120
0121 static const struct protection_properties non_supported_protection = {
0122 .supported = false
0123 };
0124
0125 static bool hdmi_14_process_transaction(
0126 struct dc_link *link,
0127 struct hdcp_protection_message *message_info)
0128 {
0129 uint8_t *buff = NULL;
0130 bool result;
0131 const uint8_t hdcp_i2c_addr_link_primary = 0x3a;
0132 const uint8_t hdcp_i2c_addr_link_secondary = 0x3b;
0133 struct i2c_command i2c_command;
0134 uint8_t offset = hdcp_i2c_offsets[message_info->msg_id];
0135 struct i2c_payload i2c_payloads[] = {
0136 { true, 0, 1, &offset },
0137
0138 { 0 }
0139 };
0140
0141 switch (message_info->link) {
0142 case HDCP_LINK_SECONDARY:
0143 i2c_payloads[0].address = hdcp_i2c_addr_link_secondary;
0144 i2c_payloads[1].address = hdcp_i2c_addr_link_secondary;
0145 break;
0146 case HDCP_LINK_PRIMARY:
0147 default:
0148 i2c_payloads[0].address = hdcp_i2c_addr_link_primary;
0149 i2c_payloads[1].address = hdcp_i2c_addr_link_primary;
0150 break;
0151 }
0152
0153 if (hdcp_cmd_is_read[message_info->msg_id]) {
0154 i2c_payloads[1].write = false;
0155 i2c_command.number_of_payloads = ARRAY_SIZE(i2c_payloads);
0156 i2c_payloads[1].length = message_info->length;
0157 i2c_payloads[1].data = message_info->data;
0158 } else {
0159 i2c_command.number_of_payloads = 1;
0160 buff = kzalloc(message_info->length + 1, GFP_KERNEL);
0161
0162 if (!buff)
0163 return false;
0164
0165 buff[0] = offset;
0166 memmove(&buff[1], message_info->data, message_info->length);
0167 i2c_payloads[0].length = message_info->length + 1;
0168 i2c_payloads[0].data = buff;
0169 }
0170
0171 i2c_command.payloads = i2c_payloads;
0172 i2c_command.engine = I2C_COMMAND_ENGINE_HW;
0173 i2c_command.speed = link->ddc->ctx->dc->caps.i2c_speed_in_khz;
0174
0175 result = dm_helpers_submit_i2c(
0176 link->ctx,
0177 link,
0178 &i2c_command);
0179 kfree(buff);
0180
0181 return result;
0182 }
0183
0184 static const struct protection_properties hdmi_14_protection = {
0185 .supported = true,
0186 .process_transaction = hdmi_14_process_transaction
0187 };
0188
0189 static const uint32_t hdcp_dpcd_addrs[HDCP_MESSAGE_ID_MAX] = {
0190 [HDCP_MESSAGE_ID_READ_BKSV] = 0x68000,
0191 [HDCP_MESSAGE_ID_READ_RI_R0] = 0x68005,
0192 [HDCP_MESSAGE_ID_READ_PJ] = 0xFFFFFFFF,
0193 [HDCP_MESSAGE_ID_WRITE_AKSV] = 0x68007,
0194 [HDCP_MESSAGE_ID_WRITE_AINFO] = 0x6803B,
0195 [HDCP_MESSAGE_ID_WRITE_AN] = 0x6800c,
0196 [HDCP_MESSAGE_ID_READ_VH_X] = 0x68014,
0197 [HDCP_MESSAGE_ID_READ_VH_0] = 0x68014,
0198 [HDCP_MESSAGE_ID_READ_VH_1] = 0x68018,
0199 [HDCP_MESSAGE_ID_READ_VH_2] = 0x6801c,
0200 [HDCP_MESSAGE_ID_READ_VH_3] = 0x68020,
0201 [HDCP_MESSAGE_ID_READ_VH_4] = 0x68024,
0202 [HDCP_MESSAGE_ID_READ_BCAPS] = 0x68028,
0203 [HDCP_MESSAGE_ID_READ_BSTATUS] = 0x68029,
0204 [HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x6802c,
0205 [HDCP_MESSAGE_ID_READ_BINFO] = 0x6802a,
0206 [HDCP_MESSAGE_ID_RX_CAPS] = 0x6921d,
0207 [HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x69000,
0208 [HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x6900b,
0209 [HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x69220,
0210 [HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x692a0,
0211 [HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x692c0,
0212 [HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x692e0,
0213 [HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x692f0,
0214 [HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x692f8,
0215 [HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x69318,
0216 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x69330,
0217 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x693e0,
0218 [HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x693f0,
0219 [HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x69473,
0220 [HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x69493,
0221 [HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x69494
0222 };
0223
0224 static bool dpcd_access_helper(
0225 struct dc_link *link,
0226 uint32_t length,
0227 uint8_t *data,
0228 uint32_t dpcd_addr,
0229 bool is_read)
0230 {
0231 enum dc_status status;
0232 uint32_t cur_length = 0;
0233 uint32_t offset = 0;
0234 uint32_t ksv_read_size = 0x6803b - 0x6802c;
0235
0236
0237 if (dpcd_addr == 0x6802c) {
0238 if (length % HDCP14_KSV_SIZE) {
0239 DC_LOG_ERROR("%s: KsvFifo Size(%d) is not a multiple of HDCP14_KSV_SIZE(%d)\n",
0240 __func__,
0241 length,
0242 HDCP14_KSV_SIZE);
0243 }
0244 if (length > HDCP14_MAX_KSV_FIFO_SIZE) {
0245 DC_LOG_ERROR("%s: KsvFifo Size(%d) is greater than HDCP14_MAX_KSV_FIFO_SIZE(%d)\n",
0246 __func__,
0247 length,
0248 HDCP14_MAX_KSV_FIFO_SIZE);
0249 }
0250
0251 DC_LOG_ERROR("%s: Reading %d Ksv(s) from KsvFifo\n",
0252 __func__,
0253 length / HDCP14_KSV_SIZE);
0254
0255 while (length > 0) {
0256 if (length > ksv_read_size) {
0257 status = core_link_read_dpcd(
0258 link,
0259 dpcd_addr + offset,
0260 data + offset,
0261 ksv_read_size);
0262
0263 data += ksv_read_size;
0264 length -= ksv_read_size;
0265 } else {
0266 status = core_link_read_dpcd(
0267 link,
0268 dpcd_addr + offset,
0269 data + offset,
0270 length);
0271
0272 data += length;
0273 length = 0;
0274 }
0275
0276 if (status != DC_OK)
0277 return false;
0278 }
0279 } else {
0280 while (length > 0) {
0281 if (length > DEFAULT_AUX_MAX_DATA_SIZE)
0282 cur_length = DEFAULT_AUX_MAX_DATA_SIZE;
0283 else
0284 cur_length = length;
0285
0286 if (is_read) {
0287 status = core_link_read_dpcd(
0288 link,
0289 dpcd_addr + offset,
0290 data + offset,
0291 cur_length);
0292 } else {
0293 status = core_link_write_dpcd(
0294 link,
0295 dpcd_addr + offset,
0296 data + offset,
0297 cur_length);
0298 }
0299
0300 if (status != DC_OK)
0301 return false;
0302
0303 length -= cur_length;
0304 offset += cur_length;
0305 }
0306 }
0307 return true;
0308 }
0309
0310 static bool dp_11_process_transaction(
0311 struct dc_link *link,
0312 struct hdcp_protection_message *message_info)
0313 {
0314 return dpcd_access_helper(
0315 link,
0316 message_info->length,
0317 message_info->data,
0318 hdcp_dpcd_addrs[message_info->msg_id],
0319 hdcp_cmd_is_read[message_info->msg_id]);
0320 }
0321
0322 static const struct protection_properties dp_11_protection = {
0323 .supported = true,
0324 .process_transaction = dp_11_process_transaction
0325 };
0326
0327 static const struct protection_properties *get_protection_properties_by_signal(
0328 struct dc_link *link,
0329 enum signal_type st,
0330 enum hdcp_version version)
0331 {
0332 switch (version) {
0333 case HDCP_VERSION_14:
0334 switch (st) {
0335 case SIGNAL_TYPE_DVI_SINGLE_LINK:
0336 case SIGNAL_TYPE_DVI_DUAL_LINK:
0337 case SIGNAL_TYPE_HDMI_TYPE_A:
0338 return &hdmi_14_protection;
0339 case SIGNAL_TYPE_DISPLAY_PORT:
0340 if (link &&
0341 (link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER ||
0342 link->dpcd_caps.dongle_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER)) {
0343 return &non_supported_protection;
0344 }
0345 return &dp_11_protection;
0346 case SIGNAL_TYPE_DISPLAY_PORT_MST:
0347 case SIGNAL_TYPE_EDP:
0348 return &dp_11_protection;
0349 default:
0350 return &non_supported_protection;
0351 }
0352 break;
0353 case HDCP_VERSION_22:
0354 switch (st) {
0355 case SIGNAL_TYPE_DVI_SINGLE_LINK:
0356 case SIGNAL_TYPE_DVI_DUAL_LINK:
0357 case SIGNAL_TYPE_HDMI_TYPE_A:
0358 return &hdmi_14_protection;
0359 case SIGNAL_TYPE_DISPLAY_PORT:
0360 case SIGNAL_TYPE_DISPLAY_PORT_MST:
0361 case SIGNAL_TYPE_EDP:
0362 return &dp_11_protection;
0363 default:
0364 return &non_supported_protection;
0365 }
0366 break;
0367 default:
0368 return &non_supported_protection;
0369 }
0370 }
0371
0372 enum hdcp_message_status dc_process_hdcp_msg(
0373 enum signal_type signal,
0374 struct dc_link *link,
0375 struct hdcp_protection_message *message_info)
0376 {
0377 enum hdcp_message_status status = HDCP_MESSAGE_FAILURE;
0378 uint32_t i = 0;
0379
0380 const struct protection_properties *protection_props;
0381
0382 if (!message_info)
0383 return HDCP_MESSAGE_UNSUPPORTED;
0384
0385 if (message_info->msg_id < HDCP_MESSAGE_ID_READ_BKSV ||
0386 message_info->msg_id >= HDCP_MESSAGE_ID_MAX)
0387 return HDCP_MESSAGE_UNSUPPORTED;
0388
0389 protection_props =
0390 get_protection_properties_by_signal(
0391 link,
0392 signal,
0393 message_info->version);
0394
0395 if (!protection_props->supported)
0396 return HDCP_MESSAGE_UNSUPPORTED;
0397
0398 if (protection_props->process_transaction(
0399 link,
0400 message_info)) {
0401 status = HDCP_MESSAGE_SUCCESS;
0402 } else {
0403 for (i = 0; i < message_info->max_retries; i++) {
0404 if (protection_props->process_transaction(
0405 link,
0406 message_info)) {
0407 status = HDCP_MESSAGE_SUCCESS;
0408 break;
0409 }
0410 }
0411 }
0412
0413 return status;
0414 }
0415