Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2019 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
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; /* 0x74 >> 1*/
0132     const uint8_t hdcp_i2c_addr_link_secondary = 0x3b; /* 0x76 >> 1*/
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         /* actual hdcp payload, will be filled later, zeroed for now*/
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;//only 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     /* Read KSV, need repeatedly handle */
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; //todo version2.2
0359         case SIGNAL_TYPE_DISPLAY_PORT:
0360         case SIGNAL_TYPE_DISPLAY_PORT_MST:
0361         case SIGNAL_TYPE_EDP:
0362             return &dp_11_protection;  //todo version2.2
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