LCOV - code coverage report
Current view: top level - drivers/gpu/drm - drm_dp_mst_topology.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 2474 0.0 %
Date: 2022-03-28 13:20:08 Functions: 0 130 0.0 %
Branches: 0 1135 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright © 2014 Red Hat
       3                 :            :  *
       4                 :            :  * Permission to use, copy, modify, distribute, and sell this software and its
       5                 :            :  * documentation for any purpose is hereby granted without fee, provided that
       6                 :            :  * the above copyright notice appear in all copies and that both that copyright
       7                 :            :  * notice and this permission notice appear in supporting documentation, and
       8                 :            :  * that the name of the copyright holders not be used in advertising or
       9                 :            :  * publicity pertaining to distribution of the software without specific,
      10                 :            :  * written prior permission.  The copyright holders make no representations
      11                 :            :  * about the suitability of this software for any purpose.  It is provided "as
      12                 :            :  * is" without express or implied warranty.
      13                 :            :  *
      14                 :            :  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
      15                 :            :  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
      16                 :            :  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
      17                 :            :  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
      18                 :            :  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
      19                 :            :  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
      20                 :            :  * OF THIS SOFTWARE.
      21                 :            :  */
      22                 :            : 
      23                 :            : #include <linux/delay.h>
      24                 :            : #include <linux/errno.h>
      25                 :            : #include <linux/i2c.h>
      26                 :            : #include <linux/init.h>
      27                 :            : #include <linux/kernel.h>
      28                 :            : #include <linux/sched.h>
      29                 :            : #include <linux/seq_file.h>
      30                 :            : 
      31                 :            : #if IS_ENABLED(CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS)
      32                 :            : #include <linux/stacktrace.h>
      33                 :            : #include <linux/sort.h>
      34                 :            : #include <linux/timekeeping.h>
      35                 :            : #include <linux/math64.h>
      36                 :            : #endif
      37                 :            : 
      38                 :            : #include <drm/drm_atomic.h>
      39                 :            : #include <drm/drm_atomic_helper.h>
      40                 :            : #include <drm/drm_dp_mst_helper.h>
      41                 :            : #include <drm/drm_drv.h>
      42                 :            : #include <drm/drm_print.h>
      43                 :            : #include <drm/drm_probe_helper.h>
      44                 :            : 
      45                 :            : #include "drm_crtc_helper_internal.h"
      46                 :            : #include "drm_dp_mst_topology_internal.h"
      47                 :            : 
      48                 :            : /**
      49                 :            :  * DOC: dp mst helper
      50                 :            :  *
      51                 :            :  * These functions contain parts of the DisplayPort 1.2a MultiStream Transport
      52                 :            :  * protocol. The helpers contain a topology manager and bandwidth manager.
      53                 :            :  * The helpers encapsulate the sending and received of sideband msgs.
      54                 :            :  */
      55                 :            : struct drm_dp_pending_up_req {
      56                 :            :         struct drm_dp_sideband_msg_hdr hdr;
      57                 :            :         struct drm_dp_sideband_msg_req_body msg;
      58                 :            :         struct list_head next;
      59                 :            : };
      60                 :            : 
      61                 :            : static bool dump_dp_payload_table(struct drm_dp_mst_topology_mgr *mgr,
      62                 :            :                                   char *buf);
      63                 :            : 
      64                 :            : static void drm_dp_mst_topology_put_port(struct drm_dp_mst_port *port);
      65                 :            : 
      66                 :            : static int drm_dp_dpcd_write_payload(struct drm_dp_mst_topology_mgr *mgr,
      67                 :            :                                      int id,
      68                 :            :                                      struct drm_dp_payload *payload);
      69                 :            : 
      70                 :            : static int drm_dp_send_dpcd_read(struct drm_dp_mst_topology_mgr *mgr,
      71                 :            :                                  struct drm_dp_mst_port *port,
      72                 :            :                                  int offset, int size, u8 *bytes);
      73                 :            : static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr,
      74                 :            :                                   struct drm_dp_mst_port *port,
      75                 :            :                                   int offset, int size, u8 *bytes);
      76                 :            : 
      77                 :            : static int drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
      78                 :            :                                     struct drm_dp_mst_branch *mstb);
      79                 :            : 
      80                 :            : static void
      81                 :            : drm_dp_send_clear_payload_id_table(struct drm_dp_mst_topology_mgr *mgr,
      82                 :            :                                    struct drm_dp_mst_branch *mstb);
      83                 :            : 
      84                 :            : static int drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr,
      85                 :            :                                            struct drm_dp_mst_branch *mstb,
      86                 :            :                                            struct drm_dp_mst_port *port);
      87                 :            : static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr,
      88                 :            :                                  u8 *guid);
      89                 :            : 
      90                 :            : static int drm_dp_mst_register_i2c_bus(struct drm_dp_aux *aux);
      91                 :            : static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_aux *aux);
      92                 :            : static void drm_dp_mst_kick_tx(struct drm_dp_mst_topology_mgr *mgr);
      93                 :            : 
      94                 :            : #define DBG_PREFIX "[dp_mst]"
      95                 :            : 
      96                 :            : #define DP_STR(x) [DP_ ## x] = #x
      97                 :            : 
      98                 :          0 : static const char *drm_dp_mst_req_type_str(u8 req_type)
      99                 :            : {
     100                 :          0 :         static const char * const req_type_str[] = {
     101                 :            :                 DP_STR(GET_MSG_TRANSACTION_VERSION),
     102                 :            :                 DP_STR(LINK_ADDRESS),
     103                 :            :                 DP_STR(CONNECTION_STATUS_NOTIFY),
     104                 :            :                 DP_STR(ENUM_PATH_RESOURCES),
     105                 :            :                 DP_STR(ALLOCATE_PAYLOAD),
     106                 :            :                 DP_STR(QUERY_PAYLOAD),
     107                 :            :                 DP_STR(RESOURCE_STATUS_NOTIFY),
     108                 :            :                 DP_STR(CLEAR_PAYLOAD_ID_TABLE),
     109                 :            :                 DP_STR(REMOTE_DPCD_READ),
     110                 :            :                 DP_STR(REMOTE_DPCD_WRITE),
     111                 :            :                 DP_STR(REMOTE_I2C_READ),
     112                 :            :                 DP_STR(REMOTE_I2C_WRITE),
     113                 :            :                 DP_STR(POWER_UP_PHY),
     114                 :            :                 DP_STR(POWER_DOWN_PHY),
     115                 :            :                 DP_STR(SINK_EVENT_NOTIFY),
     116                 :            :                 DP_STR(QUERY_STREAM_ENC_STATUS),
     117                 :            :         };
     118                 :            : 
     119                 :          0 :         if (req_type >= ARRAY_SIZE(req_type_str) ||
     120   [ #  #  #  #  :          0 :             !req_type_str[req_type])
             #  #  #  # ]
     121                 :          0 :                 return "unknown";
     122                 :            : 
     123                 :            :         return req_type_str[req_type];
     124                 :            : }
     125                 :            : 
     126                 :            : #undef DP_STR
     127                 :            : #define DP_STR(x) [DP_NAK_ ## x] = #x
     128                 :            : 
     129                 :          0 : static const char *drm_dp_mst_nak_reason_str(u8 nak_reason)
     130                 :            : {
     131                 :          0 :         static const char * const nak_reason_str[] = {
     132                 :            :                 DP_STR(WRITE_FAILURE),
     133                 :            :                 DP_STR(INVALID_READ),
     134                 :            :                 DP_STR(CRC_FAILURE),
     135                 :            :                 DP_STR(BAD_PARAM),
     136                 :            :                 DP_STR(DEFER),
     137                 :            :                 DP_STR(LINK_FAILURE),
     138                 :            :                 DP_STR(NO_RESOURCES),
     139                 :            :                 DP_STR(DPCD_FAIL),
     140                 :            :                 DP_STR(I2C_NAK),
     141                 :            :                 DP_STR(ALLOCATE_FAIL),
     142                 :            :         };
     143                 :            : 
     144                 :          0 :         if (nak_reason >= ARRAY_SIZE(nak_reason_str) ||
     145         [ #  # ]:          0 :             !nak_reason_str[nak_reason])
     146                 :          0 :                 return "unknown";
     147                 :            : 
     148                 :            :         return nak_reason_str[nak_reason];
     149                 :            : }
     150                 :            : 
     151                 :            : #undef DP_STR
     152                 :            : #define DP_STR(x) [DRM_DP_SIDEBAND_TX_ ## x] = #x
     153                 :            : 
     154                 :          0 : static const char *drm_dp_mst_sideband_tx_state_str(int state)
     155                 :            : {
     156                 :          0 :         static const char * const sideband_reason_str[] = {
     157                 :            :                 DP_STR(QUEUED),
     158                 :            :                 DP_STR(START_SEND),
     159                 :            :                 DP_STR(SENT),
     160                 :            :                 DP_STR(RX),
     161                 :            :                 DP_STR(TIMEOUT),
     162                 :            :         };
     163                 :            : 
     164                 :          0 :         if (state >= ARRAY_SIZE(sideband_reason_str) ||
     165         [ #  # ]:          0 :             !sideband_reason_str[state])
     166                 :          0 :                 return "unknown";
     167                 :            : 
     168                 :            :         return sideband_reason_str[state];
     169                 :            : }
     170                 :            : 
     171                 :            : static int
     172                 :          0 : drm_dp_mst_rad_to_str(const u8 rad[8], u8 lct, char *out, size_t len)
     173                 :            : {
     174                 :          0 :         int i;
     175                 :          0 :         u8 unpacked_rad[16];
     176                 :            : 
     177         [ #  # ]:          0 :         for (i = 0; i < lct; i++) {
     178         [ #  # ]:          0 :                 if (i % 2)
     179                 :          0 :                         unpacked_rad[i] = rad[i / 2] >> 4;
     180                 :            :                 else
     181                 :          0 :                         unpacked_rad[i] = rad[i / 2] & BIT_MASK(4);
     182                 :            :         }
     183                 :            : 
     184                 :            :         /* TODO: Eventually add something to printk so we can format the rad
     185                 :            :          * like this: 1.2.3
     186                 :            :          */
     187                 :          0 :         return snprintf(out, len, "%*phC", lct, unpacked_rad);
     188                 :            : }
     189                 :            : 
     190                 :            : /* sideband msg handling */
     191                 :          0 : static u8 drm_dp_msg_header_crc4(const uint8_t *data, size_t num_nibbles)
     192                 :            : {
     193                 :          0 :         u8 bitmask = 0x80;
     194                 :          0 :         u8 bitshift = 7;
     195                 :          0 :         u8 array_index = 0;
     196                 :          0 :         int number_of_bits = num_nibbles * 4;
     197                 :          0 :         u8 remainder = 0;
     198                 :            : 
     199         [ #  # ]:          0 :         while (number_of_bits != 0) {
     200                 :          0 :                 number_of_bits--;
     201                 :          0 :                 remainder <<= 1;
     202                 :          0 :                 remainder |= (data[array_index] & bitmask) >> bitshift;
     203                 :          0 :                 bitmask >>= 1;
     204                 :          0 :                 bitshift--;
     205         [ #  # ]:          0 :                 if (bitmask == 0) {
     206                 :          0 :                         bitmask = 0x80;
     207                 :          0 :                         bitshift = 7;
     208                 :          0 :                         array_index++;
     209                 :            :                 }
     210         [ #  # ]:          0 :                 if ((remainder & 0x10) == 0x10)
     211                 :          0 :                         remainder ^= 0x13;
     212                 :            :         }
     213                 :            : 
     214                 :            :         number_of_bits = 4;
     215         [ #  # ]:          0 :         while (number_of_bits != 0) {
     216                 :          0 :                 number_of_bits--;
     217                 :          0 :                 remainder <<= 1;
     218         [ #  # ]:          0 :                 if ((remainder & 0x10) != 0)
     219                 :          0 :                         remainder ^= 0x13;
     220                 :            :         }
     221                 :            : 
     222                 :          0 :         return remainder;
     223                 :            : }
     224                 :            : 
     225                 :          0 : static u8 drm_dp_msg_data_crc4(const uint8_t *data, u8 number_of_bytes)
     226                 :            : {
     227                 :          0 :         u8 bitmask = 0x80;
     228                 :          0 :         u8 bitshift = 7;
     229                 :          0 :         u8 array_index = 0;
     230                 :          0 :         int number_of_bits = number_of_bytes * 8;
     231                 :          0 :         u16 remainder = 0;
     232                 :            : 
     233         [ #  # ]:          0 :         while (number_of_bits != 0) {
     234                 :          0 :                 number_of_bits--;
     235                 :          0 :                 remainder <<= 1;
     236                 :          0 :                 remainder |= (data[array_index] & bitmask) >> bitshift;
     237                 :          0 :                 bitmask >>= 1;
     238                 :          0 :                 bitshift--;
     239         [ #  # ]:          0 :                 if (bitmask == 0) {
     240                 :          0 :                         bitmask = 0x80;
     241                 :          0 :                         bitshift = 7;
     242                 :          0 :                         array_index++;
     243                 :            :                 }
     244         [ #  # ]:          0 :                 if ((remainder & 0x100) == 0x100)
     245                 :          0 :                         remainder ^= 0xd5;
     246                 :            :         }
     247                 :            : 
     248                 :            :         number_of_bits = 8;
     249         [ #  # ]:          0 :         while (number_of_bits != 0) {
     250                 :          0 :                 number_of_bits--;
     251                 :          0 :                 remainder <<= 1;
     252         [ #  # ]:          0 :                 if ((remainder & 0x100) != 0)
     253                 :          0 :                         remainder ^= 0xd5;
     254                 :            :         }
     255                 :            : 
     256                 :          0 :         return remainder & 0xff;
     257                 :            : }
     258                 :          0 : static inline u8 drm_dp_calc_sb_hdr_size(struct drm_dp_sideband_msg_hdr *hdr)
     259                 :            : {
     260                 :          0 :         u8 size = 3;
     261                 :          0 :         size += (hdr->lct / 2);
     262                 :          0 :         return size;
     263                 :            : }
     264                 :            : 
     265                 :          0 : static void drm_dp_encode_sideband_msg_hdr(struct drm_dp_sideband_msg_hdr *hdr,
     266                 :            :                                            u8 *buf, int *len)
     267                 :            : {
     268                 :          0 :         int idx = 0;
     269                 :          0 :         int i;
     270                 :          0 :         u8 crc4;
     271                 :          0 :         buf[idx++] = ((hdr->lct & 0xf) << 4) | (hdr->lcr & 0xf);
     272         [ #  # ]:          0 :         for (i = 0; i < (hdr->lct / 2); i++)
     273                 :          0 :                 buf[idx++] = hdr->rad[i];
     274                 :          0 :         buf[idx++] = (hdr->broadcast << 7) | (hdr->path_msg << 6) |
     275                 :          0 :                 (hdr->msg_len & 0x3f);
     276                 :          0 :         buf[idx++] = (hdr->somt << 7) | (hdr->eomt << 6) | (hdr->seqno << 4);
     277                 :            : 
     278                 :          0 :         crc4 = drm_dp_msg_header_crc4(buf, (idx * 2) - 1);
     279                 :          0 :         buf[idx - 1] |= (crc4 & 0xf);
     280                 :            : 
     281                 :          0 :         *len = idx;
     282                 :          0 : }
     283                 :            : 
     284                 :          0 : static bool drm_dp_decode_sideband_msg_hdr(struct drm_dp_sideband_msg_hdr *hdr,
     285                 :            :                                            u8 *buf, int buflen, u8 *hdrlen)
     286                 :            : {
     287                 :          0 :         u8 crc4;
     288                 :          0 :         u8 len;
     289                 :          0 :         int i;
     290                 :          0 :         u8 idx;
     291         [ #  # ]:          0 :         if (buf[0] == 0)
     292                 :            :                 return false;
     293                 :          0 :         len = 3;
     294                 :          0 :         len += ((buf[0] & 0xf0) >> 4) / 2;
     295         [ #  # ]:          0 :         if (len > buflen)
     296                 :            :                 return false;
     297                 :          0 :         crc4 = drm_dp_msg_header_crc4(buf, (len * 2) - 1);
     298                 :            : 
     299         [ #  # ]:          0 :         if ((crc4 & 0xf) != (buf[len - 1] & 0xf)) {
     300                 :          0 :                 DRM_DEBUG_KMS("crc4 mismatch 0x%x 0x%x\n", crc4, buf[len - 1]);
     301                 :          0 :                 return false;
     302                 :            :         }
     303                 :            : 
     304                 :          0 :         hdr->lct = (buf[0] & 0xf0) >> 4;
     305                 :          0 :         hdr->lcr = (buf[0] & 0xf);
     306                 :          0 :         idx = 1;
     307         [ #  # ]:          0 :         for (i = 0; i < (hdr->lct / 2); i++)
     308                 :          0 :                 hdr->rad[i] = buf[idx++];
     309                 :          0 :         hdr->broadcast = (buf[idx] >> 7) & 0x1;
     310                 :          0 :         hdr->path_msg = (buf[idx] >> 6) & 0x1;
     311                 :          0 :         hdr->msg_len = buf[idx] & 0x3f;
     312                 :          0 :         idx++;
     313                 :          0 :         hdr->somt = (buf[idx] >> 7) & 0x1;
     314                 :          0 :         hdr->eomt = (buf[idx] >> 6) & 0x1;
     315                 :          0 :         hdr->seqno = (buf[idx] >> 4) & 0x1;
     316                 :          0 :         idx++;
     317                 :          0 :         *hdrlen = idx;
     318                 :          0 :         return true;
     319                 :            : }
     320                 :            : 
     321                 :            : void
     322                 :          0 : drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,
     323                 :            :                            struct drm_dp_sideband_msg_tx *raw)
     324                 :            : {
     325                 :          0 :         int idx = 0;
     326                 :          0 :         int i;
     327                 :          0 :         u8 *buf = raw->msg;
     328                 :          0 :         buf[idx++] = req->req_type & 0x7f;
     329                 :            : 
     330   [ #  #  #  #  :          0 :         switch (req->req_type) {
             #  #  #  # ]
     331                 :          0 :         case DP_ENUM_PATH_RESOURCES:
     332                 :            :         case DP_POWER_DOWN_PHY:
     333                 :            :         case DP_POWER_UP_PHY:
     334                 :          0 :                 buf[idx] = (req->u.port_num.port_number & 0xf) << 4;
     335                 :          0 :                 idx++;
     336                 :          0 :                 break;
     337                 :          0 :         case DP_ALLOCATE_PAYLOAD:
     338                 :          0 :                 buf[idx] = (req->u.allocate_payload.port_number & 0xf) << 4 |
     339                 :          0 :                         (req->u.allocate_payload.number_sdp_streams & 0xf);
     340                 :          0 :                 idx++;
     341                 :          0 :                 buf[idx] = (req->u.allocate_payload.vcpi & 0x7f);
     342                 :          0 :                 idx++;
     343                 :          0 :                 buf[idx] = (req->u.allocate_payload.pbn >> 8);
     344                 :          0 :                 idx++;
     345                 :          0 :                 buf[idx] = (req->u.allocate_payload.pbn & 0xff);
     346                 :          0 :                 idx++;
     347         [ #  # ]:          0 :                 for (i = 0; i < req->u.allocate_payload.number_sdp_streams / 2; i++) {
     348                 :          0 :                         buf[idx] = ((req->u.allocate_payload.sdp_stream_sink[i * 2] & 0xf) << 4) |
     349                 :          0 :                                 (req->u.allocate_payload.sdp_stream_sink[i * 2 + 1] & 0xf);
     350                 :          0 :                         idx++;
     351                 :            :                 }
     352         [ #  # ]:          0 :                 if (req->u.allocate_payload.number_sdp_streams & 1) {
     353                 :          0 :                         i = req->u.allocate_payload.number_sdp_streams - 1;
     354                 :          0 :                         buf[idx] = (req->u.allocate_payload.sdp_stream_sink[i] & 0xf) << 4;
     355                 :          0 :                         idx++;
     356                 :            :                 }
     357                 :            :                 break;
     358                 :          0 :         case DP_QUERY_PAYLOAD:
     359                 :          0 :                 buf[idx] = (req->u.query_payload.port_number & 0xf) << 4;
     360                 :          0 :                 idx++;
     361                 :          0 :                 buf[idx] = (req->u.query_payload.vcpi & 0x7f);
     362                 :          0 :                 idx++;
     363                 :          0 :                 break;
     364                 :          0 :         case DP_REMOTE_DPCD_READ:
     365                 :          0 :                 buf[idx] = (req->u.dpcd_read.port_number & 0xf) << 4;
     366                 :          0 :                 buf[idx] |= ((req->u.dpcd_read.dpcd_address & 0xf0000) >> 16) & 0xf;
     367                 :          0 :                 idx++;
     368                 :          0 :                 buf[idx] = (req->u.dpcd_read.dpcd_address & 0xff00) >> 8;
     369                 :          0 :                 idx++;
     370                 :          0 :                 buf[idx] = (req->u.dpcd_read.dpcd_address & 0xff);
     371                 :          0 :                 idx++;
     372                 :          0 :                 buf[idx] = (req->u.dpcd_read.num_bytes);
     373                 :          0 :                 idx++;
     374                 :          0 :                 break;
     375                 :            : 
     376                 :          0 :         case DP_REMOTE_DPCD_WRITE:
     377                 :          0 :                 buf[idx] = (req->u.dpcd_write.port_number & 0xf) << 4;
     378                 :          0 :                 buf[idx] |= ((req->u.dpcd_write.dpcd_address & 0xf0000) >> 16) & 0xf;
     379                 :          0 :                 idx++;
     380                 :          0 :                 buf[idx] = (req->u.dpcd_write.dpcd_address & 0xff00) >> 8;
     381                 :          0 :                 idx++;
     382                 :          0 :                 buf[idx] = (req->u.dpcd_write.dpcd_address & 0xff);
     383                 :          0 :                 idx++;
     384                 :          0 :                 buf[idx] = (req->u.dpcd_write.num_bytes);
     385                 :          0 :                 idx++;
     386                 :          0 :                 memcpy(&buf[idx], req->u.dpcd_write.bytes, req->u.dpcd_write.num_bytes);
     387                 :          0 :                 idx += req->u.dpcd_write.num_bytes;
     388                 :          0 :                 break;
     389                 :          0 :         case DP_REMOTE_I2C_READ:
     390                 :          0 :                 buf[idx] = (req->u.i2c_read.port_number & 0xf) << 4;
     391                 :          0 :                 buf[idx] |= (req->u.i2c_read.num_transactions & 0x3);
     392                 :          0 :                 idx++;
     393         [ #  # ]:          0 :                 for (i = 0; i < (req->u.i2c_read.num_transactions & 0x3); i++) {
     394                 :          0 :                         buf[idx] = req->u.i2c_read.transactions[i].i2c_dev_id & 0x7f;
     395                 :          0 :                         idx++;
     396                 :          0 :                         buf[idx] = req->u.i2c_read.transactions[i].num_bytes;
     397                 :          0 :                         idx++;
     398                 :          0 :                         memcpy(&buf[idx], req->u.i2c_read.transactions[i].bytes, req->u.i2c_read.transactions[i].num_bytes);
     399                 :          0 :                         idx += req->u.i2c_read.transactions[i].num_bytes;
     400                 :            : 
     401                 :          0 :                         buf[idx] = (req->u.i2c_read.transactions[i].no_stop_bit & 0x1) << 4;
     402                 :          0 :                         buf[idx] |= (req->u.i2c_read.transactions[i].i2c_transaction_delay & 0xf);
     403                 :          0 :                         idx++;
     404                 :            :                 }
     405                 :          0 :                 buf[idx] = (req->u.i2c_read.read_i2c_device_id) & 0x7f;
     406                 :          0 :                 idx++;
     407                 :          0 :                 buf[idx] = (req->u.i2c_read.num_bytes_read);
     408                 :          0 :                 idx++;
     409                 :          0 :                 break;
     410                 :            : 
     411                 :          0 :         case DP_REMOTE_I2C_WRITE:
     412                 :          0 :                 buf[idx] = (req->u.i2c_write.port_number & 0xf) << 4;
     413                 :          0 :                 idx++;
     414                 :          0 :                 buf[idx] = (req->u.i2c_write.write_i2c_device_id) & 0x7f;
     415                 :          0 :                 idx++;
     416                 :          0 :                 buf[idx] = (req->u.i2c_write.num_bytes);
     417                 :          0 :                 idx++;
     418                 :          0 :                 memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);
     419                 :          0 :                 idx += req->u.i2c_write.num_bytes;
     420                 :          0 :                 break;
     421                 :            :         }
     422                 :          0 :         raw->cur_len = idx;
     423                 :          0 : }
     424                 :            : EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_dp_encode_sideband_req);
     425                 :            : 
     426                 :            : /* Decode a sideband request we've encoded, mainly used for debugging */
     427                 :            : int
     428                 :          0 : drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw,
     429                 :            :                            struct drm_dp_sideband_msg_req_body *req)
     430                 :            : {
     431                 :          0 :         const u8 *buf = raw->msg;
     432                 :          0 :         int i, idx = 0;
     433                 :            : 
     434                 :          0 :         req->req_type = buf[idx++] & 0x7f;
     435   [ #  #  #  #  :          0 :         switch (req->req_type) {
             #  #  #  # ]
     436                 :          0 :         case DP_ENUM_PATH_RESOURCES:
     437                 :            :         case DP_POWER_DOWN_PHY:
     438                 :            :         case DP_POWER_UP_PHY:
     439                 :          0 :                 req->u.port_num.port_number = (buf[idx] >> 4) & 0xf;
     440                 :          0 :                 break;
     441                 :          0 :         case DP_ALLOCATE_PAYLOAD:
     442                 :            :                 {
     443                 :          0 :                         struct drm_dp_allocate_payload *a =
     444                 :            :                                 &req->u.allocate_payload;
     445                 :            : 
     446                 :          0 :                         a->number_sdp_streams = buf[idx] & 0xf;
     447                 :          0 :                         a->port_number = (buf[idx] >> 4) & 0xf;
     448                 :            : 
     449         [ #  # ]:          0 :                         WARN_ON(buf[++idx] & 0x80);
     450                 :          0 :                         a->vcpi = buf[idx] & 0x7f;
     451                 :            : 
     452                 :          0 :                         a->pbn = buf[++idx] << 8;
     453                 :          0 :                         a->pbn |= buf[++idx];
     454                 :            : 
     455                 :          0 :                         idx++;
     456         [ #  # ]:          0 :                         for (i = 0; i < a->number_sdp_streams; i++) {
     457                 :          0 :                                 a->sdp_stream_sink[i] =
     458         [ #  # ]:          0 :                                         (buf[idx + (i / 2)] >> ((i % 2) ? 0 : 4)) & 0xf;
     459                 :            :                         }
     460                 :            :                 }
     461                 :            :                 break;
     462                 :          0 :         case DP_QUERY_PAYLOAD:
     463                 :          0 :                 req->u.query_payload.port_number = (buf[idx] >> 4) & 0xf;
     464         [ #  # ]:          0 :                 WARN_ON(buf[++idx] & 0x80);
     465                 :          0 :                 req->u.query_payload.vcpi = buf[idx] & 0x7f;
     466                 :          0 :                 break;
     467                 :          0 :         case DP_REMOTE_DPCD_READ:
     468                 :            :                 {
     469                 :          0 :                         struct drm_dp_remote_dpcd_read *r = &req->u.dpcd_read;
     470                 :            : 
     471                 :          0 :                         r->port_number = (buf[idx] >> 4) & 0xf;
     472                 :            : 
     473                 :          0 :                         r->dpcd_address = (buf[idx] << 16) & 0xf0000;
     474                 :          0 :                         r->dpcd_address |= (buf[++idx] << 8) & 0xff00;
     475                 :          0 :                         r->dpcd_address |= buf[++idx] & 0xff;
     476                 :            : 
     477                 :          0 :                         r->num_bytes = buf[++idx];
     478                 :            :                 }
     479                 :          0 :                 break;
     480                 :          0 :         case DP_REMOTE_DPCD_WRITE:
     481                 :            :                 {
     482                 :          0 :                         struct drm_dp_remote_dpcd_write *w =
     483                 :            :                                 &req->u.dpcd_write;
     484                 :            : 
     485                 :          0 :                         w->port_number = (buf[idx] >> 4) & 0xf;
     486                 :            : 
     487                 :          0 :                         w->dpcd_address = (buf[idx] << 16) & 0xf0000;
     488                 :          0 :                         w->dpcd_address |= (buf[++idx] << 8) & 0xff00;
     489                 :          0 :                         w->dpcd_address |= buf[++idx] & 0xff;
     490                 :            : 
     491                 :          0 :                         w->num_bytes = buf[++idx];
     492                 :            : 
     493                 :          0 :                         w->bytes = kmemdup(&buf[++idx], w->num_bytes,
     494                 :            :                                            GFP_KERNEL);
     495         [ #  # ]:          0 :                         if (!w->bytes)
     496                 :          0 :                                 return -ENOMEM;
     497                 :            :                 }
     498                 :            :                 break;
     499                 :          0 :         case DP_REMOTE_I2C_READ:
     500                 :            :                 {
     501                 :          0 :                         struct drm_dp_remote_i2c_read *r = &req->u.i2c_read;
     502                 :          0 :                         struct drm_dp_remote_i2c_read_tx *tx;
     503                 :          0 :                         bool failed = false;
     504                 :            : 
     505                 :          0 :                         r->num_transactions = buf[idx] & 0x3;
     506                 :          0 :                         r->port_number = (buf[idx] >> 4) & 0xf;
     507         [ #  # ]:          0 :                         for (i = 0; i < r->num_transactions; i++) {
     508                 :          0 :                                 tx = &r->transactions[i];
     509                 :            : 
     510                 :          0 :                                 tx->i2c_dev_id = buf[++idx] & 0x7f;
     511                 :          0 :                                 tx->num_bytes = buf[++idx];
     512                 :          0 :                                 tx->bytes = kmemdup(&buf[++idx],
     513                 :            :                                                     tx->num_bytes,
     514                 :            :                                                     GFP_KERNEL);
     515         [ #  # ]:          0 :                                 if (!tx->bytes) {
     516                 :            :                                         failed = true;
     517                 :            :                                         break;
     518                 :            :                                 }
     519                 :          0 :                                 idx += tx->num_bytes;
     520                 :          0 :                                 tx->no_stop_bit = (buf[idx] >> 5) & 0x1;
     521                 :          0 :                                 tx->i2c_transaction_delay = buf[idx] & 0xf;
     522                 :            :                         }
     523                 :            : 
     524         [ #  # ]:          0 :                         if (failed) {
     525         [ #  # ]:          0 :                                 for (i = 0; i < r->num_transactions; i++) {
     526                 :          0 :                                         tx = &r->transactions[i];
     527                 :          0 :                                         kfree(tx->bytes);
     528                 :            :                                 }
     529                 :            :                                 return -ENOMEM;
     530                 :            :                         }
     531                 :            : 
     532                 :          0 :                         r->read_i2c_device_id = buf[++idx] & 0x7f;
     533                 :          0 :                         r->num_bytes_read = buf[++idx];
     534                 :            :                 }
     535                 :          0 :                 break;
     536                 :          0 :         case DP_REMOTE_I2C_WRITE:
     537                 :            :                 {
     538                 :          0 :                         struct drm_dp_remote_i2c_write *w = &req->u.i2c_write;
     539                 :            : 
     540                 :          0 :                         w->port_number = (buf[idx] >> 4) & 0xf;
     541                 :          0 :                         w->write_i2c_device_id = buf[++idx] & 0x7f;
     542                 :          0 :                         w->num_bytes = buf[++idx];
     543                 :          0 :                         w->bytes = kmemdup(&buf[++idx], w->num_bytes,
     544                 :            :                                            GFP_KERNEL);
     545         [ #  # ]:          0 :                         if (!w->bytes)
     546                 :          0 :                                 return -ENOMEM;
     547                 :            :                 }
     548                 :            :                 break;
     549                 :            :         }
     550                 :            : 
     551                 :            :         return 0;
     552                 :            : }
     553                 :            : EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_dp_decode_sideband_req);
     554                 :            : 
     555                 :            : void
     556                 :          0 : drm_dp_dump_sideband_msg_req_body(const struct drm_dp_sideband_msg_req_body *req,
     557                 :            :                                   int indent, struct drm_printer *printer)
     558                 :            : {
     559                 :          0 :         int i;
     560                 :            : 
     561                 :            : #define P(f, ...) drm_printf_indent(printer, indent, f, ##__VA_ARGS__)
     562         [ #  # ]:          0 :         if (req->req_type == DP_LINK_ADDRESS) {
     563                 :            :                 /* No contents to print */
     564         [ #  # ]:          0 :                 P("type=%s\n", drm_dp_mst_req_type_str(req->req_type));
     565                 :          0 :                 return;
     566                 :            :         }
     567                 :            : 
     568         [ #  # ]:          0 :         P("type=%s contents:\n", drm_dp_mst_req_type_str(req->req_type));
     569                 :          0 :         indent++;
     570                 :            : 
     571   [ #  #  #  #  :          0 :         switch (req->req_type) {
             #  #  #  # ]
     572                 :          0 :         case DP_ENUM_PATH_RESOURCES:
     573                 :            :         case DP_POWER_DOWN_PHY:
     574                 :            :         case DP_POWER_UP_PHY:
     575                 :          0 :                 P("port=%d\n", req->u.port_num.port_number);
     576                 :          0 :                 break;
     577                 :          0 :         case DP_ALLOCATE_PAYLOAD:
     578                 :          0 :                 P("port=%d vcpi=%d pbn=%d sdp_streams=%d %*ph\n",
     579                 :            :                   req->u.allocate_payload.port_number,
     580                 :            :                   req->u.allocate_payload.vcpi, req->u.allocate_payload.pbn,
     581                 :            :                   req->u.allocate_payload.number_sdp_streams,
     582                 :            :                   req->u.allocate_payload.number_sdp_streams,
     583                 :            :                   req->u.allocate_payload.sdp_stream_sink);
     584                 :          0 :                 break;
     585                 :          0 :         case DP_QUERY_PAYLOAD:
     586                 :          0 :                 P("port=%d vcpi=%d\n",
     587                 :            :                   req->u.query_payload.port_number,
     588                 :            :                   req->u.query_payload.vcpi);
     589                 :          0 :                 break;
     590                 :          0 :         case DP_REMOTE_DPCD_READ:
     591                 :          0 :                 P("port=%d dpcd_addr=%05x len=%d\n",
     592                 :            :                   req->u.dpcd_read.port_number, req->u.dpcd_read.dpcd_address,
     593                 :            :                   req->u.dpcd_read.num_bytes);
     594                 :          0 :                 break;
     595                 :          0 :         case DP_REMOTE_DPCD_WRITE:
     596                 :          0 :                 P("port=%d addr=%05x len=%d: %*ph\n",
     597                 :            :                   req->u.dpcd_write.port_number,
     598                 :            :                   req->u.dpcd_write.dpcd_address,
     599                 :            :                   req->u.dpcd_write.num_bytes, req->u.dpcd_write.num_bytes,
     600                 :            :                   req->u.dpcd_write.bytes);
     601                 :          0 :                 break;
     602                 :          0 :         case DP_REMOTE_I2C_READ:
     603                 :          0 :                 P("port=%d num_tx=%d id=%d size=%d:\n",
     604                 :            :                   req->u.i2c_read.port_number,
     605                 :            :                   req->u.i2c_read.num_transactions,
     606                 :            :                   req->u.i2c_read.read_i2c_device_id,
     607                 :            :                   req->u.i2c_read.num_bytes_read);
     608                 :            : 
     609                 :          0 :                 indent++;
     610         [ #  # ]:          0 :                 for (i = 0; i < req->u.i2c_read.num_transactions; i++) {
     611                 :          0 :                         const struct drm_dp_remote_i2c_read_tx *rtx =
     612                 :            :                                 &req->u.i2c_read.transactions[i];
     613                 :            : 
     614                 :          0 :                         P("%d: id=%03d size=%03d no_stop_bit=%d tx_delay=%03d: %*ph\n",
     615                 :            :                           i, rtx->i2c_dev_id, rtx->num_bytes,
     616                 :            :                           rtx->no_stop_bit, rtx->i2c_transaction_delay,
     617                 :            :                           rtx->num_bytes, rtx->bytes);
     618                 :            :                 }
     619                 :            :                 break;
     620                 :          0 :         case DP_REMOTE_I2C_WRITE:
     621                 :          0 :                 P("port=%d id=%d size=%d: %*ph\n",
     622                 :            :                   req->u.i2c_write.port_number,
     623                 :            :                   req->u.i2c_write.write_i2c_device_id,
     624                 :            :                   req->u.i2c_write.num_bytes, req->u.i2c_write.num_bytes,
     625                 :            :                   req->u.i2c_write.bytes);
     626                 :          0 :                 break;
     627                 :          0 :         default:
     628                 :          0 :                 P("???\n");
     629                 :          0 :                 break;
     630                 :            :         }
     631                 :            : #undef P
     632                 :            : }
     633                 :            : EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_dp_dump_sideband_msg_req_body);
     634                 :            : 
     635                 :            : static inline void
     636                 :          0 : drm_dp_mst_dump_sideband_msg_tx(struct drm_printer *p,
     637                 :            :                                 const struct drm_dp_sideband_msg_tx *txmsg)
     638                 :            : {
     639                 :          0 :         struct drm_dp_sideband_msg_req_body req;
     640                 :          0 :         char buf[64];
     641                 :          0 :         int ret;
     642                 :          0 :         int i;
     643                 :            : 
     644                 :          0 :         drm_dp_mst_rad_to_str(txmsg->dst->rad, txmsg->dst->lct, buf,
     645                 :            :                               sizeof(buf));
     646                 :          0 :         drm_printf(p, "txmsg cur_offset=%x cur_len=%x seqno=%x state=%s path_msg=%d dst=%s\n",
     647                 :          0 :                    txmsg->cur_offset, txmsg->cur_len, txmsg->seqno,
     648                 :            :                    drm_dp_mst_sideband_tx_state_str(txmsg->state),
     649         [ #  # ]:          0 :                    txmsg->path_msg, buf);
     650                 :            : 
     651                 :          0 :         ret = drm_dp_decode_sideband_req(txmsg, &req);
     652         [ #  # ]:          0 :         if (ret) {
     653                 :          0 :                 drm_printf(p, "<failed to decode sideband req: %d>\n", ret);
     654                 :          0 :                 return;
     655                 :            :         }
     656                 :          0 :         drm_dp_dump_sideband_msg_req_body(&req, 1, p);
     657                 :            : 
     658   [ #  #  #  # ]:          0 :         switch (req.req_type) {
     659                 :          0 :         case DP_REMOTE_DPCD_WRITE:
     660                 :          0 :                 kfree(req.u.dpcd_write.bytes);
     661                 :          0 :                 break;
     662                 :            :         case DP_REMOTE_I2C_READ:
     663         [ #  # ]:          0 :                 for (i = 0; i < req.u.i2c_read.num_transactions; i++)
     664                 :          0 :                         kfree(req.u.i2c_read.transactions[i].bytes);
     665                 :            :                 break;
     666                 :          0 :         case DP_REMOTE_I2C_WRITE:
     667                 :          0 :                 kfree(req.u.i2c_write.bytes);
     668                 :          0 :                 break;
     669                 :            :         }
     670                 :          0 : }
     671                 :            : 
     672                 :          0 : static void drm_dp_crc_sideband_chunk_req(u8 *msg, u8 len)
     673                 :            : {
     674                 :          0 :         u8 crc4;
     675                 :          0 :         crc4 = drm_dp_msg_data_crc4(msg, len);
     676                 :          0 :         msg[len] = crc4;
     677                 :            : }
     678                 :            : 
     679                 :          0 : static void drm_dp_encode_sideband_reply(struct drm_dp_sideband_msg_reply_body *rep,
     680                 :            :                                          struct drm_dp_sideband_msg_tx *raw)
     681                 :            : {
     682                 :          0 :         int idx = 0;
     683                 :          0 :         u8 *buf = raw->msg;
     684                 :            : 
     685                 :          0 :         buf[idx++] = (rep->reply_type & 0x1) << 7 | (rep->req_type & 0x7f);
     686                 :            : 
     687                 :          0 :         raw->cur_len = idx;
     688                 :            : }
     689                 :            : 
     690                 :            : /* this adds a chunk of msg to the builder to get the final msg */
     691                 :          0 : static bool drm_dp_sideband_msg_build(struct drm_dp_sideband_msg_rx *msg,
     692                 :            :                                       u8 *replybuf, u8 replybuflen, bool hdr)
     693                 :            : {
     694                 :          0 :         int ret;
     695                 :          0 :         u8 crc4;
     696                 :            : 
     697         [ #  # ]:          0 :         if (hdr) {
     698                 :          0 :                 u8 hdrlen;
     699                 :          0 :                 struct drm_dp_sideband_msg_hdr recv_hdr;
     700                 :          0 :                 ret = drm_dp_decode_sideband_msg_hdr(&recv_hdr, replybuf, replybuflen, &hdrlen);
     701         [ #  # ]:          0 :                 if (ret == false) {
     702                 :          0 :                         print_hex_dump(KERN_DEBUG, "failed hdr", DUMP_PREFIX_NONE, 16, 1, replybuf, replybuflen, false);
     703                 :          0 :                         return false;
     704                 :            :                 }
     705                 :            : 
     706                 :            :                 /*
     707                 :            :                  * ignore out-of-order messages or messages that are part of a
     708                 :            :                  * failed transaction
     709                 :            :                  */
     710   [ #  #  #  # ]:          0 :                 if (!recv_hdr.somt && !msg->have_somt)
     711                 :            :                         return false;
     712                 :            : 
     713                 :            :                 /* get length contained in this portion */
     714                 :          0 :                 msg->curchunk_len = recv_hdr.msg_len;
     715                 :          0 :                 msg->curchunk_hdrlen = hdrlen;
     716                 :            : 
     717                 :            :                 /* we have already gotten an somt - don't bother parsing */
     718   [ #  #  #  # ]:          0 :                 if (recv_hdr.somt && msg->have_somt)
     719                 :            :                         return false;
     720                 :            : 
     721         [ #  # ]:          0 :                 if (recv_hdr.somt) {
     722                 :          0 :                         memcpy(&msg->initial_hdr, &recv_hdr, sizeof(struct drm_dp_sideband_msg_hdr));
     723                 :          0 :                         msg->have_somt = true;
     724                 :            :                 }
     725         [ #  # ]:          0 :                 if (recv_hdr.eomt)
     726                 :          0 :                         msg->have_eomt = true;
     727                 :            : 
     728                 :            :                 /* copy the bytes for the remainder of this header chunk */
     729                 :          0 :                 msg->curchunk_idx = min(msg->curchunk_len, (u8)(replybuflen - hdrlen));
     730                 :          0 :                 memcpy(&msg->chunk[0], replybuf + hdrlen, msg->curchunk_idx);
     731                 :            :         } else {
     732                 :          0 :                 memcpy(&msg->chunk[msg->curchunk_idx], replybuf, replybuflen);
     733                 :          0 :                 msg->curchunk_idx += replybuflen;
     734                 :            :         }
     735                 :            : 
     736         [ #  # ]:          0 :         if (msg->curchunk_idx >= msg->curchunk_len) {
     737                 :            :                 /* do CRC */
     738                 :          0 :                 crc4 = drm_dp_msg_data_crc4(msg->chunk, msg->curchunk_len - 1);
     739                 :            :                 /* copy chunk into bigger msg */
     740                 :          0 :                 memcpy(&msg->msg[msg->curlen], msg->chunk, msg->curchunk_len - 1);
     741                 :          0 :                 msg->curlen += msg->curchunk_len - 1;
     742                 :            :         }
     743                 :            :         return true;
     744                 :            : }
     745                 :            : 
     746                 :          0 : static bool drm_dp_sideband_parse_link_address(struct drm_dp_sideband_msg_rx *raw,
     747                 :            :                                                struct drm_dp_sideband_msg_reply_body *repmsg)
     748                 :            : {
     749                 :          0 :         int idx = 1;
     750                 :          0 :         int i;
     751                 :          0 :         memcpy(repmsg->u.link_addr.guid, &raw->msg[idx], 16);
     752                 :          0 :         idx += 16;
     753                 :          0 :         repmsg->u.link_addr.nports = raw->msg[idx] & 0xf;
     754                 :          0 :         idx++;
     755         [ #  # ]:          0 :         if (idx > raw->curlen)
     756                 :          0 :                 goto fail_len;
     757         [ #  # ]:          0 :         for (i = 0; i < repmsg->u.link_addr.nports; i++) {
     758         [ #  # ]:          0 :                 if (raw->msg[idx] & 0x80)
     759                 :          0 :                         repmsg->u.link_addr.ports[i].input_port = 1;
     760                 :            : 
     761                 :          0 :                 repmsg->u.link_addr.ports[i].peer_device_type = (raw->msg[idx] >> 4) & 0x7;
     762                 :          0 :                 repmsg->u.link_addr.ports[i].port_number = (raw->msg[idx] & 0xf);
     763                 :            : 
     764                 :          0 :                 idx++;
     765         [ #  # ]:          0 :                 if (idx > raw->curlen)
     766                 :          0 :                         goto fail_len;
     767                 :          0 :                 repmsg->u.link_addr.ports[i].mcs = (raw->msg[idx] >> 7) & 0x1;
     768                 :          0 :                 repmsg->u.link_addr.ports[i].ddps = (raw->msg[idx] >> 6) & 0x1;
     769         [ #  # ]:          0 :                 if (repmsg->u.link_addr.ports[i].input_port == 0)
     770                 :          0 :                         repmsg->u.link_addr.ports[i].legacy_device_plug_status = (raw->msg[idx] >> 5) & 0x1;
     771                 :          0 :                 idx++;
     772         [ #  # ]:          0 :                 if (idx > raw->curlen)
     773                 :          0 :                         goto fail_len;
     774         [ #  # ]:          0 :                 if (repmsg->u.link_addr.ports[i].input_port == 0) {
     775                 :          0 :                         repmsg->u.link_addr.ports[i].dpcd_revision = (raw->msg[idx]);
     776                 :          0 :                         idx++;
     777         [ #  # ]:          0 :                         if (idx > raw->curlen)
     778                 :          0 :                                 goto fail_len;
     779                 :          0 :                         memcpy(repmsg->u.link_addr.ports[i].peer_guid, &raw->msg[idx], 16);
     780                 :          0 :                         idx += 16;
     781         [ #  # ]:          0 :                         if (idx > raw->curlen)
     782                 :          0 :                                 goto fail_len;
     783                 :          0 :                         repmsg->u.link_addr.ports[i].num_sdp_streams = (raw->msg[idx] >> 4) & 0xf;
     784                 :          0 :                         repmsg->u.link_addr.ports[i].num_sdp_stream_sinks = (raw->msg[idx] & 0xf);
     785                 :          0 :                         idx++;
     786                 :            : 
     787                 :            :                 }
     788         [ #  # ]:          0 :                 if (idx > raw->curlen)
     789                 :          0 :                         goto fail_len;
     790                 :            :         }
     791                 :            : 
     792                 :            :         return true;
     793                 :          0 : fail_len:
     794                 :          0 :         DRM_DEBUG_KMS("link address reply parse length fail %d %d\n", idx, raw->curlen);
     795                 :          0 :         return false;
     796                 :            : }
     797                 :            : 
     798                 :          0 : static bool drm_dp_sideband_parse_remote_dpcd_read(struct drm_dp_sideband_msg_rx *raw,
     799                 :            :                                                    struct drm_dp_sideband_msg_reply_body *repmsg)
     800                 :            : {
     801                 :          0 :         int idx = 1;
     802                 :          0 :         repmsg->u.remote_dpcd_read_ack.port_number = raw->msg[idx] & 0xf;
     803                 :          0 :         idx++;
     804         [ #  # ]:          0 :         if (idx > raw->curlen)
     805                 :          0 :                 goto fail_len;
     806                 :          0 :         repmsg->u.remote_dpcd_read_ack.num_bytes = raw->msg[idx];
     807                 :          0 :         idx++;
     808         [ #  # ]:          0 :         if (idx > raw->curlen)
     809                 :          0 :                 goto fail_len;
     810                 :            : 
     811                 :          0 :         memcpy(repmsg->u.remote_dpcd_read_ack.bytes, &raw->msg[idx], repmsg->u.remote_dpcd_read_ack.num_bytes);
     812                 :          0 :         return true;
     813                 :          0 : fail_len:
     814                 :          0 :         DRM_DEBUG_KMS("link address reply parse length fail %d %d\n", idx, raw->curlen);
     815                 :          0 :         return false;
     816                 :            : }
     817                 :            : 
     818                 :          0 : static bool drm_dp_sideband_parse_remote_dpcd_write(struct drm_dp_sideband_msg_rx *raw,
     819                 :            :                                                       struct drm_dp_sideband_msg_reply_body *repmsg)
     820                 :            : {
     821                 :          0 :         int idx = 1;
     822                 :          0 :         repmsg->u.remote_dpcd_write_ack.port_number = raw->msg[idx] & 0xf;
     823                 :          0 :         idx++;
     824                 :          0 :         if (idx > raw->curlen)
     825                 :          0 :                 goto fail_len;
     826                 :            :         return true;
     827                 :            : fail_len:
     828                 :          0 :         DRM_DEBUG_KMS("parse length fail %d %d\n", idx, raw->curlen);
     829                 :          0 :         return false;
     830                 :            : }
     831                 :            : 
     832                 :          0 : static bool drm_dp_sideband_parse_remote_i2c_read_ack(struct drm_dp_sideband_msg_rx *raw,
     833                 :            :                                                       struct drm_dp_sideband_msg_reply_body *repmsg)
     834                 :            : {
     835                 :          0 :         int idx = 1;
     836                 :            : 
     837                 :          0 :         repmsg->u.remote_i2c_read_ack.port_number = (raw->msg[idx] & 0xf);
     838                 :          0 :         idx++;
     839         [ #  # ]:          0 :         if (idx > raw->curlen)
     840                 :          0 :                 goto fail_len;
     841                 :          0 :         repmsg->u.remote_i2c_read_ack.num_bytes = raw->msg[idx];
     842                 :          0 :         idx++;
     843                 :            :         /* TODO check */
     844                 :          0 :         memcpy(repmsg->u.remote_i2c_read_ack.bytes, &raw->msg[idx], repmsg->u.remote_i2c_read_ack.num_bytes);
     845                 :          0 :         return true;
     846                 :            : fail_len:
     847                 :          0 :         DRM_DEBUG_KMS("remote i2c reply parse length fail %d %d\n", idx, raw->curlen);
     848                 :          0 :         return false;
     849                 :            : }
     850                 :            : 
     851                 :          0 : static bool drm_dp_sideband_parse_enum_path_resources_ack(struct drm_dp_sideband_msg_rx *raw,
     852                 :            :                                                           struct drm_dp_sideband_msg_reply_body *repmsg)
     853                 :            : {
     854                 :          0 :         int idx = 1;
     855                 :          0 :         repmsg->u.path_resources.port_number = (raw->msg[idx] >> 4) & 0xf;
     856                 :          0 :         repmsg->u.path_resources.fec_capable = raw->msg[idx] & 0x1;
     857                 :          0 :         idx++;
     858         [ #  # ]:          0 :         if (idx > raw->curlen)
     859                 :          0 :                 goto fail_len;
     860                 :          0 :         repmsg->u.path_resources.full_payload_bw_number = (raw->msg[idx] << 8) | (raw->msg[idx+1]);
     861                 :          0 :         idx += 2;
     862         [ #  # ]:          0 :         if (idx > raw->curlen)
     863                 :          0 :                 goto fail_len;
     864                 :          0 :         repmsg->u.path_resources.avail_payload_bw_number = (raw->msg[idx] << 8) | (raw->msg[idx+1]);
     865                 :          0 :         idx += 2;
     866         [ #  # ]:          0 :         if (idx > raw->curlen)
     867                 :          0 :                 goto fail_len;
     868                 :            :         return true;
     869                 :          0 : fail_len:
     870                 :          0 :         DRM_DEBUG_KMS("enum resource parse length fail %d %d\n", idx, raw->curlen);
     871                 :          0 :         return false;
     872                 :            : }
     873                 :            : 
     874                 :          0 : static bool drm_dp_sideband_parse_allocate_payload_ack(struct drm_dp_sideband_msg_rx *raw,
     875                 :            :                                                           struct drm_dp_sideband_msg_reply_body *repmsg)
     876                 :            : {
     877                 :          0 :         int idx = 1;
     878                 :          0 :         repmsg->u.allocate_payload.port_number = (raw->msg[idx] >> 4) & 0xf;
     879                 :          0 :         idx++;
     880         [ #  # ]:          0 :         if (idx > raw->curlen)
     881                 :          0 :                 goto fail_len;
     882                 :          0 :         repmsg->u.allocate_payload.vcpi = raw->msg[idx];
     883                 :          0 :         idx++;
     884         [ #  # ]:          0 :         if (idx > raw->curlen)
     885                 :          0 :                 goto fail_len;
     886                 :          0 :         repmsg->u.allocate_payload.allocated_pbn = (raw->msg[idx] << 8) | (raw->msg[idx+1]);
     887                 :          0 :         idx += 2;
     888         [ #  # ]:          0 :         if (idx > raw->curlen)
     889                 :          0 :                 goto fail_len;
     890                 :            :         return true;
     891                 :          0 : fail_len:
     892                 :          0 :         DRM_DEBUG_KMS("allocate payload parse length fail %d %d\n", idx, raw->curlen);
     893                 :          0 :         return false;
     894                 :            : }
     895                 :            : 
     896                 :            : static bool drm_dp_sideband_parse_query_payload_ack(struct drm_dp_sideband_msg_rx *raw,
     897                 :            :                                                     struct drm_dp_sideband_msg_reply_body *repmsg)
     898                 :            : {
     899                 :            :         int idx = 1;
     900                 :            :         repmsg->u.query_payload.port_number = (raw->msg[idx] >> 4) & 0xf;
     901                 :            :         idx++;
     902                 :            :         if (idx > raw->curlen)
     903                 :            :                 goto fail_len;
     904                 :            :         repmsg->u.query_payload.allocated_pbn = (raw->msg[idx] << 8) | (raw->msg[idx + 1]);
     905                 :            :         idx += 2;
     906                 :            :         if (idx > raw->curlen)
     907                 :            :                 goto fail_len;
     908                 :            :         return true;
     909                 :            : fail_len:
     910                 :            :         DRM_DEBUG_KMS("query payload parse length fail %d %d\n", idx, raw->curlen);
     911                 :            :         return false;
     912                 :            : }
     913                 :            : 
     914                 :          0 : static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_msg_rx *raw,
     915                 :            :                                                        struct drm_dp_sideband_msg_reply_body *repmsg)
     916                 :            : {
     917                 :          0 :         int idx = 1;
     918                 :            : 
     919                 :          0 :         repmsg->u.port_number.port_number = (raw->msg[idx] >> 4) & 0xf;
     920                 :          0 :         idx++;
     921                 :          0 :         if (idx > raw->curlen) {
     922                 :          0 :                 DRM_DEBUG_KMS("power up/down phy parse length fail %d %d\n",
     923                 :            :                               idx, raw->curlen);
     924                 :          0 :                 return false;
     925                 :            :         }
     926                 :            :         return true;
     927                 :            : }
     928                 :            : 
     929                 :          0 : static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
     930                 :            :                                         struct drm_dp_sideband_msg_reply_body *msg)
     931                 :            : {
     932                 :          0 :         memset(msg, 0, sizeof(*msg));
     933                 :          0 :         msg->reply_type = (raw->msg[0] & 0x80) >> 7;
     934                 :          0 :         msg->req_type = (raw->msg[0] & 0x7f);
     935                 :            : 
     936         [ #  # ]:          0 :         if (msg->reply_type == DP_SIDEBAND_REPLY_NAK) {
     937                 :          0 :                 memcpy(msg->u.nak.guid, &raw->msg[1], 16);
     938                 :          0 :                 msg->u.nak.reason = raw->msg[17];
     939                 :          0 :                 msg->u.nak.nak_data = raw->msg[18];
     940                 :          0 :                 return false;
     941                 :            :         }
     942                 :            : 
     943   [ #  #  #  #  :          0 :         switch (msg->req_type) {
          #  #  #  #  #  
                      # ]
     944                 :          0 :         case DP_LINK_ADDRESS:
     945                 :          0 :                 return drm_dp_sideband_parse_link_address(raw, msg);
     946                 :          0 :         case DP_QUERY_PAYLOAD:
     947                 :          0 :                 return drm_dp_sideband_parse_query_payload_ack(raw, msg);
     948                 :          0 :         case DP_REMOTE_DPCD_READ:
     949                 :          0 :                 return drm_dp_sideband_parse_remote_dpcd_read(raw, msg);
     950                 :          0 :         case DP_REMOTE_DPCD_WRITE:
     951         [ #  # ]:          0 :                 return drm_dp_sideband_parse_remote_dpcd_write(raw, msg);
     952                 :          0 :         case DP_REMOTE_I2C_READ:
     953                 :          0 :                 return drm_dp_sideband_parse_remote_i2c_read_ack(raw, msg);
     954                 :          0 :         case DP_ENUM_PATH_RESOURCES:
     955                 :          0 :                 return drm_dp_sideband_parse_enum_path_resources_ack(raw, msg);
     956                 :          0 :         case DP_ALLOCATE_PAYLOAD:
     957                 :          0 :                 return drm_dp_sideband_parse_allocate_payload_ack(raw, msg);
     958                 :          0 :         case DP_POWER_DOWN_PHY:
     959                 :            :         case DP_POWER_UP_PHY:
     960         [ #  # ]:          0 :                 return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);
     961                 :            :         case DP_CLEAR_PAYLOAD_ID_TABLE:
     962                 :            :                 return true; /* since there's nothing to parse */
     963                 :          0 :         default:
     964         [ #  # ]:          0 :                 DRM_ERROR("Got unknown reply 0x%02x (%s)\n", msg->req_type,
     965                 :            :                           drm_dp_mst_req_type_str(msg->req_type));
     966                 :          0 :                 return false;
     967                 :            :         }
     968                 :            : }
     969                 :            : 
     970                 :          0 : static bool drm_dp_sideband_parse_connection_status_notify(struct drm_dp_sideband_msg_rx *raw,
     971                 :            :                                                            struct drm_dp_sideband_msg_req_body *msg)
     972                 :            : {
     973                 :          0 :         int idx = 1;
     974                 :            : 
     975                 :          0 :         msg->u.conn_stat.port_number = (raw->msg[idx] & 0xf0) >> 4;
     976                 :          0 :         idx++;
     977         [ #  # ]:          0 :         if (idx > raw->curlen)
     978                 :          0 :                 goto fail_len;
     979                 :            : 
     980                 :          0 :         memcpy(msg->u.conn_stat.guid, &raw->msg[idx], 16);
     981                 :          0 :         idx += 16;
     982         [ #  # ]:          0 :         if (idx > raw->curlen)
     983                 :          0 :                 goto fail_len;
     984                 :            : 
     985                 :          0 :         msg->u.conn_stat.legacy_device_plug_status = (raw->msg[idx] >> 6) & 0x1;
     986                 :          0 :         msg->u.conn_stat.displayport_device_plug_status = (raw->msg[idx] >> 5) & 0x1;
     987                 :          0 :         msg->u.conn_stat.message_capability_status = (raw->msg[idx] >> 4) & 0x1;
     988                 :          0 :         msg->u.conn_stat.input_port = (raw->msg[idx] >> 3) & 0x1;
     989                 :          0 :         msg->u.conn_stat.peer_device_type = (raw->msg[idx] & 0x7);
     990                 :          0 :         idx++;
     991                 :          0 :         return true;
     992                 :          0 : fail_len:
     993                 :          0 :         DRM_DEBUG_KMS("connection status reply parse length fail %d %d\n", idx, raw->curlen);
     994                 :          0 :         return false;
     995                 :            : }
     996                 :            : 
     997                 :          0 : static bool drm_dp_sideband_parse_resource_status_notify(struct drm_dp_sideband_msg_rx *raw,
     998                 :            :                                                            struct drm_dp_sideband_msg_req_body *msg)
     999                 :            : {
    1000                 :          0 :         int idx = 1;
    1001                 :            : 
    1002                 :          0 :         msg->u.resource_stat.port_number = (raw->msg[idx] & 0xf0) >> 4;
    1003                 :          0 :         idx++;
    1004         [ #  # ]:          0 :         if (idx > raw->curlen)
    1005                 :          0 :                 goto fail_len;
    1006                 :            : 
    1007                 :          0 :         memcpy(msg->u.resource_stat.guid, &raw->msg[idx], 16);
    1008                 :          0 :         idx += 16;
    1009         [ #  # ]:          0 :         if (idx > raw->curlen)
    1010                 :          0 :                 goto fail_len;
    1011                 :            : 
    1012                 :          0 :         msg->u.resource_stat.available_pbn = (raw->msg[idx] << 8) | (raw->msg[idx + 1]);
    1013                 :          0 :         idx++;
    1014                 :          0 :         return true;
    1015                 :          0 : fail_len:
    1016                 :          0 :         DRM_DEBUG_KMS("resource status reply parse length fail %d %d\n", idx, raw->curlen);
    1017                 :          0 :         return false;
    1018                 :            : }
    1019                 :            : 
    1020                 :          0 : static bool drm_dp_sideband_parse_req(struct drm_dp_sideband_msg_rx *raw,
    1021                 :            :                                       struct drm_dp_sideband_msg_req_body *msg)
    1022                 :            : {
    1023                 :          0 :         memset(msg, 0, sizeof(*msg));
    1024                 :          0 :         msg->req_type = (raw->msg[0] & 0x7f);
    1025                 :            : 
    1026      [ #  #  # ]:          0 :         switch (msg->req_type) {
    1027                 :          0 :         case DP_CONNECTION_STATUS_NOTIFY:
    1028                 :          0 :                 return drm_dp_sideband_parse_connection_status_notify(raw, msg);
    1029                 :          0 :         case DP_RESOURCE_STATUS_NOTIFY:
    1030                 :          0 :                 return drm_dp_sideband_parse_resource_status_notify(raw, msg);
    1031                 :          0 :         default:
    1032         [ #  # ]:          0 :                 DRM_ERROR("Got unknown request 0x%02x (%s)\n", msg->req_type,
    1033                 :            :                           drm_dp_mst_req_type_str(msg->req_type));
    1034                 :          0 :                 return false;
    1035                 :            :         }
    1036                 :            : }
    1037                 :            : 
    1038                 :          0 : static int build_dpcd_write(struct drm_dp_sideband_msg_tx *msg, u8 port_num, u32 offset, u8 num_bytes, u8 *bytes)
    1039                 :            : {
    1040                 :          0 :         struct drm_dp_sideband_msg_req_body req;
    1041                 :            : 
    1042                 :          0 :         req.req_type = DP_REMOTE_DPCD_WRITE;
    1043                 :          0 :         req.u.dpcd_write.port_number = port_num;
    1044                 :          0 :         req.u.dpcd_write.dpcd_address = offset;
    1045                 :          0 :         req.u.dpcd_write.num_bytes = num_bytes;
    1046                 :          0 :         req.u.dpcd_write.bytes = bytes;
    1047                 :          0 :         drm_dp_encode_sideband_req(&req, msg);
    1048                 :            : 
    1049                 :          0 :         return 0;
    1050                 :            : }
    1051                 :            : 
    1052                 :          0 : static int build_link_address(struct drm_dp_sideband_msg_tx *msg)
    1053                 :            : {
    1054                 :          0 :         struct drm_dp_sideband_msg_req_body req;
    1055                 :            : 
    1056                 :          0 :         req.req_type = DP_LINK_ADDRESS;
    1057                 :          0 :         drm_dp_encode_sideband_req(&req, msg);
    1058                 :          0 :         return 0;
    1059                 :            : }
    1060                 :            : 
    1061                 :          0 : static int build_clear_payload_id_table(struct drm_dp_sideband_msg_tx *msg)
    1062                 :            : {
    1063                 :          0 :         struct drm_dp_sideband_msg_req_body req;
    1064                 :            : 
    1065                 :          0 :         req.req_type = DP_CLEAR_PAYLOAD_ID_TABLE;
    1066                 :          0 :         drm_dp_encode_sideband_req(&req, msg);
    1067                 :          0 :         return 0;
    1068                 :            : }
    1069                 :            : 
    1070                 :          0 : static int build_enum_path_resources(struct drm_dp_sideband_msg_tx *msg, int port_num)
    1071                 :            : {
    1072                 :          0 :         struct drm_dp_sideband_msg_req_body req;
    1073                 :            : 
    1074                 :          0 :         req.req_type = DP_ENUM_PATH_RESOURCES;
    1075                 :          0 :         req.u.port_num.port_number = port_num;
    1076                 :          0 :         drm_dp_encode_sideband_req(&req, msg);
    1077                 :          0 :         msg->path_msg = true;
    1078                 :          0 :         return 0;
    1079                 :            : }
    1080                 :            : 
    1081                 :          0 : static int build_allocate_payload(struct drm_dp_sideband_msg_tx *msg, int port_num,
    1082                 :            :                                   u8 vcpi, uint16_t pbn,
    1083                 :            :                                   u8 number_sdp_streams,
    1084                 :            :                                   u8 *sdp_stream_sink)
    1085                 :            : {
    1086                 :          0 :         struct drm_dp_sideband_msg_req_body req;
    1087                 :          0 :         memset(&req, 0, sizeof(req));
    1088                 :          0 :         req.req_type = DP_ALLOCATE_PAYLOAD;
    1089                 :          0 :         req.u.allocate_payload.port_number = port_num;
    1090                 :          0 :         req.u.allocate_payload.vcpi = vcpi;
    1091                 :          0 :         req.u.allocate_payload.pbn = pbn;
    1092                 :          0 :         req.u.allocate_payload.number_sdp_streams = number_sdp_streams;
    1093                 :          0 :         memcpy(req.u.allocate_payload.sdp_stream_sink, sdp_stream_sink,
    1094                 :            :                    number_sdp_streams);
    1095                 :          0 :         drm_dp_encode_sideband_req(&req, msg);
    1096                 :          0 :         msg->path_msg = true;
    1097                 :          0 :         return 0;
    1098                 :            : }
    1099                 :            : 
    1100                 :          0 : static int build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,
    1101                 :            :                                   int port_num, bool power_up)
    1102                 :            : {
    1103                 :          0 :         struct drm_dp_sideband_msg_req_body req;
    1104                 :            : 
    1105         [ #  # ]:          0 :         if (power_up)
    1106                 :          0 :                 req.req_type = DP_POWER_UP_PHY;
    1107                 :            :         else
    1108                 :          0 :                 req.req_type = DP_POWER_DOWN_PHY;
    1109                 :            : 
    1110                 :          0 :         req.u.port_num.port_number = port_num;
    1111                 :          0 :         drm_dp_encode_sideband_req(&req, msg);
    1112                 :          0 :         msg->path_msg = true;
    1113                 :          0 :         return 0;
    1114                 :            : }
    1115                 :            : 
    1116                 :          0 : static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
    1117                 :            :                                         struct drm_dp_vcpi *vcpi)
    1118                 :            : {
    1119                 :          0 :         int ret, vcpi_ret;
    1120                 :            : 
    1121                 :          0 :         mutex_lock(&mgr->payload_lock);
    1122                 :          0 :         ret = find_first_zero_bit(&mgr->payload_mask, mgr->max_payloads + 1);
    1123         [ #  # ]:          0 :         if (ret > mgr->max_payloads) {
    1124                 :          0 :                 ret = -EINVAL;
    1125                 :          0 :                 DRM_DEBUG_KMS("out of payload ids %d\n", ret);
    1126                 :          0 :                 goto out_unlock;
    1127                 :            :         }
    1128                 :            : 
    1129                 :          0 :         vcpi_ret = find_first_zero_bit(&mgr->vcpi_mask, mgr->max_payloads + 1);
    1130         [ #  # ]:          0 :         if (vcpi_ret > mgr->max_payloads) {
    1131                 :          0 :                 ret = -EINVAL;
    1132                 :          0 :                 DRM_DEBUG_KMS("out of vcpi ids %d\n", ret);
    1133                 :          0 :                 goto out_unlock;
    1134                 :            :         }
    1135                 :            : 
    1136                 :          0 :         set_bit(ret, &mgr->payload_mask);
    1137                 :          0 :         set_bit(vcpi_ret, &mgr->vcpi_mask);
    1138                 :          0 :         vcpi->vcpi = vcpi_ret + 1;
    1139                 :          0 :         mgr->proposed_vcpis[ret - 1] = vcpi;
    1140                 :          0 : out_unlock:
    1141                 :          0 :         mutex_unlock(&mgr->payload_lock);
    1142                 :          0 :         return ret;
    1143                 :            : }
    1144                 :            : 
    1145                 :          0 : static void drm_dp_mst_put_payload_id(struct drm_dp_mst_topology_mgr *mgr,
    1146                 :            :                                       int vcpi)
    1147                 :            : {
    1148                 :          0 :         int i;
    1149         [ #  # ]:          0 :         if (vcpi == 0)
    1150                 :            :                 return;
    1151                 :            : 
    1152                 :          0 :         mutex_lock(&mgr->payload_lock);
    1153                 :          0 :         DRM_DEBUG_KMS("putting payload %d\n", vcpi);
    1154                 :          0 :         clear_bit(vcpi - 1, &mgr->vcpi_mask);
    1155                 :            : 
    1156         [ #  # ]:          0 :         for (i = 0; i < mgr->max_payloads; i++) {
    1157         [ #  # ]:          0 :                 if (mgr->proposed_vcpis[i] &&
    1158         [ #  # ]:          0 :                     mgr->proposed_vcpis[i]->vcpi == vcpi) {
    1159                 :          0 :                         mgr->proposed_vcpis[i] = NULL;
    1160                 :          0 :                         clear_bit(i + 1, &mgr->payload_mask);
    1161                 :            :                 }
    1162                 :            :         }
    1163                 :          0 :         mutex_unlock(&mgr->payload_lock);
    1164                 :            : }
    1165                 :            : 
    1166                 :          0 : static bool check_txmsg_state(struct drm_dp_mst_topology_mgr *mgr,
    1167                 :            :                               struct drm_dp_sideband_msg_tx *txmsg)
    1168                 :            : {
    1169                 :          0 :         unsigned int state;
    1170                 :            : 
    1171                 :            :         /*
    1172                 :            :          * All updates to txmsg->state are protected by mgr->qlock, and the two
    1173                 :            :          * cases we check here are terminal states. For those the barriers
    1174                 :            :          * provided by the wake_up/wait_event pair are enough.
    1175                 :            :          */
    1176                 :          0 :         state = READ_ONCE(txmsg->state);
    1177   [ #  #  #  # ]:          0 :         return (state == DRM_DP_SIDEBAND_TX_RX ||
    1178                 :            :                 state == DRM_DP_SIDEBAND_TX_TIMEOUT);
    1179                 :            : }
    1180                 :            : 
    1181                 :          0 : static int drm_dp_mst_wait_tx_reply(struct drm_dp_mst_branch *mstb,
    1182                 :            :                                     struct drm_dp_sideband_msg_tx *txmsg)
    1183                 :            : {
    1184                 :          0 :         struct drm_dp_mst_topology_mgr *mgr = mstb->mgr;
    1185                 :          0 :         int ret;
    1186                 :            : 
    1187   [ #  #  #  #  :          0 :         ret = wait_event_timeout(mgr->tx_waitq,
                   #  # ]
    1188                 :            :                                  check_txmsg_state(mgr, txmsg),
    1189                 :            :                                  (4 * HZ));
    1190                 :          0 :         mutex_lock(&mstb->mgr->qlock);
    1191         [ #  # ]:          0 :         if (ret > 0) {
    1192         [ #  # ]:          0 :                 if (txmsg->state == DRM_DP_SIDEBAND_TX_TIMEOUT) {
    1193                 :          0 :                         ret = -EIO;
    1194                 :          0 :                         goto out;
    1195                 :            :                 }
    1196                 :            :         } else {
    1197                 :          0 :                 DRM_DEBUG_KMS("timedout msg send %p %d %d\n", txmsg, txmsg->state, txmsg->seqno);
    1198                 :            : 
    1199                 :            :                 /* dump some state */
    1200                 :          0 :                 ret = -EIO;
    1201                 :            : 
    1202                 :            :                 /* remove from q */
    1203         [ #  # ]:          0 :                 if (txmsg->state == DRM_DP_SIDEBAND_TX_QUEUED ||
    1204                 :            :                     txmsg->state == DRM_DP_SIDEBAND_TX_START_SEND) {
    1205                 :          0 :                         list_del(&txmsg->next);
    1206                 :            :                 }
    1207                 :            : 
    1208         [ #  # ]:          0 :                 if (txmsg->state == DRM_DP_SIDEBAND_TX_START_SEND ||
    1209                 :            :                     txmsg->state == DRM_DP_SIDEBAND_TX_SENT) {
    1210                 :          0 :                         mstb->tx_slots[txmsg->seqno] = NULL;
    1211                 :            :                 }
    1212                 :          0 :                 mgr->is_waiting_for_dwn_reply = false;
    1213                 :            : 
    1214                 :            :         }
    1215                 :          0 : out:
    1216   [ #  #  #  # ]:          0 :         if (unlikely(ret == -EIO) && drm_debug_enabled(DRM_UT_DP)) {
    1217                 :          0 :                 struct drm_printer p = drm_debug_printer(DBG_PREFIX);
    1218                 :            : 
    1219                 :          0 :                 drm_dp_mst_dump_sideband_msg_tx(&p, txmsg);
    1220                 :            :         }
    1221                 :          0 :         mutex_unlock(&mgr->qlock);
    1222                 :            : 
    1223                 :          0 :         drm_dp_mst_kick_tx(mgr);
    1224                 :          0 :         return ret;
    1225                 :            : }
    1226                 :            : 
    1227                 :          0 : static struct drm_dp_mst_branch *drm_dp_add_mst_branch_device(u8 lct, u8 *rad)
    1228                 :            : {
    1229                 :          0 :         struct drm_dp_mst_branch *mstb;
    1230                 :            : 
    1231                 :          0 :         mstb = kzalloc(sizeof(*mstb), GFP_KERNEL);
    1232         [ #  # ]:          0 :         if (!mstb)
    1233                 :            :                 return NULL;
    1234                 :            : 
    1235                 :          0 :         mstb->lct = lct;
    1236         [ #  # ]:          0 :         if (lct > 1)
    1237                 :          0 :                 memcpy(mstb->rad, rad, lct / 2);
    1238                 :          0 :         INIT_LIST_HEAD(&mstb->ports);
    1239                 :          0 :         kref_init(&mstb->topology_kref);
    1240                 :          0 :         kref_init(&mstb->malloc_kref);
    1241                 :          0 :         return mstb;
    1242                 :            : }
    1243                 :            : 
    1244                 :          0 : static void drm_dp_free_mst_branch_device(struct kref *kref)
    1245                 :            : {
    1246                 :          0 :         struct drm_dp_mst_branch *mstb =
    1247                 :          0 :                 container_of(kref, struct drm_dp_mst_branch, malloc_kref);
    1248                 :            : 
    1249         [ #  # ]:          0 :         if (mstb->port_parent)
    1250                 :          0 :                 drm_dp_mst_put_port_malloc(mstb->port_parent);
    1251                 :            : 
    1252                 :          0 :         kfree(mstb);
    1253                 :          0 : }
    1254                 :            : 
    1255                 :            : /**
    1256                 :            :  * DOC: Branch device and port refcounting
    1257                 :            :  *
    1258                 :            :  * Topology refcount overview
    1259                 :            :  * ~~~~~~~~~~~~~~~~~~~~~~~~~~
    1260                 :            :  *
    1261                 :            :  * The refcounting schemes for &struct drm_dp_mst_branch and &struct
    1262                 :            :  * drm_dp_mst_port are somewhat unusual. Both ports and branch devices have
    1263                 :            :  * two different kinds of refcounts: topology refcounts, and malloc refcounts.
    1264                 :            :  *
    1265                 :            :  * Topology refcounts are not exposed to drivers, and are handled internally
    1266                 :            :  * by the DP MST helpers. The helpers use them in order to prevent the
    1267                 :            :  * in-memory topology state from being changed in the middle of critical
    1268                 :            :  * operations like changing the internal state of payload allocations. This
    1269                 :            :  * means each branch and port will be considered to be connected to the rest
    1270                 :            :  * of the topology until its topology refcount reaches zero. Additionally,
    1271                 :            :  * for ports this means that their associated &struct drm_connector will stay
    1272                 :            :  * registered with userspace until the port's refcount reaches 0.
    1273                 :            :  *
    1274                 :            :  * Malloc refcount overview
    1275                 :            :  * ~~~~~~~~~~~~~~~~~~~~~~~~
    1276                 :            :  *
    1277                 :            :  * Malloc references are used to keep a &struct drm_dp_mst_port or &struct
    1278                 :            :  * drm_dp_mst_branch allocated even after all of its topology references have
    1279                 :            :  * been dropped, so that the driver or MST helpers can safely access each
    1280                 :            :  * branch's last known state before it was disconnected from the topology.
    1281                 :            :  * When the malloc refcount of a port or branch reaches 0, the memory
    1282                 :            :  * allocation containing the &struct drm_dp_mst_branch or &struct
    1283                 :            :  * drm_dp_mst_port respectively will be freed.
    1284                 :            :  *
    1285                 :            :  * For &struct drm_dp_mst_branch, malloc refcounts are not currently exposed
    1286                 :            :  * to drivers. As of writing this documentation, there are no drivers that
    1287                 :            :  * have a usecase for accessing &struct drm_dp_mst_branch outside of the MST
    1288                 :            :  * helpers. Exposing this API to drivers in a race-free manner would take more
    1289                 :            :  * tweaking of the refcounting scheme, however patches are welcome provided
    1290                 :            :  * there is a legitimate driver usecase for this.
    1291                 :            :  *
    1292                 :            :  * Refcount relationships in a topology
    1293                 :            :  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1294                 :            :  *
    1295                 :            :  * Let's take a look at why the relationship between topology and malloc
    1296                 :            :  * refcounts is designed the way it is.
    1297                 :            :  *
    1298                 :            :  * .. kernel-figure:: dp-mst/topology-figure-1.dot
    1299                 :            :  *
    1300                 :            :  *    An example of topology and malloc refs in a DP MST topology with two
    1301                 :            :  *    active payloads. Topology refcount increments are indicated by solid
    1302                 :            :  *    lines, and malloc refcount increments are indicated by dashed lines.
    1303                 :            :  *    Each starts from the branch which incremented the refcount, and ends at
    1304                 :            :  *    the branch to which the refcount belongs to, i.e. the arrow points the
    1305                 :            :  *    same way as the C pointers used to reference a structure.
    1306                 :            :  *
    1307                 :            :  * As you can see in the above figure, every branch increments the topology
    1308                 :            :  * refcount of its children, and increments the malloc refcount of its
    1309                 :            :  * parent. Additionally, every payload increments the malloc refcount of its
    1310                 :            :  * assigned port by 1.
    1311                 :            :  *
    1312                 :            :  * So, what would happen if MSTB #3 from the above figure was unplugged from
    1313                 :            :  * the system, but the driver hadn't yet removed payload #2 from port #3? The
    1314                 :            :  * topology would start to look like the figure below.
    1315                 :            :  *
    1316                 :            :  * .. kernel-figure:: dp-mst/topology-figure-2.dot
    1317                 :            :  *
    1318                 :            :  *    Ports and branch devices which have been released from memory are
    1319                 :            :  *    colored grey, and references which have been removed are colored red.
    1320                 :            :  *
    1321                 :            :  * Whenever a port or branch device's topology refcount reaches zero, it will
    1322                 :            :  * decrement the topology refcounts of all its children, the malloc refcount
    1323                 :            :  * of its parent, and finally its own malloc refcount. For MSTB #4 and port
    1324                 :            :  * #4, this means they both have been disconnected from the topology and freed
    1325                 :            :  * from memory. But, because payload #2 is still holding a reference to port
    1326                 :            :  * #3, port #3 is removed from the topology but its &struct drm_dp_mst_port
    1327                 :            :  * is still accessible from memory. This also means port #3 has not yet
    1328                 :            :  * decremented the malloc refcount of MSTB #3, so its &struct
    1329                 :            :  * drm_dp_mst_branch will also stay allocated in memory until port #3's
    1330                 :            :  * malloc refcount reaches 0.
    1331                 :            :  *
    1332                 :            :  * This relationship is necessary because in order to release payload #2, we
    1333                 :            :  * need to be able to figure out the last relative of port #3 that's still
    1334                 :            :  * connected to the topology. In this case, we would travel up the topology as
    1335                 :            :  * shown below.
    1336                 :            :  *
    1337                 :            :  * .. kernel-figure:: dp-mst/topology-figure-3.dot
    1338                 :            :  *
    1339                 :            :  * And finally, remove payload #2 by communicating with port #2 through
    1340                 :            :  * sideband transactions.
    1341                 :            :  */
    1342                 :            : 
    1343                 :            : /**
    1344                 :            :  * drm_dp_mst_get_mstb_malloc() - Increment the malloc refcount of a branch
    1345                 :            :  * device
    1346                 :            :  * @mstb: The &struct drm_dp_mst_branch to increment the malloc refcount of
    1347                 :            :  *
    1348                 :            :  * Increments &drm_dp_mst_branch.malloc_kref. When
    1349                 :            :  * &drm_dp_mst_branch.malloc_kref reaches 0, the memory allocation for @mstb
    1350                 :            :  * will be released and @mstb may no longer be used.
    1351                 :            :  *
    1352                 :            :  * See also: drm_dp_mst_put_mstb_malloc()
    1353                 :            :  */
    1354                 :            : static void
    1355                 :          0 : drm_dp_mst_get_mstb_malloc(struct drm_dp_mst_branch *mstb)
    1356                 :            : {
    1357                 :          0 :         kref_get(&mstb->malloc_kref);
    1358                 :          0 :         DRM_DEBUG("mstb %p (%d)\n", mstb, kref_read(&mstb->malloc_kref));
    1359                 :          0 : }
    1360                 :            : 
    1361                 :            : /**
    1362                 :            :  * drm_dp_mst_put_mstb_malloc() - Decrement the malloc refcount of a branch
    1363                 :            :  * device
    1364                 :            :  * @mstb: The &struct drm_dp_mst_branch to decrement the malloc refcount of
    1365                 :            :  *
    1366                 :            :  * Decrements &drm_dp_mst_branch.malloc_kref. When
    1367                 :            :  * &drm_dp_mst_branch.malloc_kref reaches 0, the memory allocation for @mstb
    1368                 :            :  * will be released and @mstb may no longer be used.
    1369                 :            :  *
    1370                 :            :  * See also: drm_dp_mst_get_mstb_malloc()
    1371                 :            :  */
    1372                 :            : static void
    1373                 :          0 : drm_dp_mst_put_mstb_malloc(struct drm_dp_mst_branch *mstb)
    1374                 :            : {
    1375                 :          0 :         DRM_DEBUG("mstb %p (%d)\n", mstb, kref_read(&mstb->malloc_kref) - 1);
    1376                 :          0 :         kref_put(&mstb->malloc_kref, drm_dp_free_mst_branch_device);
    1377                 :          0 : }
    1378                 :            : 
    1379                 :          0 : static void drm_dp_free_mst_port(struct kref *kref)
    1380                 :            : {
    1381                 :          0 :         struct drm_dp_mst_port *port =
    1382                 :          0 :                 container_of(kref, struct drm_dp_mst_port, malloc_kref);
    1383                 :            : 
    1384                 :          0 :         drm_dp_mst_put_mstb_malloc(port->parent);
    1385                 :          0 :         kfree(port);
    1386                 :          0 : }
    1387                 :            : 
    1388                 :            : /**
    1389                 :            :  * drm_dp_mst_get_port_malloc() - Increment the malloc refcount of an MST port
    1390                 :            :  * @port: The &struct drm_dp_mst_port to increment the malloc refcount of
    1391                 :            :  *
    1392                 :            :  * Increments &drm_dp_mst_port.malloc_kref. When &drm_dp_mst_port.malloc_kref
    1393                 :            :  * reaches 0, the memory allocation for @port will be released and @port may
    1394                 :            :  * no longer be used.
    1395                 :            :  *
    1396                 :            :  * Because @port could potentially be freed at any time by the DP MST helpers
    1397                 :            :  * if &drm_dp_mst_port.malloc_kref reaches 0, including during a call to this
    1398                 :            :  * function, drivers that which to make use of &struct drm_dp_mst_port should
    1399                 :            :  * ensure that they grab at least one main malloc reference to their MST ports
    1400                 :            :  * in &drm_dp_mst_topology_cbs.add_connector. This callback is called before
    1401                 :            :  * there is any chance for &drm_dp_mst_port.malloc_kref to reach 0.
    1402                 :            :  *
    1403                 :            :  * See also: drm_dp_mst_put_port_malloc()
    1404                 :            :  */
    1405                 :            : void
    1406                 :          0 : drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port)
    1407                 :            : {
    1408                 :          0 :         kref_get(&port->malloc_kref);
    1409                 :          0 :         DRM_DEBUG("port %p (%d)\n", port, kref_read(&port->malloc_kref));
    1410                 :          0 : }
    1411                 :            : EXPORT_SYMBOL(drm_dp_mst_get_port_malloc);
    1412                 :            : 
    1413                 :            : /**
    1414                 :            :  * drm_dp_mst_put_port_malloc() - Decrement the malloc refcount of an MST port
    1415                 :            :  * @port: The &struct drm_dp_mst_port to decrement the malloc refcount of
    1416                 :            :  *
    1417                 :            :  * Decrements &drm_dp_mst_port.malloc_kref. When &drm_dp_mst_port.malloc_kref
    1418                 :            :  * reaches 0, the memory allocation for @port will be released and @port may
    1419                 :            :  * no longer be used.
    1420                 :            :  *
    1421                 :            :  * See also: drm_dp_mst_get_port_malloc()
    1422                 :            :  */
    1423                 :            : void
    1424                 :          0 : drm_dp_mst_put_port_malloc(struct drm_dp_mst_port *port)
    1425                 :            : {
    1426                 :          0 :         DRM_DEBUG("port %p (%d)\n", port, kref_read(&port->malloc_kref) - 1);
    1427                 :          0 :         kref_put(&port->malloc_kref, drm_dp_free_mst_port);
    1428                 :          0 : }
    1429                 :            : EXPORT_SYMBOL(drm_dp_mst_put_port_malloc);
    1430                 :            : 
    1431                 :            : #if IS_ENABLED(CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS)
    1432                 :            : 
    1433                 :            : #define STACK_DEPTH 8
    1434                 :            : 
    1435                 :            : static noinline void
    1436                 :            : __topology_ref_save(struct drm_dp_mst_topology_mgr *mgr,
    1437                 :            :                     struct drm_dp_mst_topology_ref_history *history,
    1438                 :            :                     enum drm_dp_mst_topology_ref_type type)
    1439                 :            : {
    1440                 :            :         struct drm_dp_mst_topology_ref_entry *entry = NULL;
    1441                 :            :         depot_stack_handle_t backtrace;
    1442                 :            :         ulong stack_entries[STACK_DEPTH];
    1443                 :            :         uint n;
    1444                 :            :         int i;
    1445                 :            : 
    1446                 :            :         n = stack_trace_save(stack_entries, ARRAY_SIZE(stack_entries), 1);
    1447                 :            :         backtrace = stack_depot_save(stack_entries, n, GFP_KERNEL);
    1448                 :            :         if (!backtrace)
    1449                 :            :                 return;
    1450                 :            : 
    1451                 :            :         /* Try to find an existing entry for this backtrace */
    1452                 :            :         for (i = 0; i < history->len; i++) {
    1453                 :            :                 if (history->entries[i].backtrace == backtrace) {
    1454                 :            :                         entry = &history->entries[i];
    1455                 :            :                         break;
    1456                 :            :                 }
    1457                 :            :         }
    1458                 :            : 
    1459                 :            :         /* Otherwise add one */
    1460                 :            :         if (!entry) {
    1461                 :            :                 struct drm_dp_mst_topology_ref_entry *new;
    1462                 :            :                 int new_len = history->len + 1;
    1463                 :            : 
    1464                 :            :                 new = krealloc(history->entries, sizeof(*new) * new_len,
    1465                 :            :                                GFP_KERNEL);
    1466                 :            :                 if (!new)
    1467                 :            :                         return;
    1468                 :            : 
    1469                 :            :                 entry = &new[history->len];
    1470                 :            :                 history->len = new_len;
    1471                 :            :                 history->entries = new;
    1472                 :            : 
    1473                 :            :                 entry->backtrace = backtrace;
    1474                 :            :                 entry->type = type;
    1475                 :            :                 entry->count = 0;
    1476                 :            :         }
    1477                 :            :         entry->count++;
    1478                 :            :         entry->ts_nsec = ktime_get_ns();
    1479                 :            : }
    1480                 :            : 
    1481                 :            : static int
    1482                 :            : topology_ref_history_cmp(const void *a, const void *b)
    1483                 :            : {
    1484                 :            :         const struct drm_dp_mst_topology_ref_entry *entry_a = a, *entry_b = b;
    1485                 :            : 
    1486                 :            :         if (entry_a->ts_nsec > entry_b->ts_nsec)
    1487                 :            :                 return 1;
    1488                 :            :         else if (entry_a->ts_nsec < entry_b->ts_nsec)
    1489                 :            :                 return -1;
    1490                 :            :         else
    1491                 :            :                 return 0;
    1492                 :            : }
    1493                 :            : 
    1494                 :            : static inline const char *
    1495                 :            : topology_ref_type_to_str(enum drm_dp_mst_topology_ref_type type)
    1496                 :            : {
    1497                 :            :         if (type == DRM_DP_MST_TOPOLOGY_REF_GET)
    1498                 :            :                 return "get";
    1499                 :            :         else
    1500                 :            :                 return "put";
    1501                 :            : }
    1502                 :            : 
    1503                 :            : static void
    1504                 :            : __dump_topology_ref_history(struct drm_dp_mst_topology_ref_history *history,
    1505                 :            :                             void *ptr, const char *type_str)
    1506                 :            : {
    1507                 :            :         struct drm_printer p = drm_debug_printer(DBG_PREFIX);
    1508                 :            :         char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
    1509                 :            :         int i;
    1510                 :            : 
    1511                 :            :         if (!buf)
    1512                 :            :                 return;
    1513                 :            : 
    1514                 :            :         if (!history->len)
    1515                 :            :                 goto out;
    1516                 :            : 
    1517                 :            :         /* First, sort the list so that it goes from oldest to newest
    1518                 :            :          * reference entry
    1519                 :            :          */
    1520                 :            :         sort(history->entries, history->len, sizeof(*history->entries),
    1521                 :            :              topology_ref_history_cmp, NULL);
    1522                 :            : 
    1523                 :            :         drm_printf(&p, "%s (%p) topology count reached 0, dumping history:\n",
    1524                 :            :                    type_str, ptr);
    1525                 :            : 
    1526                 :            :         for (i = 0; i < history->len; i++) {
    1527                 :            :                 const struct drm_dp_mst_topology_ref_entry *entry =
    1528                 :            :                         &history->entries[i];
    1529                 :            :                 ulong *entries;
    1530                 :            :                 uint nr_entries;
    1531                 :            :                 u64 ts_nsec = entry->ts_nsec;
    1532                 :            :                 u32 rem_nsec = do_div(ts_nsec, 1000000000);
    1533                 :            : 
    1534                 :            :                 nr_entries = stack_depot_fetch(entry->backtrace, &entries);
    1535                 :            :                 stack_trace_snprint(buf, PAGE_SIZE, entries, nr_entries, 4);
    1536                 :            : 
    1537                 :            :                 drm_printf(&p, "  %d %ss (last at %5llu.%06u):\n%s",
    1538                 :            :                            entry->count,
    1539                 :            :                            topology_ref_type_to_str(entry->type),
    1540                 :            :                            ts_nsec, rem_nsec / 1000, buf);
    1541                 :            :         }
    1542                 :            : 
    1543                 :            :         /* Now free the history, since this is the only time we expose it */
    1544                 :            :         kfree(history->entries);
    1545                 :            : out:
    1546                 :            :         kfree(buf);
    1547                 :            : }
    1548                 :            : 
    1549                 :            : static __always_inline void
    1550                 :            : drm_dp_mst_dump_mstb_topology_history(struct drm_dp_mst_branch *mstb)
    1551                 :            : {
    1552                 :            :         __dump_topology_ref_history(&mstb->topology_ref_history, mstb,
    1553                 :            :                                     "MSTB");
    1554                 :            : }
    1555                 :            : 
    1556                 :            : static __always_inline void
    1557                 :            : drm_dp_mst_dump_port_topology_history(struct drm_dp_mst_port *port)
    1558                 :            : {
    1559                 :            :         __dump_topology_ref_history(&port->topology_ref_history, port,
    1560                 :            :                                     "Port");
    1561                 :            : }
    1562                 :            : 
    1563                 :            : static __always_inline void
    1564                 :            : save_mstb_topology_ref(struct drm_dp_mst_branch *mstb,
    1565                 :            :                        enum drm_dp_mst_topology_ref_type type)
    1566                 :            : {
    1567                 :            :         __topology_ref_save(mstb->mgr, &mstb->topology_ref_history, type);
    1568                 :            : }
    1569                 :            : 
    1570                 :            : static __always_inline void
    1571                 :            : save_port_topology_ref(struct drm_dp_mst_port *port,
    1572                 :            :                        enum drm_dp_mst_topology_ref_type type)
    1573                 :            : {
    1574                 :            :         __topology_ref_save(port->mgr, &port->topology_ref_history, type);
    1575                 :            : }
    1576                 :            : 
    1577                 :            : static inline void
    1578                 :            : topology_ref_history_lock(struct drm_dp_mst_topology_mgr *mgr)
    1579                 :            : {
    1580                 :            :         mutex_lock(&mgr->topology_ref_history_lock);
    1581                 :            : }
    1582                 :            : 
    1583                 :            : static inline void
    1584                 :            : topology_ref_history_unlock(struct drm_dp_mst_topology_mgr *mgr)
    1585                 :            : {
    1586                 :            :         mutex_unlock(&mgr->topology_ref_history_lock);
    1587                 :            : }
    1588                 :            : #else
    1589                 :            : static inline void
    1590                 :          0 : topology_ref_history_lock(struct drm_dp_mst_topology_mgr *mgr) {}
    1591                 :            : static inline void
    1592                 :          0 : topology_ref_history_unlock(struct drm_dp_mst_topology_mgr *mgr) {}
    1593                 :            : static inline void
    1594                 :          0 : drm_dp_mst_dump_mstb_topology_history(struct drm_dp_mst_branch *mstb) {}
    1595                 :            : static inline void
    1596                 :          0 : drm_dp_mst_dump_port_topology_history(struct drm_dp_mst_port *port) {}
    1597                 :            : #define save_mstb_topology_ref(mstb, type)
    1598                 :            : #define save_port_topology_ref(port, type)
    1599                 :            : #endif
    1600                 :            : 
    1601                 :          0 : static void drm_dp_destroy_mst_branch_device(struct kref *kref)
    1602                 :            : {
    1603                 :          0 :         struct drm_dp_mst_branch *mstb =
    1604                 :          0 :                 container_of(kref, struct drm_dp_mst_branch, topology_kref);
    1605                 :          0 :         struct drm_dp_mst_topology_mgr *mgr = mstb->mgr;
    1606                 :            : 
    1607                 :          0 :         drm_dp_mst_dump_mstb_topology_history(mstb);
    1608                 :            : 
    1609                 :          0 :         INIT_LIST_HEAD(&mstb->destroy_next);
    1610                 :            : 
    1611                 :            :         /*
    1612                 :            :          * This can get called under mgr->mutex, so we need to perform the
    1613                 :            :          * actual destruction of the mstb in another worker
    1614                 :            :          */
    1615                 :          0 :         mutex_lock(&mgr->delayed_destroy_lock);
    1616                 :          0 :         list_add(&mstb->destroy_next, &mgr->destroy_branch_device_list);
    1617                 :          0 :         mutex_unlock(&mgr->delayed_destroy_lock);
    1618                 :          0 :         schedule_work(&mgr->delayed_destroy_work);
    1619                 :          0 : }
    1620                 :            : 
    1621                 :            : /**
    1622                 :            :  * drm_dp_mst_topology_try_get_mstb() - Increment the topology refcount of a
    1623                 :            :  * branch device unless it's zero
    1624                 :            :  * @mstb: &struct drm_dp_mst_branch to increment the topology refcount of
    1625                 :            :  *
    1626                 :            :  * Attempts to grab a topology reference to @mstb, if it hasn't yet been
    1627                 :            :  * removed from the topology (e.g. &drm_dp_mst_branch.topology_kref has
    1628                 :            :  * reached 0). Holding a topology reference implies that a malloc reference
    1629                 :            :  * will be held to @mstb as long as the user holds the topology reference.
    1630                 :            :  *
    1631                 :            :  * Care should be taken to ensure that the user has at least one malloc
    1632                 :            :  * reference to @mstb. If you already have a topology reference to @mstb, you
    1633                 :            :  * should use drm_dp_mst_topology_get_mstb() instead.
    1634                 :            :  *
    1635                 :            :  * See also:
    1636                 :            :  * drm_dp_mst_topology_get_mstb()
    1637                 :            :  * drm_dp_mst_topology_put_mstb()
    1638                 :            :  *
    1639                 :            :  * Returns:
    1640                 :            :  * * 1: A topology reference was grabbed successfully
    1641                 :            :  * * 0: @port is no longer in the topology, no reference was grabbed
    1642                 :            :  */
    1643                 :            : static int __must_check
    1644                 :          0 : drm_dp_mst_topology_try_get_mstb(struct drm_dp_mst_branch *mstb)
    1645                 :            : {
    1646                 :          0 :         int ret;
    1647                 :            : 
    1648                 :          0 :         topology_ref_history_lock(mstb->mgr);
    1649                 :          0 :         ret = kref_get_unless_zero(&mstb->topology_kref);
    1650         [ #  # ]:          0 :         if (ret) {
    1651                 :          0 :                 DRM_DEBUG("mstb %p (%d)\n",
    1652                 :            :                           mstb, kref_read(&mstb->topology_kref));
    1653                 :          0 :                 save_mstb_topology_ref(mstb, DRM_DP_MST_TOPOLOGY_REF_GET);
    1654                 :            :         }
    1655                 :            : 
    1656                 :          0 :         topology_ref_history_unlock(mstb->mgr);
    1657                 :            : 
    1658                 :          0 :         return ret;
    1659                 :            : }
    1660                 :            : 
    1661                 :            : /**
    1662                 :            :  * drm_dp_mst_topology_get_mstb() - Increment the topology refcount of a
    1663                 :            :  * branch device
    1664                 :            :  * @mstb: The &struct drm_dp_mst_branch to increment the topology refcount of
    1665                 :            :  *
    1666                 :            :  * Increments &drm_dp_mst_branch.topology_refcount without checking whether or
    1667                 :            :  * not it's already reached 0. This is only valid to use in scenarios where
    1668                 :            :  * you are already guaranteed to have at least one active topology reference
    1669                 :            :  * to @mstb. Otherwise, drm_dp_mst_topology_try_get_mstb() must be used.
    1670                 :            :  *
    1671                 :            :  * See also:
    1672                 :            :  * drm_dp_mst_topology_try_get_mstb()
    1673                 :            :  * drm_dp_mst_topology_put_mstb()
    1674                 :            :  */
    1675                 :          0 : static void drm_dp_mst_topology_get_mstb(struct drm_dp_mst_branch *mstb)
    1676                 :            : {
    1677                 :          0 :         topology_ref_history_lock(mstb->mgr);
    1678                 :            : 
    1679                 :          0 :         save_mstb_topology_ref(mstb, DRM_DP_MST_TOPOLOGY_REF_GET);
    1680         [ #  # ]:          0 :         WARN_ON(kref_read(&mstb->topology_kref) == 0);
    1681                 :          0 :         kref_get(&mstb->topology_kref);
    1682                 :          0 :         DRM_DEBUG("mstb %p (%d)\n", mstb, kref_read(&mstb->topology_kref));
    1683                 :            : 
    1684                 :          0 :         topology_ref_history_unlock(mstb->mgr);
    1685                 :          0 : }
    1686                 :            : 
    1687                 :            : /**
    1688                 :            :  * drm_dp_mst_topology_put_mstb() - release a topology reference to a branch
    1689                 :            :  * device
    1690                 :            :  * @mstb: The &struct drm_dp_mst_branch to release the topology reference from
    1691                 :            :  *
    1692                 :            :  * Releases a topology reference from @mstb by decrementing
    1693                 :            :  * &drm_dp_mst_branch.topology_kref.
    1694                 :            :  *
    1695                 :            :  * See also:
    1696                 :            :  * drm_dp_mst_topology_try_get_mstb()
    1697                 :            :  * drm_dp_mst_topology_get_mstb()
    1698                 :            :  */
    1699                 :            : static void
    1700                 :          0 : drm_dp_mst_topology_put_mstb(struct drm_dp_mst_branch *mstb)
    1701                 :            : {
    1702                 :          0 :         topology_ref_history_lock(mstb->mgr);
    1703                 :            : 
    1704                 :          0 :         DRM_DEBUG("mstb %p (%d)\n",
    1705                 :            :                   mstb, kref_read(&mstb->topology_kref) - 1);
    1706                 :          0 :         save_mstb_topology_ref(mstb, DRM_DP_MST_TOPOLOGY_REF_PUT);
    1707                 :            : 
    1708                 :          0 :         topology_ref_history_unlock(mstb->mgr);
    1709                 :          0 :         kref_put(&mstb->topology_kref, drm_dp_destroy_mst_branch_device);
    1710                 :          0 : }
    1711                 :            : 
    1712                 :          0 : static void drm_dp_destroy_port(struct kref *kref)
    1713                 :            : {
    1714                 :          0 :         struct drm_dp_mst_port *port =
    1715                 :          0 :                 container_of(kref, struct drm_dp_mst_port, topology_kref);
    1716                 :          0 :         struct drm_dp_mst_topology_mgr *mgr = port->mgr;
    1717                 :            : 
    1718                 :          0 :         drm_dp_mst_dump_port_topology_history(port);
    1719                 :            : 
    1720                 :            :         /* There's nothing that needs locking to destroy an input port yet */
    1721         [ #  # ]:          0 :         if (port->input) {
    1722                 :          0 :                 drm_dp_mst_put_port_malloc(port);
    1723                 :          0 :                 return;
    1724                 :            :         }
    1725                 :            : 
    1726                 :          0 :         kfree(port->cached_edid);
    1727                 :            : 
    1728                 :            :         /*
    1729                 :            :          * we can't destroy the connector here, as we might be holding the
    1730                 :            :          * mode_config.mutex from an EDID retrieval
    1731                 :            :          */
    1732                 :          0 :         mutex_lock(&mgr->delayed_destroy_lock);
    1733                 :          0 :         list_add(&port->next, &mgr->destroy_port_list);
    1734                 :          0 :         mutex_unlock(&mgr->delayed_destroy_lock);
    1735                 :          0 :         schedule_work(&mgr->delayed_destroy_work);
    1736                 :            : }
    1737                 :            : 
    1738                 :            : /**
    1739                 :            :  * drm_dp_mst_topology_try_get_port() - Increment the topology refcount of a
    1740                 :            :  * port unless it's zero
    1741                 :            :  * @port: &struct drm_dp_mst_port to increment the topology refcount of
    1742                 :            :  *
    1743                 :            :  * Attempts to grab a topology reference to @port, if it hasn't yet been
    1744                 :            :  * removed from the topology (e.g. &drm_dp_mst_port.topology_kref has reached
    1745                 :            :  * 0). Holding a topology reference implies that a malloc reference will be
    1746                 :            :  * held to @port as long as the user holds the topology reference.
    1747                 :            :  *
    1748                 :            :  * Care should be taken to ensure that the user has at least one malloc
    1749                 :            :  * reference to @port. If you already have a topology reference to @port, you
    1750                 :            :  * should use drm_dp_mst_topology_get_port() instead.
    1751                 :            :  *
    1752                 :            :  * See also:
    1753                 :            :  * drm_dp_mst_topology_get_port()
    1754                 :            :  * drm_dp_mst_topology_put_port()
    1755                 :            :  *
    1756                 :            :  * Returns:
    1757                 :            :  * * 1: A topology reference was grabbed successfully
    1758                 :            :  * * 0: @port is no longer in the topology, no reference was grabbed
    1759                 :            :  */
    1760                 :            : static int __must_check
    1761                 :          0 : drm_dp_mst_topology_try_get_port(struct drm_dp_mst_port *port)
    1762                 :            : {
    1763                 :          0 :         int ret;
    1764                 :            : 
    1765                 :          0 :         topology_ref_history_lock(port->mgr);
    1766                 :          0 :         ret = kref_get_unless_zero(&port->topology_kref);
    1767         [ #  # ]:          0 :         if (ret) {
    1768                 :          0 :                 DRM_DEBUG("port %p (%d)\n",
    1769                 :            :                           port, kref_read(&port->topology_kref));
    1770                 :          0 :                 save_port_topology_ref(port, DRM_DP_MST_TOPOLOGY_REF_GET);
    1771                 :            :         }
    1772                 :            : 
    1773                 :          0 :         topology_ref_history_unlock(port->mgr);
    1774                 :          0 :         return ret;
    1775                 :            : }
    1776                 :            : 
    1777                 :            : /**
    1778                 :            :  * drm_dp_mst_topology_get_port() - Increment the topology refcount of a port
    1779                 :            :  * @port: The &struct drm_dp_mst_port to increment the topology refcount of
    1780                 :            :  *
    1781                 :            :  * Increments &drm_dp_mst_port.topology_refcount without checking whether or
    1782                 :            :  * not it's already reached 0. This is only valid to use in scenarios where
    1783                 :            :  * you are already guaranteed to have at least one active topology reference
    1784                 :            :  * to @port. Otherwise, drm_dp_mst_topology_try_get_port() must be used.
    1785                 :            :  *
    1786                 :            :  * See also:
    1787                 :            :  * drm_dp_mst_topology_try_get_port()
    1788                 :            :  * drm_dp_mst_topology_put_port()
    1789                 :            :  */
    1790                 :          0 : static void drm_dp_mst_topology_get_port(struct drm_dp_mst_port *port)
    1791                 :            : {
    1792                 :          0 :         topology_ref_history_lock(port->mgr);
    1793                 :            : 
    1794         [ #  # ]:          0 :         WARN_ON(kref_read(&port->topology_kref) == 0);
    1795                 :          0 :         kref_get(&port->topology_kref);
    1796                 :          0 :         DRM_DEBUG("port %p (%d)\n", port, kref_read(&port->topology_kref));
    1797                 :          0 :         save_port_topology_ref(port, DRM_DP_MST_TOPOLOGY_REF_GET);
    1798                 :            : 
    1799                 :          0 :         topology_ref_history_unlock(port->mgr);
    1800                 :          0 : }
    1801                 :            : 
    1802                 :            : /**
    1803                 :            :  * drm_dp_mst_topology_put_port() - release a topology reference to a port
    1804                 :            :  * @port: The &struct drm_dp_mst_port to release the topology reference from
    1805                 :            :  *
    1806                 :            :  * Releases a topology reference from @port by decrementing
    1807                 :            :  * &drm_dp_mst_port.topology_kref.
    1808                 :            :  *
    1809                 :            :  * See also:
    1810                 :            :  * drm_dp_mst_topology_try_get_port()
    1811                 :            :  * drm_dp_mst_topology_get_port()
    1812                 :            :  */
    1813                 :          0 : static void drm_dp_mst_topology_put_port(struct drm_dp_mst_port *port)
    1814                 :            : {
    1815                 :          0 :         topology_ref_history_lock(port->mgr);
    1816                 :            : 
    1817                 :          0 :         DRM_DEBUG("port %p (%d)\n",
    1818                 :            :                   port, kref_read(&port->topology_kref) - 1);
    1819                 :          0 :         save_port_topology_ref(port, DRM_DP_MST_TOPOLOGY_REF_PUT);
    1820                 :            : 
    1821                 :          0 :         topology_ref_history_unlock(port->mgr);
    1822                 :          0 :         kref_put(&port->topology_kref, drm_dp_destroy_port);
    1823                 :          0 : }
    1824                 :            : 
    1825                 :            : static struct drm_dp_mst_branch *
    1826                 :          0 : drm_dp_mst_topology_get_mstb_validated_locked(struct drm_dp_mst_branch *mstb,
    1827                 :            :                                               struct drm_dp_mst_branch *to_find)
    1828                 :            : {
    1829                 :          0 :         struct drm_dp_mst_port *port;
    1830                 :          0 :         struct drm_dp_mst_branch *rmstb;
    1831                 :            : 
    1832         [ #  # ]:          0 :         if (to_find == mstb)
    1833                 :            :                 return mstb;
    1834                 :            : 
    1835         [ #  # ]:          0 :         list_for_each_entry(port, &mstb->ports, next) {
    1836         [ #  # ]:          0 :                 if (port->mstb) {
    1837                 :          0 :                         rmstb = drm_dp_mst_topology_get_mstb_validated_locked(
    1838                 :            :                             port->mstb, to_find);
    1839         [ #  # ]:          0 :                         if (rmstb)
    1840                 :          0 :                                 return rmstb;
    1841                 :            :                 }
    1842                 :            :         }
    1843                 :            :         return NULL;
    1844                 :            : }
    1845                 :            : 
    1846                 :            : static struct drm_dp_mst_branch *
    1847                 :          0 : drm_dp_mst_topology_get_mstb_validated(struct drm_dp_mst_topology_mgr *mgr,
    1848                 :            :                                        struct drm_dp_mst_branch *mstb)
    1849                 :            : {
    1850                 :          0 :         struct drm_dp_mst_branch *rmstb = NULL;
    1851                 :            : 
    1852                 :          0 :         mutex_lock(&mgr->lock);
    1853         [ #  # ]:          0 :         if (mgr->mst_primary) {
    1854                 :          0 :                 rmstb = drm_dp_mst_topology_get_mstb_validated_locked(
    1855                 :            :                     mgr->mst_primary, mstb);
    1856                 :            : 
    1857   [ #  #  #  # ]:          0 :                 if (rmstb && !drm_dp_mst_topology_try_get_mstb(rmstb))
    1858                 :          0 :                         rmstb = NULL;
    1859                 :            :         }
    1860                 :          0 :         mutex_unlock(&mgr->lock);
    1861                 :          0 :         return rmstb;
    1862                 :            : }
    1863                 :            : 
    1864                 :            : static struct drm_dp_mst_port *
    1865                 :          0 : drm_dp_mst_topology_get_port_validated_locked(struct drm_dp_mst_branch *mstb,
    1866                 :            :                                               struct drm_dp_mst_port *to_find)
    1867                 :            : {
    1868                 :          0 :         struct drm_dp_mst_port *port, *mport;
    1869                 :            : 
    1870         [ #  # ]:          0 :         list_for_each_entry(port, &mstb->ports, next) {
    1871         [ #  # ]:          0 :                 if (port == to_find)
    1872                 :          0 :                         return port;
    1873                 :            : 
    1874         [ #  # ]:          0 :                 if (port->mstb) {
    1875                 :          0 :                         mport = drm_dp_mst_topology_get_port_validated_locked(
    1876                 :            :                             port->mstb, to_find);
    1877         [ #  # ]:          0 :                         if (mport)
    1878                 :          0 :                                 return mport;
    1879                 :            :                 }
    1880                 :            :         }
    1881                 :            :         return NULL;
    1882                 :            : }
    1883                 :            : 
    1884                 :            : static struct drm_dp_mst_port *
    1885                 :          0 : drm_dp_mst_topology_get_port_validated(struct drm_dp_mst_topology_mgr *mgr,
    1886                 :            :                                        struct drm_dp_mst_port *port)
    1887                 :            : {
    1888                 :          0 :         struct drm_dp_mst_port *rport = NULL;
    1889                 :            : 
    1890                 :          0 :         mutex_lock(&mgr->lock);
    1891         [ #  # ]:          0 :         if (mgr->mst_primary) {
    1892                 :          0 :                 rport = drm_dp_mst_topology_get_port_validated_locked(
    1893                 :            :                     mgr->mst_primary, port);
    1894                 :            : 
    1895   [ #  #  #  # ]:          0 :                 if (rport && !drm_dp_mst_topology_try_get_port(rport))
    1896                 :          0 :                         rport = NULL;
    1897                 :            :         }
    1898                 :          0 :         mutex_unlock(&mgr->lock);
    1899                 :          0 :         return rport;
    1900                 :            : }
    1901                 :            : 
    1902                 :          0 : static struct drm_dp_mst_port *drm_dp_get_port(struct drm_dp_mst_branch *mstb, u8 port_num)
    1903                 :            : {
    1904                 :          0 :         struct drm_dp_mst_port *port;
    1905                 :          0 :         int ret;
    1906                 :            : 
    1907         [ #  # ]:          0 :         list_for_each_entry(port, &mstb->ports, next) {
    1908         [ #  # ]:          0 :                 if (port->port_num == port_num) {
    1909                 :          0 :                         ret = drm_dp_mst_topology_try_get_port(port);
    1910         [ #  # ]:          0 :                         return ret ? port : NULL;
    1911                 :            :                 }
    1912                 :            :         }
    1913                 :            : 
    1914                 :            :         return NULL;
    1915                 :            : }
    1916                 :            : 
    1917                 :            : /*
    1918                 :            :  * calculate a new RAD for this MST branch device
    1919                 :            :  * if parent has an LCT of 2 then it has 1 nibble of RAD,
    1920                 :            :  * if parent has an LCT of 3 then it has 2 nibbles of RAD,
    1921                 :            :  */
    1922                 :            : static u8 drm_dp_calculate_rad(struct drm_dp_mst_port *port,
    1923                 :            :                                  u8 *rad)
    1924                 :            : {
    1925                 :            :         int parent_lct = port->parent->lct;
    1926                 :            :         int shift = 4;
    1927                 :            :         int idx = (parent_lct - 1) / 2;
    1928                 :            :         if (parent_lct > 1) {
    1929                 :            :                 memcpy(rad, port->parent->rad, idx + 1);
    1930                 :            :                 shift = (parent_lct % 2) ? 4 : 0;
    1931                 :            :         } else
    1932                 :            :                 rad[0] = 0;
    1933                 :            : 
    1934                 :            :         rad[idx] |= port->port_num << shift;
    1935                 :            :         return parent_lct + 1;
    1936                 :            : }
    1937                 :            : 
    1938                 :          0 : static bool drm_dp_mst_is_end_device(u8 pdt, bool mcs)
    1939                 :            : {
    1940         [ #  # ]:          0 :         switch (pdt) {
    1941                 :            :         case DP_PEER_DEVICE_DP_LEGACY_CONV:
    1942                 :            :         case DP_PEER_DEVICE_SST_SINK:
    1943                 :            :                 return true;
    1944                 :          0 :         case DP_PEER_DEVICE_MST_BRANCHING:
    1945                 :            :                 /* For sst branch device */
    1946   [ #  #  #  #  :          0 :                 if (!mcs)
          #  #  #  #  #  
                      # ]
    1947                 :            :                         return true;
    1948                 :            : 
    1949                 :            :                 return false;
    1950                 :            :         }
    1951                 :            :         return true;
    1952                 :            : }
    1953                 :            : 
    1954                 :            : static int
    1955                 :          0 : drm_dp_port_set_pdt(struct drm_dp_mst_port *port, u8 new_pdt,
    1956                 :            :                     bool new_mcs)
    1957                 :            : {
    1958                 :          0 :         struct drm_dp_mst_topology_mgr *mgr = port->mgr;
    1959                 :          0 :         struct drm_dp_mst_branch *mstb;
    1960                 :          0 :         u8 rad[8], lct;
    1961                 :          0 :         int ret = 0;
    1962                 :            : 
    1963   [ #  #  #  # ]:          0 :         if (port->pdt == new_pdt && port->mcs == new_mcs)
    1964                 :            :                 return 0;
    1965                 :            : 
    1966                 :            :         /* Teardown the old pdt, if there is one */
    1967         [ #  # ]:          0 :         if (port->pdt != DP_PEER_DEVICE_NONE) {
    1968         [ #  # ]:          0 :                 if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) {
    1969                 :            :                         /*
    1970                 :            :                          * If the new PDT would also have an i2c bus,
    1971                 :            :                          * don't bother with reregistering it
    1972                 :            :                          */
    1973         [ #  # ]:          0 :                         if (new_pdt != DP_PEER_DEVICE_NONE &&
    1974                 :            :                             drm_dp_mst_is_end_device(new_pdt, new_mcs)) {
    1975                 :          0 :                                 port->pdt = new_pdt;
    1976                 :          0 :                                 port->mcs = new_mcs;
    1977                 :          0 :                                 return 0;
    1978                 :            :                         }
    1979                 :            : 
    1980                 :            :                         /* remove i2c over sideband */
    1981                 :          0 :                         drm_dp_mst_unregister_i2c_bus(&port->aux);
    1982                 :            :                 } else {
    1983                 :          0 :                         mutex_lock(&mgr->lock);
    1984                 :          0 :                         drm_dp_mst_topology_put_mstb(port->mstb);
    1985                 :          0 :                         port->mstb = NULL;
    1986                 :          0 :                         mutex_unlock(&mgr->lock);
    1987                 :            :                 }
    1988                 :            :         }
    1989                 :            : 
    1990                 :          0 :         port->pdt = new_pdt;
    1991                 :          0 :         port->mcs = new_mcs;
    1992                 :            : 
    1993         [ #  # ]:          0 :         if (port->pdt != DP_PEER_DEVICE_NONE) {
    1994         [ #  # ]:          0 :                 if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) {
    1995                 :            :                         /* add i2c over sideband */
    1996                 :          0 :                         ret = drm_dp_mst_register_i2c_bus(&port->aux);
    1997                 :            :                 } else {
    1998                 :          0 :                         lct = drm_dp_calculate_rad(port, rad);
    1999                 :          0 :                         mstb = drm_dp_add_mst_branch_device(lct, rad);
    2000         [ #  # ]:          0 :                         if (!mstb) {
    2001                 :          0 :                                 ret = -ENOMEM;
    2002                 :          0 :                                 DRM_ERROR("Failed to create MSTB for port %p",
    2003                 :            :                                           port);
    2004                 :          0 :                                 goto out;
    2005                 :            :                         }
    2006                 :            : 
    2007                 :          0 :                         mutex_lock(&mgr->lock);
    2008                 :          0 :                         port->mstb = mstb;
    2009                 :          0 :                         mstb->mgr = port->mgr;
    2010                 :          0 :                         mstb->port_parent = port;
    2011                 :            : 
    2012                 :            :                         /*
    2013                 :            :                          * Make sure this port's memory allocation stays
    2014                 :            :                          * around until its child MSTB releases it
    2015                 :            :                          */
    2016                 :          0 :                         drm_dp_mst_get_port_malloc(port);
    2017                 :          0 :                         mutex_unlock(&mgr->lock);
    2018                 :            : 
    2019                 :            :                         /* And make sure we send a link address for this */
    2020                 :          0 :                         ret = 1;
    2021                 :            :                 }
    2022                 :            :         }
    2023                 :            : 
    2024                 :          0 : out:
    2025         [ #  # ]:          0 :         if (ret < 0)
    2026                 :          0 :                 port->pdt = DP_PEER_DEVICE_NONE;
    2027                 :            :         return ret;
    2028                 :            : }
    2029                 :            : 
    2030                 :            : /**
    2031                 :            :  * drm_dp_mst_dpcd_read() - read a series of bytes from the DPCD via sideband
    2032                 :            :  * @aux: Fake sideband AUX CH
    2033                 :            :  * @offset: address of the (first) register to read
    2034                 :            :  * @buffer: buffer to store the register values
    2035                 :            :  * @size: number of bytes in @buffer
    2036                 :            :  *
    2037                 :            :  * Performs the same functionality for remote devices via
    2038                 :            :  * sideband messaging as drm_dp_dpcd_read() does for local
    2039                 :            :  * devices via actual AUX CH.
    2040                 :            :  *
    2041                 :            :  * Return: Number of bytes read, or negative error code on failure.
    2042                 :            :  */
    2043                 :          0 : ssize_t drm_dp_mst_dpcd_read(struct drm_dp_aux *aux,
    2044                 :            :                              unsigned int offset, void *buffer, size_t size)
    2045                 :            : {
    2046                 :          0 :         struct drm_dp_mst_port *port = container_of(aux, struct drm_dp_mst_port,
    2047                 :            :                                                     aux);
    2048                 :            : 
    2049                 :          0 :         return drm_dp_send_dpcd_read(port->mgr, port,
    2050                 :            :                                      offset, size, buffer);
    2051                 :            : }
    2052                 :            : 
    2053                 :            : /**
    2054                 :            :  * drm_dp_mst_dpcd_write() - write a series of bytes to the DPCD via sideband
    2055                 :            :  * @aux: Fake sideband AUX CH
    2056                 :            :  * @offset: address of the (first) register to write
    2057                 :            :  * @buffer: buffer containing the values to write
    2058                 :            :  * @size: number of bytes in @buffer
    2059                 :            :  *
    2060                 :            :  * Performs the same functionality for remote devices via
    2061                 :            :  * sideband messaging as drm_dp_dpcd_write() does for local
    2062                 :            :  * devices via actual AUX CH.
    2063                 :            :  *
    2064                 :            :  * Return: 0 on success, negative error code on failure.
    2065                 :            :  */
    2066                 :          0 : ssize_t drm_dp_mst_dpcd_write(struct drm_dp_aux *aux,
    2067                 :            :                               unsigned int offset, void *buffer, size_t size)
    2068                 :            : {
    2069                 :          0 :         struct drm_dp_mst_port *port = container_of(aux, struct drm_dp_mst_port,
    2070                 :            :                                                     aux);
    2071                 :            : 
    2072                 :          0 :         return drm_dp_send_dpcd_write(port->mgr, port,
    2073                 :            :                                       offset, size, buffer);
    2074                 :            : }
    2075                 :            : 
    2076                 :          0 : static void drm_dp_check_mstb_guid(struct drm_dp_mst_branch *mstb, u8 *guid)
    2077                 :            : {
    2078                 :          0 :         int ret;
    2079                 :            : 
    2080                 :          0 :         memcpy(mstb->guid, guid, 16);
    2081                 :            : 
    2082                 :          0 :         if (!drm_dp_validate_guid(mstb->mgr, mstb->guid)) {
    2083                 :          0 :                 if (mstb->port_parent) {
    2084                 :          0 :                         ret = drm_dp_send_dpcd_write(
    2085                 :            :                                         mstb->mgr,
    2086                 :            :                                         mstb->port_parent,
    2087                 :            :                                         DP_GUID,
    2088                 :            :                                         16,
    2089                 :            :                                         mstb->guid);
    2090                 :            :                 } else {
    2091                 :            : 
    2092                 :          0 :                         ret = drm_dp_dpcd_write(
    2093                 :          0 :                                         mstb->mgr->aux,
    2094                 :            :                                         DP_GUID,
    2095                 :            :                                         mstb->guid,
    2096                 :            :                                         16);
    2097                 :            :                 }
    2098                 :            :         }
    2099                 :          0 : }
    2100                 :            : 
    2101                 :          0 : static void build_mst_prop_path(const struct drm_dp_mst_branch *mstb,
    2102                 :            :                                 int pnum,
    2103                 :            :                                 char *proppath,
    2104                 :            :                                 size_t proppath_size)
    2105                 :            : {
    2106                 :          0 :         int i;
    2107                 :          0 :         char temp[8];
    2108                 :          0 :         snprintf(proppath, proppath_size, "mst:%d", mstb->mgr->conn_base_id);
    2109         [ #  # ]:          0 :         for (i = 0; i < (mstb->lct - 1); i++) {
    2110         [ #  # ]:          0 :                 int shift = (i % 2) ? 0 : 4;
    2111                 :          0 :                 int port_num = (mstb->rad[i / 2] >> shift) & 0xf;
    2112                 :          0 :                 snprintf(temp, sizeof(temp), "-%d", port_num);
    2113                 :          0 :                 strlcat(proppath, temp, proppath_size);
    2114                 :            :         }
    2115                 :          0 :         snprintf(temp, sizeof(temp), "-%d", pnum);
    2116                 :          0 :         strlcat(proppath, temp, proppath_size);
    2117                 :          0 : }
    2118                 :            : 
    2119                 :            : /**
    2120                 :            :  * drm_dp_mst_connector_late_register() - Late MST connector registration
    2121                 :            :  * @connector: The MST connector
    2122                 :            :  * @port: The MST port for this connector
    2123                 :            :  *
    2124                 :            :  * Helper to register the remote aux device for this MST port. Drivers should
    2125                 :            :  * call this from their mst connector's late_register hook to enable MST aux
    2126                 :            :  * devices.
    2127                 :            :  *
    2128                 :            :  * Return: 0 on success, negative error code on failure.
    2129                 :            :  */
    2130                 :          0 : int drm_dp_mst_connector_late_register(struct drm_connector *connector,
    2131                 :            :                                        struct drm_dp_mst_port *port)
    2132                 :            : {
    2133                 :          0 :         DRM_DEBUG_KMS("registering %s remote bus for %s\n",
    2134                 :            :                       port->aux.name, connector->kdev->kobj.name);
    2135                 :            : 
    2136                 :          0 :         port->aux.dev = connector->kdev;
    2137                 :          0 :         return drm_dp_aux_register_devnode(&port->aux);
    2138                 :            : }
    2139                 :            : EXPORT_SYMBOL(drm_dp_mst_connector_late_register);
    2140                 :            : 
    2141                 :            : /**
    2142                 :            :  * drm_dp_mst_connector_early_unregister() - Early MST connector unregistration
    2143                 :            :  * @connector: The MST connector
    2144                 :            :  * @port: The MST port for this connector
    2145                 :            :  *
    2146                 :            :  * Helper to unregister the remote aux device for this MST port, registered by
    2147                 :            :  * drm_dp_mst_connector_late_register(). Drivers should call this from their mst
    2148                 :            :  * connector's early_unregister hook.
    2149                 :            :  */
    2150                 :          0 : void drm_dp_mst_connector_early_unregister(struct drm_connector *connector,
    2151                 :            :                                            struct drm_dp_mst_port *port)
    2152                 :            : {
    2153                 :          0 :         DRM_DEBUG_KMS("unregistering %s remote bus for %s\n",
    2154                 :            :                       port->aux.name, connector->kdev->kobj.name);
    2155                 :          0 :         drm_dp_aux_unregister_devnode(&port->aux);
    2156                 :          0 : }
    2157                 :            : EXPORT_SYMBOL(drm_dp_mst_connector_early_unregister);
    2158                 :            : 
    2159                 :            : static void
    2160                 :          0 : drm_dp_mst_port_add_connector(struct drm_dp_mst_branch *mstb,
    2161                 :            :                               struct drm_dp_mst_port *port)
    2162                 :            : {
    2163                 :          0 :         struct drm_dp_mst_topology_mgr *mgr = port->mgr;
    2164                 :          0 :         char proppath[255];
    2165                 :          0 :         int ret;
    2166                 :            : 
    2167                 :          0 :         build_mst_prop_path(mstb, port->port_num, proppath, sizeof(proppath));
    2168                 :          0 :         port->connector = mgr->cbs->add_connector(mgr, port, proppath);
    2169         [ #  # ]:          0 :         if (!port->connector) {
    2170                 :          0 :                 ret = -ENOMEM;
    2171                 :          0 :                 goto error;
    2172                 :            :         }
    2173                 :            : 
    2174         [ #  # ]:          0 :         if (port->pdt != DP_PEER_DEVICE_NONE &&
    2175         [ #  # ]:          0 :             drm_dp_mst_is_end_device(port->pdt, port->mcs)) {
    2176                 :          0 :                 port->cached_edid = drm_get_edid(port->connector,
    2177                 :            :                                                  &port->aux.ddc);
    2178                 :          0 :                 drm_connector_set_tile_property(port->connector);
    2179                 :            :         }
    2180                 :            : 
    2181                 :          0 :         mgr->cbs->register_connector(port->connector);
    2182                 :          0 :         return;
    2183                 :            : 
    2184                 :            : error:
    2185                 :          0 :         DRM_ERROR("Failed to create connector for port %p: %d\n", port, ret);
    2186                 :            : }
    2187                 :            : 
    2188                 :            : /*
    2189                 :            :  * Drop a topology reference, and unlink the port from the in-memory topology
    2190                 :            :  * layout
    2191                 :            :  */
    2192                 :            : static void
    2193                 :          0 : drm_dp_mst_topology_unlink_port(struct drm_dp_mst_topology_mgr *mgr,
    2194                 :            :                                 struct drm_dp_mst_port *port)
    2195                 :            : {
    2196                 :          0 :         mutex_lock(&mgr->lock);
    2197                 :          0 :         port->parent->num_ports--;
    2198                 :          0 :         list_del(&port->next);
    2199                 :          0 :         mutex_unlock(&mgr->lock);
    2200                 :          0 :         drm_dp_mst_topology_put_port(port);
    2201                 :          0 : }
    2202                 :            : 
    2203                 :            : static struct drm_dp_mst_port *
    2204                 :          0 : drm_dp_mst_add_port(struct drm_device *dev,
    2205                 :            :                     struct drm_dp_mst_topology_mgr *mgr,
    2206                 :            :                     struct drm_dp_mst_branch *mstb, u8 port_number)
    2207                 :            : {
    2208                 :          0 :         struct drm_dp_mst_port *port = kzalloc(sizeof(*port), GFP_KERNEL);
    2209                 :            : 
    2210         [ #  # ]:          0 :         if (!port)
    2211                 :            :                 return NULL;
    2212                 :            : 
    2213                 :          0 :         kref_init(&port->topology_kref);
    2214                 :          0 :         kref_init(&port->malloc_kref);
    2215                 :          0 :         port->parent = mstb;
    2216                 :          0 :         port->port_num = port_number;
    2217                 :          0 :         port->mgr = mgr;
    2218                 :          0 :         port->aux.name = "DPMST";
    2219                 :          0 :         port->aux.dev = dev->dev;
    2220                 :          0 :         port->aux.is_remote = true;
    2221                 :            : 
    2222                 :            :         /* initialize the MST downstream port's AUX crc work queue */
    2223                 :          0 :         drm_dp_remote_aux_init(&port->aux);
    2224                 :            : 
    2225                 :            :         /*
    2226                 :            :          * Make sure the memory allocation for our parent branch stays
    2227                 :            :          * around until our own memory allocation is released
    2228                 :            :          */
    2229                 :          0 :         drm_dp_mst_get_mstb_malloc(mstb);
    2230                 :            : 
    2231                 :          0 :         return port;
    2232                 :            : }
    2233                 :            : 
    2234                 :            : static int
    2235                 :          0 : drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,
    2236                 :            :                                     struct drm_device *dev,
    2237                 :            :                                     struct drm_dp_link_addr_reply_port *port_msg)
    2238                 :            : {
    2239                 :          0 :         struct drm_dp_mst_topology_mgr *mgr = mstb->mgr;
    2240                 :          0 :         struct drm_dp_mst_port *port;
    2241                 :          0 :         int old_ddps = 0, ret;
    2242                 :          0 :         u8 new_pdt = DP_PEER_DEVICE_NONE;
    2243                 :          0 :         bool new_mcs = 0;
    2244                 :          0 :         bool created = false, send_link_addr = false, changed = false;
    2245                 :            : 
    2246                 :          0 :         port = drm_dp_get_port(mstb, port_msg->port_number);
    2247         [ #  # ]:          0 :         if (!port) {
    2248                 :          0 :                 port = drm_dp_mst_add_port(dev, mgr, mstb,
    2249                 :          0 :                                            port_msg->port_number);
    2250         [ #  # ]:          0 :                 if (!port)
    2251                 :            :                         return -ENOMEM;
    2252                 :            :                 created = true;
    2253                 :            :                 changed = true;
    2254   [ #  #  #  #  :          0 :         } else if (!port->input && port_msg->input_port && port->connector) {
                   #  # ]
    2255                 :            :                 /* Since port->connector can't be changed here, we create a
    2256                 :            :                  * new port if input_port changes from 0 to 1
    2257                 :            :                  */
    2258                 :          0 :                 drm_dp_mst_topology_unlink_port(mgr, port);
    2259                 :          0 :                 drm_dp_mst_topology_put_port(port);
    2260                 :          0 :                 port = drm_dp_mst_add_port(dev, mgr, mstb,
    2261                 :          0 :                                            port_msg->port_number);
    2262         [ #  # ]:          0 :                 if (!port)
    2263                 :            :                         return -ENOMEM;
    2264                 :            :                 changed = true;
    2265                 :            :                 created = true;
    2266   [ #  #  #  # ]:          0 :         } else if (port->input && !port_msg->input_port) {
    2267                 :            :                 changed = true;
    2268         [ #  # ]:          0 :         } else if (port->connector) {
    2269                 :            :                 /* We're updating a port that's exposed to userspace, so do it
    2270                 :            :                  * under lock
    2271                 :            :                  */
    2272                 :          0 :                 drm_modeset_lock(&mgr->base.lock, NULL);
    2273                 :            : 
    2274                 :          0 :                 old_ddps = port->ddps;
    2275   [ #  #  #  # ]:          0 :                 changed = port->ddps != port_msg->ddps ||
    2276                 :          0 :                         (port->ddps &&
    2277         [ #  # ]:          0 :                          (port->ldps != port_msg->legacy_device_plug_status ||
    2278         [ #  # ]:          0 :                           port->dpcd_rev != port_msg->dpcd_revision ||
    2279         [ #  # ]:          0 :                           port->mcs != port_msg->mcs ||
    2280         [ #  # ]:          0 :                           port->pdt != port_msg->peer_device_type ||
    2281                 :          0 :                           port->num_sdp_stream_sinks !=
    2282         [ #  # ]:          0 :                           port_msg->num_sdp_stream_sinks));
    2283                 :            :         }
    2284                 :            : 
    2285                 :          0 :         port->input = port_msg->input_port;
    2286         [ #  # ]:          0 :         if (!port->input)
    2287                 :          0 :                 new_pdt = port_msg->peer_device_type;
    2288                 :          0 :         new_mcs = port_msg->mcs;
    2289                 :          0 :         port->ddps = port_msg->ddps;
    2290                 :          0 :         port->ldps = port_msg->legacy_device_plug_status;
    2291                 :          0 :         port->dpcd_rev = port_msg->dpcd_revision;
    2292                 :          0 :         port->num_sdp_streams = port_msg->num_sdp_streams;
    2293                 :          0 :         port->num_sdp_stream_sinks = port_msg->num_sdp_stream_sinks;
    2294                 :            : 
    2295                 :            :         /* manage mstb port lists with mgr lock - take a reference
    2296                 :            :            for this list */
    2297         [ #  # ]:          0 :         if (created) {
    2298                 :          0 :                 mutex_lock(&mgr->lock);
    2299                 :          0 :                 drm_dp_mst_topology_get_port(port);
    2300                 :          0 :                 list_add(&port->next, &mstb->ports);
    2301                 :          0 :                 mstb->num_ports++;
    2302                 :          0 :                 mutex_unlock(&mgr->lock);
    2303                 :            :         }
    2304                 :            : 
    2305                 :            :         /*
    2306                 :            :          * Reprobe PBN caps on both hotplug, and when re-probing the link
    2307                 :            :          * for our parent mstb
    2308                 :            :          */
    2309   [ #  #  #  # ]:          0 :         if (old_ddps != port->ddps || !created) {
    2310   [ #  #  #  # ]:          0 :                 if (port->ddps && !port->input) {
    2311                 :          0 :                         ret = drm_dp_send_enum_path_resources(mgr, mstb,
    2312                 :            :                                                               port);
    2313         [ #  # ]:          0 :                         if (ret == 1)
    2314                 :          0 :                                 changed = true;
    2315                 :            :                 } else {
    2316                 :          0 :                         port->full_pbn = 0;
    2317                 :            :                 }
    2318                 :            :         }
    2319                 :            : 
    2320                 :          0 :         ret = drm_dp_port_set_pdt(port, new_pdt, new_mcs);
    2321         [ #  # ]:          0 :         if (ret == 1) {
    2322                 :            :                 send_link_addr = true;
    2323         [ #  # ]:          0 :         } else if (ret < 0) {
    2324                 :          0 :                 DRM_ERROR("Failed to change PDT on port %p: %d\n",
    2325                 :            :                           port, ret);
    2326                 :          0 :                 goto fail;
    2327                 :            :         }
    2328                 :            : 
    2329                 :            :         /*
    2330                 :            :          * If this port wasn't just created, then we're reprobing because
    2331                 :            :          * we're coming out of suspend. In this case, always resend the link
    2332                 :            :          * address if there's an MSTB on this port
    2333                 :            :          */
    2334   [ #  #  #  # ]:          0 :         if (!created && port->pdt == DP_PEER_DEVICE_MST_BRANCHING &&
    2335         [ #  # ]:          0 :             port->mcs)
    2336                 :          0 :                 send_link_addr = true;
    2337                 :            : 
    2338         [ #  # ]:          0 :         if (port->connector)
    2339                 :          0 :                 drm_modeset_unlock(&mgr->base.lock);
    2340         [ #  # ]:          0 :         else if (!port->input)
    2341                 :          0 :                 drm_dp_mst_port_add_connector(mstb, port);
    2342                 :            : 
    2343   [ #  #  #  # ]:          0 :         if (send_link_addr && port->mstb) {
    2344                 :          0 :                 ret = drm_dp_send_link_address(mgr, port->mstb);
    2345         [ #  # ]:          0 :                 if (ret == 1) /* MSTB below us changed */
    2346                 :            :                         changed = true;
    2347         [ #  # ]:          0 :                 else if (ret < 0)
    2348                 :          0 :                         goto fail_put;
    2349                 :            :         }
    2350                 :            : 
    2351                 :            :         /* put reference to this port */
    2352                 :          0 :         drm_dp_mst_topology_put_port(port);
    2353                 :          0 :         return changed;
    2354                 :            : 
    2355                 :            : fail:
    2356                 :          0 :         drm_dp_mst_topology_unlink_port(mgr, port);
    2357         [ #  # ]:          0 :         if (port->connector)
    2358                 :          0 :                 drm_modeset_unlock(&mgr->base.lock);
    2359                 :          0 : fail_put:
    2360                 :          0 :         drm_dp_mst_topology_put_port(port);
    2361                 :          0 :         return ret;
    2362                 :            : }
    2363                 :            : 
    2364                 :            : static void
    2365                 :          0 : drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
    2366                 :            :                             struct drm_dp_connection_status_notify *conn_stat)
    2367                 :            : {
    2368                 :          0 :         struct drm_dp_mst_topology_mgr *mgr = mstb->mgr;
    2369                 :          0 :         struct drm_dp_mst_port *port;
    2370                 :          0 :         int old_ddps, old_input, ret, i;
    2371                 :          0 :         u8 new_pdt;
    2372                 :          0 :         bool new_mcs;
    2373                 :          0 :         bool dowork = false, create_connector = false;
    2374                 :            : 
    2375                 :          0 :         port = drm_dp_get_port(mstb, conn_stat->port_number);
    2376         [ #  # ]:          0 :         if (!port)
    2377                 :            :                 return;
    2378                 :            : 
    2379         [ #  # ]:          0 :         if (port->connector) {
    2380   [ #  #  #  # ]:          0 :                 if (!port->input && conn_stat->input_port) {
    2381                 :            :                         /*
    2382                 :            :                          * We can't remove a connector from an already exposed
    2383                 :            :                          * port, so just throw the port out and make sure we
    2384                 :            :                          * reprobe the link address of it's parent MSTB
    2385                 :            :                          */
    2386                 :          0 :                         drm_dp_mst_topology_unlink_port(mgr, port);
    2387                 :          0 :                         mstb->link_address_sent = false;
    2388                 :          0 :                         dowork = true;
    2389                 :          0 :                         goto out;
    2390                 :            :                 }
    2391                 :            : 
    2392                 :            :                 /* Locking is only needed if the port's exposed to userspace */
    2393                 :          0 :                 drm_modeset_lock(&mgr->base.lock, NULL);
    2394   [ #  #  #  # ]:          0 :         } else if (port->input && !conn_stat->input_port) {
    2395                 :          0 :                 create_connector = true;
    2396                 :            :                 /* Reprobe link address so we get num_sdp_streams */
    2397                 :          0 :                 mstb->link_address_sent = false;
    2398                 :          0 :                 dowork = true;
    2399                 :            :         }
    2400                 :            : 
    2401                 :          0 :         old_ddps = port->ddps;
    2402                 :          0 :         old_input = port->input;
    2403                 :          0 :         port->input = conn_stat->input_port;
    2404                 :          0 :         port->ldps = conn_stat->legacy_device_plug_status;
    2405                 :          0 :         port->ddps = conn_stat->displayport_device_plug_status;
    2406                 :            : 
    2407         [ #  # ]:          0 :         if (old_ddps != port->ddps) {
    2408   [ #  #  #  # ]:          0 :                 if (port->ddps && !port->input)
    2409                 :          0 :                         drm_dp_send_enum_path_resources(mgr, mstb, port);
    2410                 :            :                 else
    2411                 :          0 :                         port->full_pbn = 0;
    2412                 :            :         }
    2413                 :            : 
    2414         [ #  # ]:          0 :         new_pdt = port->input ? DP_PEER_DEVICE_NONE : conn_stat->peer_device_type;
    2415                 :          0 :         new_mcs = conn_stat->message_capability_status;
    2416                 :          0 :         ret = drm_dp_port_set_pdt(port, new_pdt, new_mcs);
    2417         [ #  # ]:          0 :         if (ret == 1) {
    2418                 :            :                 dowork = true;
    2419         [ #  # ]:          0 :         } else if (ret < 0) {
    2420                 :          0 :                 DRM_ERROR("Failed to change PDT for port %p: %d\n",
    2421                 :            :                           port, ret);
    2422                 :          0 :                 dowork = false;
    2423                 :            :         }
    2424                 :            : 
    2425   [ #  #  #  #  :          0 :         if (!old_input && old_ddps != port->ddps && !port->ddps) {
                   #  # ]
    2426         [ #  # ]:          0 :                 for (i = 0; i < mgr->max_payloads; i++) {
    2427                 :          0 :                         struct drm_dp_vcpi *vcpi = mgr->proposed_vcpis[i];
    2428                 :          0 :                         struct drm_dp_mst_port *port_validated;
    2429                 :            : 
    2430         [ #  # ]:          0 :                         if (!vcpi)
    2431                 :          0 :                                 continue;
    2432                 :            : 
    2433                 :          0 :                         port_validated =
    2434                 :          0 :                                 container_of(vcpi, struct drm_dp_mst_port, vcpi);
    2435                 :          0 :                         port_validated =
    2436                 :          0 :                                 drm_dp_mst_topology_get_port_validated(mgr, port_validated);
    2437         [ #  # ]:          0 :                         if (!port_validated) {
    2438                 :          0 :                                 mutex_lock(&mgr->payload_lock);
    2439                 :          0 :                                 vcpi->num_slots = 0;
    2440                 :          0 :                                 mutex_unlock(&mgr->payload_lock);
    2441                 :            :                         } else {
    2442                 :          0 :                                 drm_dp_mst_topology_put_port(port_validated);
    2443                 :            :                         }
    2444                 :            :                 }
    2445                 :            :         }
    2446                 :            : 
    2447         [ #  # ]:          0 :         if (port->connector)
    2448                 :          0 :                 drm_modeset_unlock(&mgr->base.lock);
    2449         [ #  # ]:          0 :         else if (create_connector)
    2450                 :          0 :                 drm_dp_mst_port_add_connector(mstb, port);
    2451                 :            : 
    2452                 :          0 : out:
    2453                 :          0 :         drm_dp_mst_topology_put_port(port);
    2454         [ #  # ]:          0 :         if (dowork)
    2455                 :          0 :                 queue_work(system_long_wq, &mstb->mgr->work);
    2456                 :            : }
    2457                 :            : 
    2458                 :          0 : static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_topology_mgr *mgr,
    2459                 :            :                                                                u8 lct, u8 *rad)
    2460                 :            : {
    2461                 :          0 :         struct drm_dp_mst_branch *mstb;
    2462                 :          0 :         struct drm_dp_mst_port *port;
    2463                 :          0 :         int i, ret;
    2464                 :            :         /* find the port by iterating down */
    2465                 :            : 
    2466                 :          0 :         mutex_lock(&mgr->lock);
    2467                 :          0 :         mstb = mgr->mst_primary;
    2468                 :            : 
    2469         [ #  # ]:          0 :         if (!mstb)
    2470                 :          0 :                 goto out;
    2471                 :            : 
    2472         [ #  # ]:          0 :         for (i = 0; i < lct - 1; i++) {
    2473         [ #  # ]:          0 :                 int shift = (i % 2) ? 0 : 4;
    2474                 :          0 :                 int port_num = (rad[i / 2] >> shift) & 0xf;
    2475                 :            : 
    2476         [ #  # ]:          0 :                 list_for_each_entry(port, &mstb->ports, next) {
    2477         [ #  # ]:          0 :                         if (port->port_num == port_num) {
    2478                 :          0 :                                 mstb = port->mstb;
    2479         [ #  # ]:          0 :                                 if (!mstb) {
    2480                 :          0 :                                         DRM_ERROR("failed to lookup MSTB with lct %d, rad %02x\n", lct, rad[0]);
    2481                 :          0 :                                         goto out;
    2482                 :            :                                 }
    2483                 :            : 
    2484                 :            :                                 break;
    2485                 :            :                         }
    2486                 :            :                 }
    2487                 :            :         }
    2488                 :          0 :         ret = drm_dp_mst_topology_try_get_mstb(mstb);
    2489         [ #  # ]:          0 :         if (!ret)
    2490                 :          0 :                 mstb = NULL;
    2491                 :          0 : out:
    2492                 :          0 :         mutex_unlock(&mgr->lock);
    2493                 :          0 :         return mstb;
    2494                 :            : }
    2495                 :            : 
    2496                 :          0 : static struct drm_dp_mst_branch *get_mst_branch_device_by_guid_helper(
    2497                 :            :         struct drm_dp_mst_branch *mstb,
    2498                 :            :         const uint8_t *guid)
    2499                 :            : {
    2500                 :          0 :         struct drm_dp_mst_branch *found_mstb;
    2501                 :          0 :         struct drm_dp_mst_port *port;
    2502                 :            : 
    2503         [ #  # ]:          0 :         if (memcmp(mstb->guid, guid, 16) == 0)
    2504                 :            :                 return mstb;
    2505                 :            : 
    2506                 :            : 
    2507         [ #  # ]:          0 :         list_for_each_entry(port, &mstb->ports, next) {
    2508         [ #  # ]:          0 :                 if (!port->mstb)
    2509                 :          0 :                         continue;
    2510                 :            : 
    2511                 :          0 :                 found_mstb = get_mst_branch_device_by_guid_helper(port->mstb, guid);
    2512                 :            : 
    2513         [ #  # ]:          0 :                 if (found_mstb)
    2514                 :          0 :                         return found_mstb;
    2515                 :            :         }
    2516                 :            : 
    2517                 :            :         return NULL;
    2518                 :            : }
    2519                 :            : 
    2520                 :            : static struct drm_dp_mst_branch *
    2521                 :          0 : drm_dp_get_mst_branch_device_by_guid(struct drm_dp_mst_topology_mgr *mgr,
    2522                 :            :                                      const uint8_t *guid)
    2523                 :            : {
    2524                 :          0 :         struct drm_dp_mst_branch *mstb;
    2525                 :          0 :         int ret;
    2526                 :            : 
    2527                 :            :         /* find the port by iterating down */
    2528                 :          0 :         mutex_lock(&mgr->lock);
    2529                 :            : 
    2530                 :          0 :         mstb = get_mst_branch_device_by_guid_helper(mgr->mst_primary, guid);
    2531         [ #  # ]:          0 :         if (mstb) {
    2532                 :          0 :                 ret = drm_dp_mst_topology_try_get_mstb(mstb);
    2533         [ #  # ]:          0 :                 if (!ret)
    2534                 :          0 :                         mstb = NULL;
    2535                 :            :         }
    2536                 :            : 
    2537                 :          0 :         mutex_unlock(&mgr->lock);
    2538                 :          0 :         return mstb;
    2539                 :            : }
    2540                 :            : 
    2541                 :          0 : static int drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
    2542                 :            :                                                struct drm_dp_mst_branch *mstb)
    2543                 :            : {
    2544                 :          0 :         struct drm_dp_mst_port *port;
    2545                 :          0 :         int ret;
    2546                 :          0 :         bool changed = false;
    2547                 :            : 
    2548         [ #  # ]:          0 :         if (!mstb->link_address_sent) {
    2549                 :          0 :                 ret = drm_dp_send_link_address(mgr, mstb);
    2550         [ #  # ]:          0 :                 if (ret == 1)
    2551                 :            :                         changed = true;
    2552         [ #  # ]:          0 :                 else if (ret < 0)
    2553                 :            :                         return ret;
    2554                 :            :         }
    2555                 :            : 
    2556         [ #  # ]:          0 :         list_for_each_entry(port, &mstb->ports, next) {
    2557                 :          0 :                 struct drm_dp_mst_branch *mstb_child = NULL;
    2558                 :            : 
    2559   [ #  #  #  # ]:          0 :                 if (port->input || !port->ddps)
    2560                 :          0 :                         continue;
    2561                 :            : 
    2562         [ #  # ]:          0 :                 if (port->mstb)
    2563                 :          0 :                         mstb_child = drm_dp_mst_topology_get_mstb_validated(
    2564                 :            :                             mgr, port->mstb);
    2565                 :            : 
    2566         [ #  # ]:          0 :                 if (mstb_child) {
    2567                 :          0 :                         ret = drm_dp_check_and_send_link_address(mgr,
    2568                 :            :                                                                  mstb_child);
    2569                 :          0 :                         drm_dp_mst_topology_put_mstb(mstb_child);
    2570         [ #  # ]:          0 :                         if (ret == 1)
    2571                 :            :                                 changed = true;
    2572         [ #  # ]:          0 :                         else if (ret < 0)
    2573                 :          0 :                                 return ret;
    2574                 :            :                 }
    2575                 :            :         }
    2576                 :            : 
    2577                 :          0 :         return changed;
    2578                 :            : }
    2579                 :            : 
    2580                 :          0 : static void drm_dp_mst_link_probe_work(struct work_struct *work)
    2581                 :            : {
    2582                 :          0 :         struct drm_dp_mst_topology_mgr *mgr =
    2583                 :          0 :                 container_of(work, struct drm_dp_mst_topology_mgr, work);
    2584                 :          0 :         struct drm_device *dev = mgr->dev;
    2585                 :          0 :         struct drm_dp_mst_branch *mstb;
    2586                 :          0 :         int ret;
    2587                 :          0 :         bool clear_payload_id_table;
    2588                 :            : 
    2589                 :          0 :         mutex_lock(&mgr->probe_lock);
    2590                 :            : 
    2591                 :          0 :         mutex_lock(&mgr->lock);
    2592                 :          0 :         clear_payload_id_table = !mgr->payload_id_table_cleared;
    2593                 :          0 :         mgr->payload_id_table_cleared = true;
    2594                 :            : 
    2595                 :          0 :         mstb = mgr->mst_primary;
    2596         [ #  # ]:          0 :         if (mstb) {
    2597                 :          0 :                 ret = drm_dp_mst_topology_try_get_mstb(mstb);
    2598         [ #  # ]:          0 :                 if (!ret)
    2599                 :          0 :                         mstb = NULL;
    2600                 :            :         }
    2601                 :          0 :         mutex_unlock(&mgr->lock);
    2602         [ #  # ]:          0 :         if (!mstb) {
    2603                 :          0 :                 mutex_unlock(&mgr->probe_lock);
    2604                 :          0 :                 return;
    2605                 :            :         }
    2606                 :            : 
    2607                 :            :         /*
    2608                 :            :          * Certain branch devices seem to incorrectly report an available_pbn
    2609                 :            :          * of 0 on downstream sinks, even after clearing the
    2610                 :            :          * DP_PAYLOAD_ALLOCATE_* registers in
    2611                 :            :          * drm_dp_mst_topology_mgr_set_mst(). Namely, the CableMatters USB-C
    2612                 :            :          * 2x DP hub. Sending a CLEAR_PAYLOAD_ID_TABLE message seems to make
    2613                 :            :          * things work again.
    2614                 :            :          */
    2615         [ #  # ]:          0 :         if (clear_payload_id_table) {
    2616                 :          0 :                 DRM_DEBUG_KMS("Clearing payload ID table\n");
    2617                 :          0 :                 drm_dp_send_clear_payload_id_table(mgr, mstb);
    2618                 :            :         }
    2619                 :            : 
    2620                 :          0 :         ret = drm_dp_check_and_send_link_address(mgr, mstb);
    2621                 :          0 :         drm_dp_mst_topology_put_mstb(mstb);
    2622                 :            : 
    2623                 :          0 :         mutex_unlock(&mgr->probe_lock);
    2624         [ #  # ]:          0 :         if (ret)
    2625                 :          0 :                 drm_kms_helper_hotplug_event(dev);
    2626                 :            : }
    2627                 :            : 
    2628                 :          0 : static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr,
    2629                 :            :                                  u8 *guid)
    2630                 :            : {
    2631                 :          0 :         u64 salt;
    2632                 :            : 
    2633         [ #  # ]:          0 :         if (memchr_inv(guid, 0, 16))
    2634                 :            :                 return true;
    2635                 :            : 
    2636         [ #  # ]:          0 :         salt = get_jiffies_64();
    2637                 :            : 
    2638                 :          0 :         memcpy(&guid[0], &salt, sizeof(u64));
    2639                 :          0 :         memcpy(&guid[8], &salt, sizeof(u64));
    2640                 :            : 
    2641         [ #  # ]:          0 :         return false;
    2642                 :            : }
    2643                 :            : 
    2644                 :          0 : static int build_dpcd_read(struct drm_dp_sideband_msg_tx *msg, u8 port_num, u32 offset, u8 num_bytes)
    2645                 :            : {
    2646                 :          0 :         struct drm_dp_sideband_msg_req_body req;
    2647                 :            : 
    2648                 :          0 :         req.req_type = DP_REMOTE_DPCD_READ;
    2649                 :          0 :         req.u.dpcd_read.port_number = port_num;
    2650                 :          0 :         req.u.dpcd_read.dpcd_address = offset;
    2651                 :          0 :         req.u.dpcd_read.num_bytes = num_bytes;
    2652                 :          0 :         drm_dp_encode_sideband_req(&req, msg);
    2653                 :            : 
    2654                 :          0 :         return 0;
    2655                 :            : }
    2656                 :            : 
    2657                 :          0 : static int drm_dp_send_sideband_msg(struct drm_dp_mst_topology_mgr *mgr,
    2658                 :            :                                     bool up, u8 *msg, int len)
    2659                 :            : {
    2660                 :          0 :         int ret;
    2661         [ #  # ]:          0 :         int regbase = up ? DP_SIDEBAND_MSG_UP_REP_BASE : DP_SIDEBAND_MSG_DOWN_REQ_BASE;
    2662                 :          0 :         int tosend, total, offset;
    2663                 :          0 :         int retries = 0;
    2664                 :            : 
    2665                 :          0 : retry:
    2666                 :          0 :         total = len;
    2667                 :          0 :         offset = 0;
    2668                 :          0 :         do {
    2669                 :          0 :                 tosend = min3(mgr->max_dpcd_transaction_bytes, 16, total);
    2670                 :            : 
    2671                 :          0 :                 ret = drm_dp_dpcd_write(mgr->aux, regbase + offset,
    2672                 :          0 :                                         &msg[offset],
    2673                 :            :                                         tosend);
    2674         [ #  # ]:          0 :                 if (ret != tosend) {
    2675         [ #  # ]:          0 :                         if (ret == -EIO && retries < 5) {
    2676                 :          0 :                                 retries++;
    2677                 :          0 :                                 goto retry;
    2678                 :            :                         }
    2679                 :          0 :                         DRM_DEBUG_KMS("failed to dpcd write %d %d\n", tosend, ret);
    2680                 :            : 
    2681                 :          0 :                         return -EIO;
    2682                 :            :                 }
    2683                 :          0 :                 offset += tosend;
    2684                 :          0 :                 total -= tosend;
    2685         [ #  # ]:          0 :         } while (total > 0);
    2686                 :            :         return 0;
    2687                 :            : }
    2688                 :            : 
    2689                 :          0 : static int set_hdr_from_dst_qlock(struct drm_dp_sideband_msg_hdr *hdr,
    2690                 :            :                                   struct drm_dp_sideband_msg_tx *txmsg)
    2691                 :            : {
    2692                 :          0 :         struct drm_dp_mst_branch *mstb = txmsg->dst;
    2693                 :          0 :         u8 req_type;
    2694                 :            : 
    2695                 :            :         /* both msg slots are full */
    2696         [ #  # ]:          0 :         if (txmsg->seqno == -1) {
    2697   [ #  #  #  # ]:          0 :                 if (mstb->tx_slots[0] && mstb->tx_slots[1]) {
    2698                 :          0 :                         DRM_DEBUG_KMS("%s: failed to find slot\n", __func__);
    2699                 :          0 :                         return -EAGAIN;
    2700                 :            :                 }
    2701   [ #  #  #  # ]:          0 :                 if (mstb->tx_slots[0] == NULL && mstb->tx_slots[1] == NULL) {
    2702                 :          0 :                         txmsg->seqno = mstb->last_seqno;
    2703                 :          0 :                         mstb->last_seqno ^= 1;
    2704         [ #  # ]:          0 :                 } else if (mstb->tx_slots[0] == NULL)
    2705                 :          0 :                         txmsg->seqno = 0;
    2706                 :            :                 else
    2707                 :          0 :                         txmsg->seqno = 1;
    2708                 :          0 :                 mstb->tx_slots[txmsg->seqno] = txmsg;
    2709                 :            :         }
    2710                 :            : 
    2711                 :          0 :         req_type = txmsg->msg[0] & 0x7f;
    2712                 :          0 :         if (req_type == DP_CONNECTION_STATUS_NOTIFY ||
    2713         [ #  # ]:          0 :                 req_type == DP_RESOURCE_STATUS_NOTIFY)
    2714                 :          0 :                 hdr->broadcast = 1;
    2715                 :            :         else
    2716                 :          0 :                 hdr->broadcast = 0;
    2717                 :          0 :         hdr->path_msg = txmsg->path_msg;
    2718                 :          0 :         hdr->lct = mstb->lct;
    2719                 :          0 :         hdr->lcr = mstb->lct - 1;
    2720         [ #  # ]:          0 :         if (mstb->lct > 1)
    2721                 :          0 :                 memcpy(hdr->rad, mstb->rad, mstb->lct / 2);
    2722                 :          0 :         hdr->seqno = txmsg->seqno;
    2723                 :          0 :         return 0;
    2724                 :            : }
    2725                 :            : /*
    2726                 :            :  * process a single block of the next message in the sideband queue
    2727                 :            :  */
    2728                 :          0 : static int process_single_tx_qlock(struct drm_dp_mst_topology_mgr *mgr,
    2729                 :            :                                    struct drm_dp_sideband_msg_tx *txmsg,
    2730                 :            :                                    bool up)
    2731                 :            : {
    2732                 :          0 :         u8 chunk[48];
    2733                 :          0 :         struct drm_dp_sideband_msg_hdr hdr;
    2734                 :          0 :         int len, space, idx, tosend;
    2735                 :          0 :         int ret;
    2736                 :            : 
    2737                 :          0 :         memset(&hdr, 0, sizeof(struct drm_dp_sideband_msg_hdr));
    2738                 :            : 
    2739         [ #  # ]:          0 :         if (txmsg->state == DRM_DP_SIDEBAND_TX_QUEUED) {
    2740                 :          0 :                 txmsg->seqno = -1;
    2741                 :          0 :                 txmsg->state = DRM_DP_SIDEBAND_TX_START_SEND;
    2742                 :            :         }
    2743                 :            : 
    2744                 :            :         /* make hdr from dst mst - for replies use seqno
    2745                 :            :            otherwise assign one */
    2746                 :          0 :         ret = set_hdr_from_dst_qlock(&hdr, txmsg);
    2747         [ #  # ]:          0 :         if (ret < 0)
    2748                 :            :                 return ret;
    2749                 :            : 
    2750                 :            :         /* amount left to send in this message */
    2751                 :          0 :         len = txmsg->cur_len - txmsg->cur_offset;
    2752                 :            : 
    2753                 :            :         /* 48 - sideband msg size - 1 byte for data CRC, x header bytes */
    2754                 :          0 :         space = 48 - 1 - drm_dp_calc_sb_hdr_size(&hdr);
    2755                 :            : 
    2756                 :          0 :         tosend = min(len, space);
    2757         [ #  # ]:          0 :         if (len == txmsg->cur_len)
    2758                 :          0 :                 hdr.somt = 1;
    2759         [ #  # ]:          0 :         if (space >= len)
    2760                 :          0 :                 hdr.eomt = 1;
    2761                 :            : 
    2762                 :            : 
    2763                 :          0 :         hdr.msg_len = tosend + 1;
    2764                 :          0 :         drm_dp_encode_sideband_msg_hdr(&hdr, chunk, &idx);
    2765                 :          0 :         memcpy(&chunk[idx], &txmsg->msg[txmsg->cur_offset], tosend);
    2766                 :            :         /* add crc at end */
    2767                 :          0 :         drm_dp_crc_sideband_chunk_req(&chunk[idx], tosend);
    2768                 :          0 :         idx += tosend + 1;
    2769                 :            : 
    2770                 :          0 :         ret = drm_dp_send_sideband_msg(mgr, up, chunk, idx);
    2771   [ #  #  #  # ]:          0 :         if (unlikely(ret) && drm_debug_enabled(DRM_UT_DP)) {
    2772                 :          0 :                 struct drm_printer p = drm_debug_printer(DBG_PREFIX);
    2773                 :            : 
    2774                 :          0 :                 drm_printf(&p, "sideband msg failed to send\n");
    2775                 :          0 :                 drm_dp_mst_dump_sideband_msg_tx(&p, txmsg);
    2776                 :          0 :                 return ret;
    2777                 :            :         }
    2778                 :            : 
    2779                 :          0 :         txmsg->cur_offset += tosend;
    2780         [ #  # ]:          0 :         if (txmsg->cur_offset == txmsg->cur_len) {
    2781                 :          0 :                 txmsg->state = DRM_DP_SIDEBAND_TX_SENT;
    2782                 :          0 :                 return 1;
    2783                 :            :         }
    2784                 :            :         return 0;
    2785                 :            : }
    2786                 :            : 
    2787                 :          0 : static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr)
    2788                 :            : {
    2789                 :          0 :         struct drm_dp_sideband_msg_tx *txmsg;
    2790                 :          0 :         int ret;
    2791                 :            : 
    2792         [ #  # ]:          0 :         WARN_ON(!mutex_is_locked(&mgr->qlock));
    2793                 :            : 
    2794                 :            :         /* construct a chunk from the first msg in the tx_msg queue */
    2795         [ #  # ]:          0 :         if (list_empty(&mgr->tx_msg_downq))
    2796                 :            :                 return;
    2797                 :            : 
    2798                 :          0 :         txmsg = list_first_entry(&mgr->tx_msg_downq, struct drm_dp_sideband_msg_tx, next);
    2799                 :          0 :         ret = process_single_tx_qlock(mgr, txmsg, false);
    2800         [ #  # ]:          0 :         if (ret == 1) {
    2801                 :            :                 /* txmsg is sent it should be in the slots now */
    2802                 :          0 :                 mgr->is_waiting_for_dwn_reply = true;
    2803                 :          0 :                 list_del(&txmsg->next);
    2804         [ #  # ]:          0 :         } else if (ret) {
    2805                 :          0 :                 DRM_DEBUG_KMS("failed to send msg in q %d\n", ret);
    2806                 :          0 :                 mgr->is_waiting_for_dwn_reply = false;
    2807         [ #  # ]:          0 :                 list_del(&txmsg->next);
    2808         [ #  # ]:          0 :                 if (txmsg->seqno != -1)
    2809                 :          0 :                         txmsg->dst->tx_slots[txmsg->seqno] = NULL;
    2810                 :          0 :                 txmsg->state = DRM_DP_SIDEBAND_TX_TIMEOUT;
    2811                 :          0 :                 wake_up_all(&mgr->tx_waitq);
    2812                 :            :         }
    2813                 :            : }
    2814                 :            : 
    2815                 :            : /* called holding qlock */
    2816                 :          0 : static void process_single_up_tx_qlock(struct drm_dp_mst_topology_mgr *mgr,
    2817                 :            :                                        struct drm_dp_sideband_msg_tx *txmsg)
    2818                 :            : {
    2819                 :          0 :         int ret;
    2820                 :            : 
    2821                 :            :         /* construct a chunk from the first msg in the tx_msg queue */
    2822                 :          0 :         ret = process_single_tx_qlock(mgr, txmsg, true);
    2823                 :            : 
    2824         [ #  # ]:          0 :         if (ret != 1)
    2825                 :          0 :                 DRM_DEBUG_KMS("failed to send msg in q %d\n", ret);
    2826                 :            : 
    2827         [ #  # ]:          0 :         if (txmsg->seqno != -1) {
    2828         [ #  # ]:          0 :                 WARN_ON((unsigned int)txmsg->seqno >
    2829                 :            :                         ARRAY_SIZE(txmsg->dst->tx_slots));
    2830                 :          0 :                 txmsg->dst->tx_slots[txmsg->seqno] = NULL;
    2831                 :            :         }
    2832                 :          0 : }
    2833                 :            : 
    2834                 :          0 : static void drm_dp_queue_down_tx(struct drm_dp_mst_topology_mgr *mgr,
    2835                 :            :                                  struct drm_dp_sideband_msg_tx *txmsg)
    2836                 :            : {
    2837                 :          0 :         mutex_lock(&mgr->qlock);
    2838         [ #  # ]:          0 :         list_add_tail(&txmsg->next, &mgr->tx_msg_downq);
    2839                 :            : 
    2840         [ #  # ]:          0 :         if (drm_debug_enabled(DRM_UT_DP)) {
    2841                 :          0 :                 struct drm_printer p = drm_debug_printer(DBG_PREFIX);
    2842                 :            : 
    2843                 :          0 :                 drm_dp_mst_dump_sideband_msg_tx(&p, txmsg);
    2844                 :            :         }
    2845                 :            : 
    2846         [ #  # ]:          0 :         if (list_is_singular(&mgr->tx_msg_downq) &&
    2847         [ #  # ]:          0 :             !mgr->is_waiting_for_dwn_reply)
    2848                 :          0 :                 process_single_down_tx_qlock(mgr);
    2849                 :          0 :         mutex_unlock(&mgr->qlock);
    2850                 :          0 : }
    2851                 :            : 
    2852                 :            : static void
    2853                 :          0 : drm_dp_dump_link_address(struct drm_dp_link_address_ack_reply *reply)
    2854                 :            : {
    2855                 :          0 :         struct drm_dp_link_addr_reply_port *port_reply;
    2856                 :          0 :         int i;
    2857                 :            : 
    2858         [ #  # ]:          0 :         for (i = 0; i < reply->nports; i++) {
    2859                 :          0 :                 port_reply = &reply->ports[i];
    2860                 :          0 :                 DRM_DEBUG_KMS("port %d: input %d, pdt: %d, pn: %d, dpcd_rev: %02x, mcs: %d, ddps: %d, ldps %d, sdp %d/%d\n",
    2861                 :            :                               i,
    2862                 :            :                               port_reply->input_port,
    2863                 :            :                               port_reply->peer_device_type,
    2864                 :            :                               port_reply->port_number,
    2865                 :            :                               port_reply->dpcd_revision,
    2866                 :            :                               port_reply->mcs,
    2867                 :            :                               port_reply->ddps,
    2868                 :            :                               port_reply->legacy_device_plug_status,
    2869                 :            :                               port_reply->num_sdp_streams,
    2870                 :            :                               port_reply->num_sdp_stream_sinks);
    2871                 :            :         }
    2872                 :          0 : }
    2873                 :            : 
    2874                 :          0 : static int drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
    2875                 :            :                                      struct drm_dp_mst_branch *mstb)
    2876                 :            : {
    2877                 :          0 :         struct drm_dp_sideband_msg_tx *txmsg;
    2878                 :          0 :         struct drm_dp_link_address_ack_reply *reply;
    2879                 :          0 :         struct drm_dp_mst_port *port, *tmp;
    2880                 :          0 :         int i, len, ret, port_mask = 0;
    2881                 :          0 :         bool changed = false;
    2882                 :            : 
    2883                 :          0 :         txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
    2884         [ #  # ]:          0 :         if (!txmsg)
    2885                 :            :                 return -ENOMEM;
    2886                 :            : 
    2887                 :          0 :         txmsg->dst = mstb;
    2888                 :          0 :         len = build_link_address(txmsg);
    2889                 :            : 
    2890                 :          0 :         mstb->link_address_sent = true;
    2891                 :          0 :         drm_dp_queue_down_tx(mgr, txmsg);
    2892                 :            : 
    2893                 :            :         /* FIXME: Actually do some real error handling here */
    2894                 :          0 :         ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
    2895         [ #  # ]:          0 :         if (ret <= 0) {
    2896                 :          0 :                 DRM_ERROR("Sending link address failed with %d\n", ret);
    2897                 :          0 :                 goto out;
    2898                 :            :         }
    2899         [ #  # ]:          0 :         if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
    2900                 :          0 :                 DRM_ERROR("link address NAK received\n");
    2901                 :          0 :                 ret = -EIO;
    2902                 :          0 :                 goto out;
    2903                 :            :         }
    2904                 :            : 
    2905                 :          0 :         reply = &txmsg->reply.u.link_addr;
    2906                 :          0 :         DRM_DEBUG_KMS("link address reply: %d\n", reply->nports);
    2907                 :          0 :         drm_dp_dump_link_address(reply);
    2908                 :            : 
    2909                 :          0 :         drm_dp_check_mstb_guid(mstb, reply->guid);
    2910                 :            : 
    2911         [ #  # ]:          0 :         for (i = 0; i < reply->nports; i++) {
    2912                 :          0 :                 port_mask |= BIT(reply->ports[i].port_number);
    2913                 :          0 :                 ret = drm_dp_mst_handle_link_address_port(mstb, mgr->dev,
    2914                 :            :                                                           &reply->ports[i]);
    2915         [ #  # ]:          0 :                 if (ret == 1)
    2916                 :            :                         changed = true;
    2917         [ #  # ]:          0 :                 else if (ret < 0)
    2918                 :          0 :                         goto out;
    2919                 :            :         }
    2920                 :            : 
    2921                 :            :         /* Prune any ports that are currently a part of mstb in our in-memory
    2922                 :            :          * topology, but were not seen in this link address. Usually this
    2923                 :            :          * means that they were removed while the topology was out of sync,
    2924                 :            :          * e.g. during suspend/resume
    2925                 :            :          */
    2926                 :          0 :         mutex_lock(&mgr->lock);
    2927         [ #  # ]:          0 :         list_for_each_entry_safe(port, tmp, &mstb->ports, next) {
    2928         [ #  # ]:          0 :                 if (port_mask & BIT(port->port_num))
    2929                 :          0 :                         continue;
    2930                 :            : 
    2931                 :          0 :                 DRM_DEBUG_KMS("port %d was not in link address, removing\n",
    2932                 :            :                               port->port_num);
    2933                 :          0 :                 list_del(&port->next);
    2934                 :          0 :                 drm_dp_mst_topology_put_port(port);
    2935                 :          0 :                 changed = true;
    2936                 :            :         }
    2937                 :          0 :         mutex_unlock(&mgr->lock);
    2938                 :            : 
    2939                 :          0 : out:
    2940         [ #  # ]:          0 :         if (ret <= 0)
    2941                 :          0 :                 mstb->link_address_sent = false;
    2942                 :          0 :         kfree(txmsg);
    2943         [ #  # ]:          0 :         return ret < 0 ? ret : changed;
    2944                 :            : }
    2945                 :            : 
    2946                 :          0 : void drm_dp_send_clear_payload_id_table(struct drm_dp_mst_topology_mgr *mgr,
    2947                 :            :                                         struct drm_dp_mst_branch *mstb)
    2948                 :            : {
    2949                 :          0 :         struct drm_dp_sideband_msg_tx *txmsg;
    2950                 :          0 :         int len, ret;
    2951                 :            : 
    2952                 :          0 :         txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
    2953         [ #  # ]:          0 :         if (!txmsg)
    2954                 :            :                 return;
    2955                 :            : 
    2956                 :          0 :         txmsg->dst = mstb;
    2957                 :          0 :         len = build_clear_payload_id_table(txmsg);
    2958                 :            : 
    2959                 :          0 :         drm_dp_queue_down_tx(mgr, txmsg);
    2960                 :            : 
    2961                 :          0 :         ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
    2962   [ #  #  #  # ]:          0 :         if (ret > 0 && txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK)
    2963                 :          0 :                 DRM_DEBUG_KMS("clear payload table id nak received\n");
    2964                 :            : 
    2965                 :          0 :         kfree(txmsg);
    2966                 :            : }
    2967                 :            : 
    2968                 :            : static int
    2969                 :          0 : drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr,
    2970                 :            :                                 struct drm_dp_mst_branch *mstb,
    2971                 :            :                                 struct drm_dp_mst_port *port)
    2972                 :            : {
    2973                 :          0 :         struct drm_dp_enum_path_resources_ack_reply *path_res;
    2974                 :          0 :         struct drm_dp_sideband_msg_tx *txmsg;
    2975                 :          0 :         int len;
    2976                 :          0 :         int ret;
    2977                 :            : 
    2978                 :          0 :         txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
    2979         [ #  # ]:          0 :         if (!txmsg)
    2980                 :            :                 return -ENOMEM;
    2981                 :            : 
    2982                 :          0 :         txmsg->dst = mstb;
    2983                 :          0 :         len = build_enum_path_resources(txmsg, port->port_num);
    2984                 :            : 
    2985                 :          0 :         drm_dp_queue_down_tx(mgr, txmsg);
    2986                 :            : 
    2987                 :          0 :         ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
    2988         [ #  # ]:          0 :         if (ret > 0) {
    2989                 :          0 :                 ret = 0;
    2990                 :          0 :                 path_res = &txmsg->reply.u.path_resources;
    2991                 :            : 
    2992         [ #  # ]:          0 :                 if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
    2993                 :          0 :                         DRM_DEBUG_KMS("enum path resources nak received\n");
    2994                 :            :                 } else {
    2995         [ #  # ]:          0 :                         if (port->port_num != path_res->port_number)
    2996                 :          0 :                                 DRM_ERROR("got incorrect port in response\n");
    2997                 :            : 
    2998                 :          0 :                         DRM_DEBUG_KMS("enum path resources %d: %d %d\n",
    2999                 :            :                                       path_res->port_number,
    3000                 :            :                                       path_res->full_payload_bw_number,
    3001                 :            :                                       path_res->avail_payload_bw_number);
    3002                 :            : 
    3003                 :            :                         /*
    3004                 :            :                          * If something changed, make sure we send a
    3005                 :            :                          * hotplug
    3006                 :            :                          */
    3007         [ #  # ]:          0 :                         if (port->full_pbn != path_res->full_payload_bw_number ||
    3008         [ #  # ]:          0 :                             port->fec_capable != path_res->fec_capable)
    3009                 :          0 :                                 ret = 1;
    3010                 :            : 
    3011                 :          0 :                         port->full_pbn = path_res->full_payload_bw_number;
    3012                 :          0 :                         port->fec_capable = path_res->fec_capable;
    3013                 :            :                 }
    3014                 :            :         }
    3015                 :            : 
    3016                 :          0 :         kfree(txmsg);
    3017                 :          0 :         return ret;
    3018                 :            : }
    3019                 :            : 
    3020                 :          0 : static struct drm_dp_mst_port *drm_dp_get_last_connected_port_to_mstb(struct drm_dp_mst_branch *mstb)
    3021                 :            : {
    3022         [ #  # ]:          0 :         if (!mstb->port_parent)
    3023                 :            :                 return NULL;
    3024                 :            : 
    3025         [ #  # ]:          0 :         if (mstb->port_parent->mstb != mstb)
    3026                 :            :                 return mstb->port_parent;
    3027                 :            : 
    3028                 :          0 :         return drm_dp_get_last_connected_port_to_mstb(mstb->port_parent->parent);
    3029                 :            : }
    3030                 :            : 
    3031                 :            : /*
    3032                 :            :  * Searches upwards in the topology starting from mstb to try to find the
    3033                 :            :  * closest available parent of mstb that's still connected to the rest of the
    3034                 :            :  * topology. This can be used in order to perform operations like releasing
    3035                 :            :  * payloads, where the branch device which owned the payload may no longer be
    3036                 :            :  * around and thus would require that the payload on the last living relative
    3037                 :            :  * be freed instead.
    3038                 :            :  */
    3039                 :            : static struct drm_dp_mst_branch *
    3040                 :          0 : drm_dp_get_last_connected_port_and_mstb(struct drm_dp_mst_topology_mgr *mgr,
    3041                 :            :                                         struct drm_dp_mst_branch *mstb,
    3042                 :            :                                         int *port_num)
    3043                 :            : {
    3044                 :          0 :         struct drm_dp_mst_branch *rmstb = NULL;
    3045                 :          0 :         struct drm_dp_mst_port *found_port;
    3046                 :            : 
    3047                 :          0 :         mutex_lock(&mgr->lock);
    3048         [ #  # ]:          0 :         if (!mgr->mst_primary)
    3049                 :          0 :                 goto out;
    3050                 :            : 
    3051                 :          0 :         do {
    3052                 :          0 :                 found_port = drm_dp_get_last_connected_port_to_mstb(mstb);
    3053         [ #  # ]:          0 :                 if (!found_port)
    3054                 :            :                         break;
    3055                 :            : 
    3056         [ #  # ]:          0 :                 if (drm_dp_mst_topology_try_get_mstb(found_port->parent)) {
    3057                 :          0 :                         rmstb = found_port->parent;
    3058                 :          0 :                         *port_num = found_port->port_num;
    3059                 :            :                 } else {
    3060                 :            :                         /* Search again, starting from this parent */
    3061                 :          0 :                         mstb = found_port->parent;
    3062                 :            :                 }
    3063         [ #  # ]:          0 :         } while (!rmstb);
    3064                 :          0 : out:
    3065                 :          0 :         mutex_unlock(&mgr->lock);
    3066                 :          0 :         return rmstb;
    3067                 :            : }
    3068                 :            : 
    3069                 :          0 : static int drm_dp_payload_send_msg(struct drm_dp_mst_topology_mgr *mgr,
    3070                 :            :                                    struct drm_dp_mst_port *port,
    3071                 :            :                                    int id,
    3072                 :            :                                    int pbn)
    3073                 :            : {
    3074                 :          0 :         struct drm_dp_sideband_msg_tx *txmsg;
    3075                 :          0 :         struct drm_dp_mst_branch *mstb;
    3076                 :          0 :         int len, ret, port_num;
    3077                 :          0 :         u8 sinks[DRM_DP_MAX_SDP_STREAMS];
    3078                 :          0 :         int i;
    3079                 :            : 
    3080                 :          0 :         port_num = port->port_num;
    3081                 :          0 :         mstb = drm_dp_mst_topology_get_mstb_validated(mgr, port->parent);
    3082         [ #  # ]:          0 :         if (!mstb) {
    3083                 :          0 :                 mstb = drm_dp_get_last_connected_port_and_mstb(mgr,
    3084                 :            :                                                                port->parent,
    3085                 :            :                                                                &port_num);
    3086                 :            : 
    3087         [ #  # ]:          0 :                 if (!mstb)
    3088                 :            :                         return -EINVAL;
    3089                 :            :         }
    3090                 :            : 
    3091                 :          0 :         txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
    3092         [ #  # ]:          0 :         if (!txmsg) {
    3093                 :          0 :                 ret = -ENOMEM;
    3094                 :          0 :                 goto fail_put;
    3095                 :            :         }
    3096                 :            : 
    3097         [ #  # ]:          0 :         for (i = 0; i < port->num_sdp_streams; i++)
    3098                 :          0 :                 sinks[i] = i;
    3099                 :            : 
    3100                 :          0 :         txmsg->dst = mstb;
    3101                 :          0 :         len = build_allocate_payload(txmsg, port_num,
    3102                 :            :                                      id,
    3103                 :          0 :                                      pbn, port->num_sdp_streams, sinks);
    3104                 :            : 
    3105                 :          0 :         drm_dp_queue_down_tx(mgr, txmsg);
    3106                 :            : 
    3107                 :            :         /*
    3108                 :            :          * FIXME: there is a small chance that between getting the last
    3109                 :            :          * connected mstb and sending the payload message, the last connected
    3110                 :            :          * mstb could also be removed from the topology. In the future, this
    3111                 :            :          * needs to be fixed by restarting the
    3112                 :            :          * drm_dp_get_last_connected_port_and_mstb() search in the event of a
    3113                 :            :          * timeout if the topology is still connected to the system.
    3114                 :            :          */
    3115                 :          0 :         ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
    3116         [ #  # ]:          0 :         if (ret > 0) {
    3117         [ #  # ]:          0 :                 if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK)
    3118                 :            :                         ret = -EINVAL;
    3119                 :            :                 else
    3120                 :          0 :                         ret = 0;
    3121                 :            :         }
    3122                 :          0 :         kfree(txmsg);
    3123                 :          0 : fail_put:
    3124                 :          0 :         drm_dp_mst_topology_put_mstb(mstb);
    3125                 :          0 :         return ret;
    3126                 :            : }
    3127                 :            : 
    3128                 :          0 : int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
    3129                 :            :                                  struct drm_dp_mst_port *port, bool power_up)
    3130                 :            : {
    3131                 :          0 :         struct drm_dp_sideband_msg_tx *txmsg;
    3132                 :          0 :         int len, ret;
    3133                 :            : 
    3134                 :          0 :         port = drm_dp_mst_topology_get_port_validated(mgr, port);
    3135         [ #  # ]:          0 :         if (!port)
    3136                 :            :                 return -EINVAL;
    3137                 :            : 
    3138                 :          0 :         txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
    3139         [ #  # ]:          0 :         if (!txmsg) {
    3140                 :          0 :                 drm_dp_mst_topology_put_port(port);
    3141                 :          0 :                 return -ENOMEM;
    3142                 :            :         }
    3143                 :            : 
    3144                 :          0 :         txmsg->dst = port->parent;
    3145                 :          0 :         len = build_power_updown_phy(txmsg, port->port_num, power_up);
    3146                 :          0 :         drm_dp_queue_down_tx(mgr, txmsg);
    3147                 :            : 
    3148                 :          0 :         ret = drm_dp_mst_wait_tx_reply(port->parent, txmsg);
    3149         [ #  # ]:          0 :         if (ret > 0) {
    3150         [ #  # ]:          0 :                 if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK)
    3151                 :            :                         ret = -EINVAL;
    3152                 :            :                 else
    3153                 :          0 :                         ret = 0;
    3154                 :            :         }
    3155                 :          0 :         kfree(txmsg);
    3156                 :          0 :         drm_dp_mst_topology_put_port(port);
    3157                 :            : 
    3158                 :          0 :         return ret;
    3159                 :            : }
    3160                 :            : EXPORT_SYMBOL(drm_dp_send_power_updown_phy);
    3161                 :            : 
    3162                 :          0 : static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
    3163                 :            :                                        int id,
    3164                 :            :                                        struct drm_dp_payload *payload)
    3165                 :            : {
    3166                 :          0 :         int ret;
    3167                 :            : 
    3168                 :          0 :         ret = drm_dp_dpcd_write_payload(mgr, id, payload);
    3169         [ #  # ]:          0 :         if (ret < 0) {
    3170                 :          0 :                 payload->payload_state = 0;
    3171                 :          0 :                 return ret;
    3172                 :            :         }
    3173                 :          0 :         payload->payload_state = DP_PAYLOAD_LOCAL;
    3174                 :          0 :         return 0;
    3175                 :            : }
    3176                 :            : 
    3177                 :          0 : static int drm_dp_create_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
    3178                 :            :                                        struct drm_dp_mst_port *port,
    3179                 :            :                                        int id,
    3180                 :            :                                        struct drm_dp_payload *payload)
    3181                 :            : {
    3182                 :          0 :         int ret;
    3183                 :          0 :         ret = drm_dp_payload_send_msg(mgr, port, id, port->vcpi.pbn);
    3184         [ #  # ]:          0 :         if (ret < 0)
    3185                 :            :                 return ret;
    3186                 :          0 :         payload->payload_state = DP_PAYLOAD_REMOTE;
    3187                 :          0 :         return ret;
    3188                 :            : }
    3189                 :            : 
    3190                 :          0 : static int drm_dp_destroy_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
    3191                 :            :                                         struct drm_dp_mst_port *port,
    3192                 :            :                                         int id,
    3193                 :            :                                         struct drm_dp_payload *payload)
    3194                 :            : {
    3195                 :          0 :         DRM_DEBUG_KMS("\n");
    3196                 :            :         /* it's okay for these to fail */
    3197         [ #  # ]:          0 :         if (port) {
    3198                 :          0 :                 drm_dp_payload_send_msg(mgr, port, id, 0);
    3199                 :            :         }
    3200                 :            : 
    3201                 :          0 :         drm_dp_dpcd_write_payload(mgr, id, payload);
    3202                 :          0 :         payload->payload_state = DP_PAYLOAD_DELETE_LOCAL;
    3203                 :          0 :         return 0;
    3204                 :            : }
    3205                 :            : 
    3206                 :          0 : static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
    3207                 :            :                                         int id,
    3208                 :            :                                         struct drm_dp_payload *payload)
    3209                 :            : {
    3210                 :          0 :         payload->payload_state = 0;
    3211                 :          0 :         return 0;
    3212                 :            : }
    3213                 :            : 
    3214                 :            : /**
    3215                 :            :  * drm_dp_update_payload_part1() - Execute payload update part 1
    3216                 :            :  * @mgr: manager to use.
    3217                 :            :  *
    3218                 :            :  * This iterates over all proposed virtual channels, and tries to
    3219                 :            :  * allocate space in the link for them. For 0->slots transitions,
    3220                 :            :  * this step just writes the VCPI to the MST device. For slots->0
    3221                 :            :  * transitions, this writes the updated VCPIs and removes the
    3222                 :            :  * remote VC payloads.
    3223                 :            :  *
    3224                 :            :  * after calling this the driver should generate ACT and payload
    3225                 :            :  * packets.
    3226                 :            :  */
    3227                 :          0 : int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
    3228                 :            : {
    3229                 :          0 :         struct drm_dp_payload req_payload;
    3230                 :          0 :         struct drm_dp_mst_port *port;
    3231                 :          0 :         int i, j;
    3232                 :          0 :         int cur_slots = 1;
    3233                 :            : 
    3234                 :          0 :         mutex_lock(&mgr->payload_lock);
    3235         [ #  # ]:          0 :         for (i = 0; i < mgr->max_payloads; i++) {
    3236                 :          0 :                 struct drm_dp_vcpi *vcpi = mgr->proposed_vcpis[i];
    3237                 :          0 :                 struct drm_dp_payload *payload = &mgr->payloads[i];
    3238                 :          0 :                 bool put_port = false;
    3239                 :            : 
    3240                 :            :                 /* solve the current payloads - compare to the hw ones
    3241                 :            :                    - update the hw view */
    3242                 :          0 :                 req_payload.start_slot = cur_slots;
    3243         [ #  # ]:          0 :                 if (vcpi) {
    3244                 :          0 :                         port = container_of(vcpi, struct drm_dp_mst_port,
    3245                 :            :                                             vcpi);
    3246                 :            : 
    3247                 :            :                         /* Validated ports don't matter if we're releasing
    3248                 :            :                          * VCPI
    3249                 :            :                          */
    3250         [ #  # ]:          0 :                         if (vcpi->num_slots) {
    3251                 :          0 :                                 port = drm_dp_mst_topology_get_port_validated(
    3252                 :            :                                     mgr, port);
    3253         [ #  # ]:          0 :                                 if (!port) {
    3254                 :          0 :                                         mutex_unlock(&mgr->payload_lock);
    3255                 :          0 :                                         return -EINVAL;
    3256                 :            :                                 }
    3257                 :            :                                 put_port = true;
    3258                 :            :                         }
    3259                 :            : 
    3260                 :          0 :                         req_payload.num_slots = vcpi->num_slots;
    3261                 :          0 :                         req_payload.vcpi = vcpi->vcpi;
    3262                 :            :                 } else {
    3263                 :          0 :                         port = NULL;
    3264                 :          0 :                         req_payload.num_slots = 0;
    3265                 :            :                 }
    3266                 :            : 
    3267                 :          0 :                 payload->start_slot = req_payload.start_slot;
    3268                 :            :                 /* work out what is required to happen with this payload */
    3269         [ #  # ]:          0 :                 if (payload->num_slots != req_payload.num_slots) {
    3270                 :            : 
    3271                 :            :                         /* need to push an update for this payload */
    3272         [ #  # ]:          0 :                         if (req_payload.num_slots) {
    3273                 :          0 :                                 drm_dp_create_payload_step1(mgr, vcpi->vcpi,
    3274                 :            :                                                             &req_payload);
    3275                 :          0 :                                 payload->num_slots = req_payload.num_slots;
    3276                 :          0 :                                 payload->vcpi = req_payload.vcpi;
    3277                 :            : 
    3278         [ #  # ]:          0 :                         } else if (payload->num_slots) {
    3279                 :          0 :                                 payload->num_slots = 0;
    3280                 :          0 :                                 drm_dp_destroy_payload_step1(mgr, port,
    3281                 :            :                                                              payload->vcpi,
    3282                 :            :                                                              payload);
    3283                 :          0 :                                 req_payload.payload_state =
    3284                 :          0 :                                         payload->payload_state;
    3285                 :          0 :                                 payload->start_slot = 0;
    3286                 :            :                         }
    3287                 :          0 :                         payload->payload_state = req_payload.payload_state;
    3288                 :            :                 }
    3289                 :          0 :                 cur_slots += req_payload.num_slots;
    3290                 :            : 
    3291         [ #  # ]:          0 :                 if (put_port)
    3292                 :          0 :                         drm_dp_mst_topology_put_port(port);
    3293                 :            :         }
    3294                 :            : 
    3295         [ #  # ]:          0 :         for (i = 0; i < mgr->max_payloads; /* do nothing */) {
    3296         [ #  # ]:          0 :                 if (mgr->payloads[i].payload_state != DP_PAYLOAD_DELETE_LOCAL) {
    3297                 :          0 :                         i++;
    3298                 :          0 :                         continue;
    3299                 :            :                 }
    3300                 :            : 
    3301                 :          0 :                 DRM_DEBUG_KMS("removing payload %d\n", i);
    3302         [ #  # ]:          0 :                 for (j = i; j < mgr->max_payloads - 1; j++) {
    3303                 :          0 :                         mgr->payloads[j] = mgr->payloads[j + 1];
    3304                 :          0 :                         mgr->proposed_vcpis[j] = mgr->proposed_vcpis[j + 1];
    3305                 :            : 
    3306         [ #  # ]:          0 :                         if (mgr->proposed_vcpis[j] &&
    3307         [ #  # ]:          0 :                             mgr->proposed_vcpis[j]->num_slots) {
    3308                 :          0 :                                 set_bit(j + 1, &mgr->payload_mask);
    3309                 :            :                         } else {
    3310                 :          0 :                                 clear_bit(j + 1, &mgr->payload_mask);
    3311                 :            :                         }
    3312                 :            :                 }
    3313                 :            : 
    3314                 :          0 :                 memset(&mgr->payloads[mgr->max_payloads - 1], 0,
    3315                 :            :                        sizeof(struct drm_dp_payload));
    3316                 :          0 :                 mgr->proposed_vcpis[mgr->max_payloads - 1] = NULL;
    3317                 :          0 :                 clear_bit(mgr->max_payloads, &mgr->payload_mask);
    3318                 :            :         }
    3319                 :          0 :         mutex_unlock(&mgr->payload_lock);
    3320                 :            : 
    3321                 :          0 :         return 0;
    3322                 :            : }
    3323                 :            : EXPORT_SYMBOL(drm_dp_update_payload_part1);
    3324                 :            : 
    3325                 :            : /**
    3326                 :            :  * drm_dp_update_payload_part2() - Execute payload update part 2
    3327                 :            :  * @mgr: manager to use.
    3328                 :            :  *
    3329                 :            :  * This iterates over all proposed virtual channels, and tries to
    3330                 :            :  * allocate space in the link for them. For 0->slots transitions,
    3331                 :            :  * this step writes the remote VC payload commands. For slots->0
    3332                 :            :  * this just resets some internal state.
    3333                 :            :  */
    3334                 :          0 : int drm_dp_update_payload_part2(struct drm_dp_mst_topology_mgr *mgr)
    3335                 :            : {
    3336                 :          0 :         struct drm_dp_mst_port *port;
    3337                 :          0 :         int i;
    3338                 :          0 :         int ret = 0;
    3339                 :          0 :         mutex_lock(&mgr->payload_lock);
    3340         [ #  # ]:          0 :         for (i = 0; i < mgr->max_payloads; i++) {
    3341                 :            : 
    3342         [ #  # ]:          0 :                 if (!mgr->proposed_vcpis[i])
    3343                 :          0 :                         continue;
    3344                 :            : 
    3345                 :          0 :                 port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi);
    3346                 :            : 
    3347                 :          0 :                 DRM_DEBUG_KMS("payload %d %d\n", i, mgr->payloads[i].payload_state);
    3348         [ #  # ]:          0 :                 if (mgr->payloads[i].payload_state == DP_PAYLOAD_LOCAL) {
    3349                 :          0 :                         ret = drm_dp_create_payload_step2(mgr, port, mgr->proposed_vcpis[i]->vcpi, &mgr->payloads[i]);
    3350         [ #  # ]:          0 :                 } else if (mgr->payloads[i].payload_state == DP_PAYLOAD_DELETE_LOCAL) {
    3351                 :          0 :                         ret = drm_dp_destroy_payload_step2(mgr, mgr->proposed_vcpis[i]->vcpi, &mgr->payloads[i]);
    3352                 :            :                 }
    3353         [ #  # ]:          0 :                 if (ret) {
    3354                 :          0 :                         mutex_unlock(&mgr->payload_lock);
    3355                 :          0 :                         return ret;
    3356                 :            :                 }
    3357                 :            :         }
    3358                 :          0 :         mutex_unlock(&mgr->payload_lock);
    3359                 :          0 :         return 0;
    3360                 :            : }
    3361                 :            : EXPORT_SYMBOL(drm_dp_update_payload_part2);
    3362                 :            : 
    3363                 :            : static int drm_dp_send_dpcd_read(struct drm_dp_mst_topology_mgr *mgr,
    3364                 :            :                                  struct drm_dp_mst_port *port,
    3365                 :            :                                  int offset, int size, u8 *bytes)
    3366                 :            : {
    3367                 :            :         int len;
    3368                 :            :         int ret = 0;
    3369                 :            :         struct drm_dp_sideband_msg_tx *txmsg;
    3370                 :            :         struct drm_dp_mst_branch *mstb;
    3371                 :            : 
    3372                 :            :         mstb = drm_dp_mst_topology_get_mstb_validated(mgr, port->parent);
    3373                 :            :         if (!mstb)
    3374                 :            :                 return -EINVAL;
    3375                 :            : 
    3376                 :            :         txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
    3377                 :            :         if (!txmsg) {
    3378                 :            :                 ret = -ENOMEM;
    3379                 :            :                 goto fail_put;
    3380                 :            :         }
    3381                 :            : 
    3382                 :            :         len = build_dpcd_read(txmsg, port->port_num, offset, size);
    3383                 :            :         txmsg->dst = port->parent;
    3384                 :            : 
    3385                 :            :         drm_dp_queue_down_tx(mgr, txmsg);
    3386                 :            : 
    3387                 :            :         ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
    3388                 :            :         if (ret < 0)
    3389                 :            :                 goto fail_free;
    3390                 :            : 
    3391                 :            :         /* DPCD read should never be NACKed */
    3392                 :            :         if (txmsg->reply.reply_type == 1) {
    3393                 :            :                 DRM_ERROR("mstb %p port %d: DPCD read on addr 0x%x for %d bytes NAKed\n",
    3394                 :            :                           mstb, port->port_num, offset, size);
    3395                 :            :                 ret = -EIO;
    3396                 :            :                 goto fail_free;
    3397                 :            :         }
    3398                 :            : 
    3399                 :            :         if (txmsg->reply.u.remote_dpcd_read_ack.num_bytes != size) {
    3400                 :            :                 ret = -EPROTO;
    3401                 :            :                 goto fail_free;
    3402                 :            :         }
    3403                 :            : 
    3404                 :            :         ret = min_t(size_t, txmsg->reply.u.remote_dpcd_read_ack.num_bytes,
    3405                 :            :                     size);
    3406                 :            :         memcpy(bytes, txmsg->reply.u.remote_dpcd_read_ack.bytes, ret);
    3407                 :            : 
    3408                 :            : fail_free:
    3409                 :            :         kfree(txmsg);
    3410                 :            : fail_put:
    3411                 :            :         drm_dp_mst_topology_put_mstb(mstb);
    3412                 :            : 
    3413                 :            :         return ret;
    3414                 :            : }
    3415                 :            : 
    3416                 :            : static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr,
    3417                 :            :                                   struct drm_dp_mst_port *port,
    3418                 :            :                                   int offset, int size, u8 *bytes)
    3419                 :            : {
    3420                 :            :         int len;
    3421                 :            :         int ret;
    3422                 :            :         struct drm_dp_sideband_msg_tx *txmsg;
    3423                 :            :         struct drm_dp_mst_branch *mstb;
    3424                 :            : 
    3425                 :            :         mstb = drm_dp_mst_topology_get_mstb_validated(mgr, port->parent);
    3426                 :            :         if (!mstb)
    3427                 :            :                 return -EINVAL;
    3428                 :            : 
    3429                 :            :         txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
    3430                 :            :         if (!txmsg) {
    3431                 :            :                 ret = -ENOMEM;
    3432                 :            :                 goto fail_put;
    3433                 :            :         }
    3434                 :            : 
    3435                 :            :         len = build_dpcd_write(txmsg, port->port_num, offset, size, bytes);
    3436                 :            :         txmsg->dst = mstb;
    3437                 :            : 
    3438                 :            :         drm_dp_queue_down_tx(mgr, txmsg);
    3439                 :            : 
    3440                 :            :         ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
    3441                 :            :         if (ret > 0) {
    3442                 :            :                 if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK)
    3443                 :            :                         ret = -EIO;
    3444                 :            :                 else
    3445                 :            :                         ret = 0;
    3446                 :            :         }
    3447                 :            :         kfree(txmsg);
    3448                 :            : fail_put:
    3449                 :            :         drm_dp_mst_topology_put_mstb(mstb);
    3450                 :            :         return ret;
    3451                 :            : }
    3452                 :            : 
    3453                 :          0 : static int drm_dp_encode_up_ack_reply(struct drm_dp_sideband_msg_tx *msg, u8 req_type)
    3454                 :            : {
    3455                 :          0 :         struct drm_dp_sideband_msg_reply_body reply;
    3456                 :            : 
    3457                 :          0 :         reply.reply_type = DP_SIDEBAND_REPLY_ACK;
    3458                 :          0 :         reply.req_type = req_type;
    3459                 :          0 :         drm_dp_encode_sideband_reply(&reply, msg);
    3460                 :          0 :         return 0;
    3461                 :            : }
    3462                 :            : 
    3463                 :          0 : static int drm_dp_send_up_ack_reply(struct drm_dp_mst_topology_mgr *mgr,
    3464                 :            :                                     struct drm_dp_mst_branch *mstb,
    3465                 :            :                                     int req_type, int seqno, bool broadcast)
    3466                 :            : {
    3467                 :          0 :         struct drm_dp_sideband_msg_tx *txmsg;
    3468                 :            : 
    3469                 :          0 :         txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
    3470         [ #  # ]:          0 :         if (!txmsg)
    3471                 :            :                 return -ENOMEM;
    3472                 :            : 
    3473                 :          0 :         txmsg->dst = mstb;
    3474                 :          0 :         txmsg->seqno = seqno;
    3475                 :          0 :         drm_dp_encode_up_ack_reply(txmsg, req_type);
    3476                 :            : 
    3477                 :          0 :         mutex_lock(&mgr->qlock);
    3478                 :            : 
    3479                 :          0 :         process_single_up_tx_qlock(mgr, txmsg);
    3480                 :            : 
    3481                 :          0 :         mutex_unlock(&mgr->qlock);
    3482                 :            : 
    3483                 :          0 :         kfree(txmsg);
    3484                 :          0 :         return 0;
    3485                 :            : }
    3486                 :            : 
    3487                 :          0 : static int drm_dp_get_vc_payload_bw(u8 dp_link_bw, u8  dp_link_count)
    3488                 :            : {
    3489         [ #  # ]:          0 :         if (dp_link_bw == 0 || dp_link_count == 0)
    3490                 :          0 :                 DRM_DEBUG_KMS("invalid link bandwidth in DPCD: %x (link count: %d)\n",
    3491                 :            :                               dp_link_bw, dp_link_count);
    3492                 :            : 
    3493                 :          0 :         return dp_link_bw * dp_link_count / 2;
    3494                 :            : }
    3495                 :            : 
    3496                 :            : /**
    3497                 :            :  * drm_dp_mst_topology_mgr_set_mst() - Set the MST state for a topology manager
    3498                 :            :  * @mgr: manager to set state for
    3499                 :            :  * @mst_state: true to enable MST on this connector - false to disable.
    3500                 :            :  *
    3501                 :            :  * This is called by the driver when it detects an MST capable device plugged
    3502                 :            :  * into a DP MST capable port, or when a DP MST capable device is unplugged.
    3503                 :            :  */
    3504                 :          0 : int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool mst_state)
    3505                 :            : {
    3506                 :          0 :         int ret = 0;
    3507                 :          0 :         int i = 0;
    3508                 :          0 :         struct drm_dp_mst_branch *mstb = NULL;
    3509                 :            : 
    3510                 :          0 :         mutex_lock(&mgr->lock);
    3511         [ #  # ]:          0 :         if (mst_state == mgr->mst_state)
    3512                 :          0 :                 goto out_unlock;
    3513                 :            : 
    3514                 :          0 :         mgr->mst_state = mst_state;
    3515                 :            :         /* set the device into MST mode */
    3516         [ #  # ]:          0 :         if (mst_state) {
    3517         [ #  # ]:          0 :                 WARN_ON(mgr->mst_primary);
    3518                 :            : 
    3519                 :            :                 /* get dpcd info */
    3520                 :          0 :                 ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE);
    3521         [ #  # ]:          0 :                 if (ret != DP_RECEIVER_CAP_SIZE) {
    3522                 :          0 :                         DRM_DEBUG_KMS("failed to read DPCD\n");
    3523                 :          0 :                         goto out_unlock;
    3524                 :            :                 }
    3525                 :            : 
    3526                 :          0 :                 mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr->dpcd[1],
    3527                 :          0 :                                                         mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK);
    3528         [ #  # ]:          0 :                 if (mgr->pbn_div == 0) {
    3529                 :          0 :                         ret = -EINVAL;
    3530                 :          0 :                         goto out_unlock;
    3531                 :            :                 }
    3532                 :            : 
    3533                 :            :                 /* add initial branch device at LCT 1 */
    3534                 :          0 :                 mstb = drm_dp_add_mst_branch_device(1, NULL);
    3535         [ #  # ]:          0 :                 if (mstb == NULL) {
    3536                 :          0 :                         ret = -ENOMEM;
    3537                 :          0 :                         goto out_unlock;
    3538                 :            :                 }
    3539                 :          0 :                 mstb->mgr = mgr;
    3540                 :            : 
    3541                 :            :                 /* give this the main reference */
    3542                 :          0 :                 mgr->mst_primary = mstb;
    3543                 :          0 :                 drm_dp_mst_topology_get_mstb(mgr->mst_primary);
    3544                 :            : 
    3545                 :          0 :                 ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,
    3546                 :            :                                                          DP_MST_EN | DP_UP_REQ_EN | DP_UPSTREAM_IS_SRC);
    3547         [ #  # ]:          0 :                 if (ret < 0) {
    3548                 :          0 :                         goto out_unlock;
    3549                 :            :                 }
    3550                 :            : 
    3551                 :            :                 {
    3552                 :          0 :                         struct drm_dp_payload reset_pay;
    3553                 :          0 :                         reset_pay.start_slot = 0;
    3554                 :          0 :                         reset_pay.num_slots = 0x3f;
    3555                 :          0 :                         drm_dp_dpcd_write_payload(mgr, 0, &reset_pay);
    3556                 :            :                 }
    3557                 :            : 
    3558                 :          0 :                 queue_work(system_long_wq, &mgr->work);
    3559                 :            : 
    3560                 :          0 :                 ret = 0;
    3561                 :            :         } else {
    3562                 :            :                 /* disable MST on the device */
    3563                 :          0 :                 mstb = mgr->mst_primary;
    3564                 :          0 :                 mgr->mst_primary = NULL;
    3565                 :            :                 /* this can fail if the device is gone */
    3566                 :          0 :                 drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL, 0);
    3567                 :          0 :                 ret = 0;
    3568                 :          0 :                 mutex_lock(&mgr->payload_lock);
    3569                 :          0 :                 memset(mgr->payloads, 0, mgr->max_payloads * sizeof(struct drm_dp_payload));
    3570                 :          0 :                 mgr->payload_mask = 0;
    3571                 :          0 :                 set_bit(0, &mgr->payload_mask);
    3572         [ #  # ]:          0 :                 for (i = 0; i < mgr->max_payloads; i++) {
    3573                 :          0 :                         struct drm_dp_vcpi *vcpi = mgr->proposed_vcpis[i];
    3574                 :            : 
    3575         [ #  # ]:          0 :                         if (vcpi) {
    3576                 :          0 :                                 vcpi->vcpi = 0;
    3577                 :          0 :                                 vcpi->num_slots = 0;
    3578                 :            :                         }
    3579                 :          0 :                         mgr->proposed_vcpis[i] = NULL;
    3580                 :            :                 }
    3581                 :          0 :                 mgr->vcpi_mask = 0;
    3582                 :          0 :                 mutex_unlock(&mgr->payload_lock);
    3583                 :            : 
    3584                 :          0 :                 mgr->payload_id_table_cleared = false;
    3585                 :            :         }
    3586                 :            : 
    3587                 :          0 : out_unlock:
    3588                 :          0 :         mutex_unlock(&mgr->lock);
    3589         [ #  # ]:          0 :         if (mstb)
    3590                 :          0 :                 drm_dp_mst_topology_put_mstb(mstb);
    3591                 :          0 :         return ret;
    3592                 :            : 
    3593                 :            : }
    3594                 :            : EXPORT_SYMBOL(drm_dp_mst_topology_mgr_set_mst);
    3595                 :            : 
    3596                 :            : static void
    3597                 :          0 : drm_dp_mst_topology_mgr_invalidate_mstb(struct drm_dp_mst_branch *mstb)
    3598                 :            : {
    3599                 :          0 :         struct drm_dp_mst_port *port;
    3600                 :            : 
    3601                 :            :         /* The link address will need to be re-sent on resume */
    3602                 :          0 :         mstb->link_address_sent = false;
    3603                 :            : 
    3604         [ #  # ]:          0 :         list_for_each_entry(port, &mstb->ports, next)
    3605         [ #  # ]:          0 :                 if (port->mstb)
    3606                 :          0 :                         drm_dp_mst_topology_mgr_invalidate_mstb(port->mstb);
    3607                 :          0 : }
    3608                 :            : 
    3609                 :            : /**
    3610                 :            :  * drm_dp_mst_topology_mgr_suspend() - suspend the MST manager
    3611                 :            :  * @mgr: manager to suspend
    3612                 :            :  *
    3613                 :            :  * This function tells the MST device that we can't handle UP messages
    3614                 :            :  * anymore. This should stop it from sending any since we are suspended.
    3615                 :            :  */
    3616                 :          0 : void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr)
    3617                 :            : {
    3618                 :          0 :         mutex_lock(&mgr->lock);
    3619                 :          0 :         drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,
    3620                 :            :                            DP_MST_EN | DP_UPSTREAM_IS_SRC);
    3621                 :          0 :         mutex_unlock(&mgr->lock);
    3622                 :          0 :         flush_work(&mgr->up_req_work);
    3623                 :          0 :         flush_work(&mgr->work);
    3624                 :          0 :         flush_work(&mgr->delayed_destroy_work);
    3625                 :            : 
    3626                 :          0 :         mutex_lock(&mgr->lock);
    3627   [ #  #  #  # ]:          0 :         if (mgr->mst_state && mgr->mst_primary)
    3628                 :          0 :                 drm_dp_mst_topology_mgr_invalidate_mstb(mgr->mst_primary);
    3629                 :          0 :         mutex_unlock(&mgr->lock);
    3630                 :          0 : }
    3631                 :            : EXPORT_SYMBOL(drm_dp_mst_topology_mgr_suspend);
    3632                 :            : 
    3633                 :            : /**
    3634                 :            :  * drm_dp_mst_topology_mgr_resume() - resume the MST manager
    3635                 :            :  * @mgr: manager to resume
    3636                 :            :  * @sync: whether or not to perform topology reprobing synchronously
    3637                 :            :  *
    3638                 :            :  * This will fetch DPCD and see if the device is still there,
    3639                 :            :  * if it is, it will rewrite the MSTM control bits, and return.
    3640                 :            :  *
    3641                 :            :  * If the device fails this returns -1, and the driver should do
    3642                 :            :  * a full MST reprobe, in case we were undocked.
    3643                 :            :  *
    3644                 :            :  * During system resume (where it is assumed that the driver will be calling
    3645                 :            :  * drm_atomic_helper_resume()) this function should be called beforehand with
    3646                 :            :  * @sync set to true. In contexts like runtime resume where the driver is not
    3647                 :            :  * expected to be calling drm_atomic_helper_resume(), this function should be
    3648                 :            :  * called with @sync set to false in order to avoid deadlocking.
    3649                 :            :  *
    3650                 :            :  * Returns: -1 if the MST topology was removed while we were suspended, 0
    3651                 :            :  * otherwise.
    3652                 :            :  */
    3653                 :          0 : int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr,
    3654                 :            :                                    bool sync)
    3655                 :            : {
    3656                 :          0 :         int ret;
    3657                 :          0 :         u8 guid[16];
    3658                 :            : 
    3659                 :          0 :         mutex_lock(&mgr->lock);
    3660         [ #  # ]:          0 :         if (!mgr->mst_primary)
    3661                 :          0 :                 goto out_fail;
    3662                 :            : 
    3663                 :          0 :         ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd,
    3664                 :            :                                DP_RECEIVER_CAP_SIZE);
    3665         [ #  # ]:          0 :         if (ret != DP_RECEIVER_CAP_SIZE) {
    3666                 :          0 :                 DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n");
    3667                 :          0 :                 goto out_fail;
    3668                 :            :         }
    3669                 :            : 
    3670                 :          0 :         ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,
    3671                 :            :                                  DP_MST_EN |
    3672                 :            :                                  DP_UP_REQ_EN |
    3673                 :            :                                  DP_UPSTREAM_IS_SRC);
    3674         [ #  # ]:          0 :         if (ret < 0) {
    3675                 :          0 :                 DRM_DEBUG_KMS("mst write failed - undocked during suspend?\n");
    3676                 :          0 :                 goto out_fail;
    3677                 :            :         }
    3678                 :            : 
    3679                 :            :         /* Some hubs forget their guids after they resume */
    3680                 :          0 :         ret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16);
    3681         [ #  # ]:          0 :         if (ret != 16) {
    3682                 :          0 :                 DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n");
    3683                 :          0 :                 goto out_fail;
    3684                 :            :         }
    3685                 :          0 :         drm_dp_check_mstb_guid(mgr->mst_primary, guid);
    3686                 :            : 
    3687                 :            :         /*
    3688                 :            :          * For the final step of resuming the topology, we need to bring the
    3689                 :            :          * state of our in-memory topology back into sync with reality. So,
    3690                 :            :          * restart the probing process as if we're probing a new hub
    3691                 :            :          */
    3692                 :          0 :         queue_work(system_long_wq, &mgr->work);
    3693                 :          0 :         mutex_unlock(&mgr->lock);
    3694                 :            : 
    3695         [ #  # ]:          0 :         if (sync) {
    3696                 :          0 :                 DRM_DEBUG_KMS("Waiting for link probe work to finish re-syncing topology...\n");
    3697                 :          0 :                 flush_work(&mgr->work);
    3698                 :            :         }
    3699                 :            : 
    3700                 :            :         return 0;
    3701                 :            : 
    3702                 :          0 : out_fail:
    3703                 :          0 :         mutex_unlock(&mgr->lock);
    3704                 :          0 :         return -1;
    3705                 :            : }
    3706                 :            : EXPORT_SYMBOL(drm_dp_mst_topology_mgr_resume);
    3707                 :            : 
    3708                 :          0 : static bool drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up)
    3709                 :            : {
    3710                 :          0 :         int len;
    3711                 :          0 :         u8 replyblock[32];
    3712                 :          0 :         int replylen, origlen, curreply;
    3713                 :          0 :         int ret;
    3714                 :          0 :         struct drm_dp_sideband_msg_rx *msg;
    3715         [ #  # ]:          0 :         int basereg = up ? DP_SIDEBAND_MSG_UP_REQ_BASE : DP_SIDEBAND_MSG_DOWN_REP_BASE;
    3716         [ #  # ]:          0 :         msg = up ? &mgr->up_req_recv : &mgr->down_rep_recv;
    3717                 :            : 
    3718                 :          0 :         len = min(mgr->max_dpcd_transaction_bytes, 16);
    3719                 :          0 :         ret = drm_dp_dpcd_read(mgr->aux, basereg,
    3720                 :            :                                replyblock, len);
    3721         [ #  # ]:          0 :         if (ret != len) {
    3722                 :          0 :                 DRM_DEBUG_KMS("failed to read DPCD down rep %d %d\n", len, ret);
    3723                 :          0 :                 return false;
    3724                 :            :         }
    3725                 :          0 :         ret = drm_dp_sideband_msg_build(msg, replyblock, len, true);
    3726         [ #  # ]:          0 :         if (!ret) {
    3727                 :          0 :                 DRM_DEBUG_KMS("sideband msg build failed %d\n", replyblock[0]);
    3728                 :          0 :                 return false;
    3729                 :            :         }
    3730                 :          0 :         replylen = msg->curchunk_len + msg->curchunk_hdrlen;
    3731                 :            : 
    3732                 :          0 :         origlen = replylen;
    3733                 :          0 :         replylen -= len;
    3734                 :          0 :         curreply = len;
    3735         [ #  # ]:          0 :         while (replylen > 0) {
    3736                 :          0 :                 len = min3(replylen, mgr->max_dpcd_transaction_bytes, 16);
    3737                 :          0 :                 ret = drm_dp_dpcd_read(mgr->aux, basereg + curreply,
    3738                 :            :                                     replyblock, len);
    3739         [ #  # ]:          0 :                 if (ret != len) {
    3740                 :          0 :                         DRM_DEBUG_KMS("failed to read a chunk (len %d, ret %d)\n",
    3741                 :            :                                       len, ret);
    3742                 :          0 :                         return false;
    3743                 :            :                 }
    3744                 :            : 
    3745                 :          0 :                 ret = drm_dp_sideband_msg_build(msg, replyblock, len, false);
    3746         [ #  # ]:          0 :                 if (!ret) {
    3747                 :          0 :                         DRM_DEBUG_KMS("failed to build sideband msg\n");
    3748                 :          0 :                         return false;
    3749                 :            :                 }
    3750                 :            : 
    3751                 :          0 :                 curreply += len;
    3752                 :          0 :                 replylen -= len;
    3753                 :            :         }
    3754                 :            :         return true;
    3755                 :            : }
    3756                 :            : 
    3757                 :          0 : static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)
    3758                 :            : {
    3759                 :          0 :         struct drm_dp_sideband_msg_tx *txmsg;
    3760                 :          0 :         struct drm_dp_mst_branch *mstb;
    3761                 :          0 :         struct drm_dp_sideband_msg_hdr *hdr = &mgr->down_rep_recv.initial_hdr;
    3762                 :          0 :         int slot = -1;
    3763                 :            : 
    3764         [ #  # ]:          0 :         if (!drm_dp_get_one_sb_msg(mgr, false))
    3765                 :          0 :                 goto clear_down_rep_recv;
    3766                 :            : 
    3767         [ #  # ]:          0 :         if (!mgr->down_rep_recv.have_eomt)
    3768                 :            :                 return 0;
    3769                 :            : 
    3770                 :          0 :         mstb = drm_dp_get_mst_branch_device(mgr, hdr->lct, hdr->rad);
    3771         [ #  # ]:          0 :         if (!mstb) {
    3772                 :          0 :                 DRM_DEBUG_KMS("Got MST reply from unknown device %d\n",
    3773                 :            :                               hdr->lct);
    3774                 :          0 :                 goto clear_down_rep_recv;
    3775                 :            :         }
    3776                 :            : 
    3777                 :            :         /* find the message */
    3778                 :          0 :         slot = hdr->seqno;
    3779                 :          0 :         mutex_lock(&mgr->qlock);
    3780                 :          0 :         txmsg = mstb->tx_slots[slot];
    3781                 :            :         /* remove from slots */
    3782                 :          0 :         mutex_unlock(&mgr->qlock);
    3783                 :            : 
    3784         [ #  # ]:          0 :         if (!txmsg) {
    3785                 :          0 :                 DRM_DEBUG_KMS("Got MST reply with no msg %p %d %d %02x %02x\n",
    3786                 :            :                               mstb, hdr->seqno, hdr->lct, hdr->rad[0],
    3787                 :            :                               mgr->down_rep_recv.msg[0]);
    3788                 :          0 :                 goto no_msg;
    3789                 :            :         }
    3790                 :            : 
    3791                 :          0 :         drm_dp_sideband_parse_reply(&mgr->down_rep_recv, &txmsg->reply);
    3792                 :            : 
    3793         [ #  # ]:          0 :         if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK)
    3794   [ #  #  #  # ]:          0 :                 DRM_DEBUG_KMS("Got NAK reply: req 0x%02x (%s), reason 0x%02x (%s), nak data 0x%02x\n",
    3795                 :            :                               txmsg->reply.req_type,
    3796                 :            :                               drm_dp_mst_req_type_str(txmsg->reply.req_type),
    3797                 :            :                               txmsg->reply.u.nak.reason,
    3798                 :            :                               drm_dp_mst_nak_reason_str(txmsg->reply.u.nak.reason),
    3799                 :            :                               txmsg->reply.u.nak.nak_data);
    3800                 :            : 
    3801                 :          0 :         memset(&mgr->down_rep_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
    3802                 :          0 :         drm_dp_mst_topology_put_mstb(mstb);
    3803                 :            : 
    3804                 :          0 :         mutex_lock(&mgr->qlock);
    3805                 :          0 :         txmsg->state = DRM_DP_SIDEBAND_TX_RX;
    3806                 :          0 :         mstb->tx_slots[slot] = NULL;
    3807                 :          0 :         mgr->is_waiting_for_dwn_reply = false;
    3808                 :          0 :         mutex_unlock(&mgr->qlock);
    3809                 :            : 
    3810                 :          0 :         wake_up_all(&mgr->tx_waitq);
    3811                 :            : 
    3812                 :          0 :         return 0;
    3813                 :            : 
    3814                 :            : no_msg:
    3815                 :          0 :         drm_dp_mst_topology_put_mstb(mstb);
    3816                 :          0 : clear_down_rep_recv:
    3817                 :          0 :         mutex_lock(&mgr->qlock);
    3818                 :          0 :         mgr->is_waiting_for_dwn_reply = false;
    3819                 :          0 :         mutex_unlock(&mgr->qlock);
    3820                 :          0 :         memset(&mgr->down_rep_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
    3821                 :            : 
    3822                 :          0 :         return 0;
    3823                 :            : }
    3824                 :            : 
    3825                 :            : static inline bool
    3826                 :          0 : drm_dp_mst_process_up_req(struct drm_dp_mst_topology_mgr *mgr,
    3827                 :            :                           struct drm_dp_pending_up_req *up_req)
    3828                 :            : {
    3829                 :          0 :         struct drm_dp_mst_branch *mstb = NULL;
    3830                 :          0 :         struct drm_dp_sideband_msg_req_body *msg = &up_req->msg;
    3831                 :          0 :         struct drm_dp_sideband_msg_hdr *hdr = &up_req->hdr;
    3832                 :          0 :         bool hotplug = false;
    3833                 :            : 
    3834         [ #  # ]:          0 :         if (hdr->broadcast) {
    3835                 :          0 :                 const u8 *guid = NULL;
    3836                 :            : 
    3837         [ #  # ]:          0 :                 if (msg->req_type == DP_CONNECTION_STATUS_NOTIFY)
    3838                 :          0 :                         guid = msg->u.conn_stat.guid;
    3839         [ #  # ]:          0 :                 else if (msg->req_type == DP_RESOURCE_STATUS_NOTIFY)
    3840                 :          0 :                         guid = msg->u.resource_stat.guid;
    3841                 :            : 
    3842         [ #  # ]:          0 :                 if (guid)
    3843                 :          0 :                         mstb = drm_dp_get_mst_branch_device_by_guid(mgr, guid);
    3844                 :            :         } else {
    3845                 :          0 :                 mstb = drm_dp_get_mst_branch_device(mgr, hdr->lct, hdr->rad);
    3846                 :            :         }
    3847                 :            : 
    3848         [ #  # ]:          0 :         if (!mstb) {
    3849                 :          0 :                 DRM_DEBUG_KMS("Got MST reply from unknown device %d\n",
    3850                 :            :                               hdr->lct);
    3851                 :          0 :                 return false;
    3852                 :            :         }
    3853                 :            : 
    3854                 :            :         /* TODO: Add missing handler for DP_RESOURCE_STATUS_NOTIFY events */
    3855         [ #  # ]:          0 :         if (msg->req_type == DP_CONNECTION_STATUS_NOTIFY) {
    3856                 :          0 :                 drm_dp_mst_handle_conn_stat(mstb, &msg->u.conn_stat);
    3857                 :          0 :                 hotplug = true;
    3858                 :            :         }
    3859                 :            : 
    3860                 :          0 :         drm_dp_mst_topology_put_mstb(mstb);
    3861                 :          0 :         return hotplug;
    3862                 :            : }
    3863                 :            : 
    3864                 :          0 : static void drm_dp_mst_up_req_work(struct work_struct *work)
    3865                 :            : {
    3866                 :          0 :         struct drm_dp_mst_topology_mgr *mgr =
    3867                 :          0 :                 container_of(work, struct drm_dp_mst_topology_mgr,
    3868                 :            :                              up_req_work);
    3869                 :          0 :         struct drm_dp_pending_up_req *up_req;
    3870                 :          0 :         bool send_hotplug = false;
    3871                 :            : 
    3872                 :          0 :         mutex_lock(&mgr->probe_lock);
    3873                 :          0 :         while (true) {
    3874                 :          0 :                 mutex_lock(&mgr->up_req_lock);
    3875         [ #  # ]:          0 :                 up_req = list_first_entry_or_null(&mgr->up_req_list,
    3876                 :            :                                                   struct drm_dp_pending_up_req,
    3877                 :            :                                                   next);
    3878         [ #  # ]:          0 :                 if (up_req)
    3879                 :          0 :                         list_del(&up_req->next);
    3880                 :          0 :                 mutex_unlock(&mgr->up_req_lock);
    3881                 :            : 
    3882         [ #  # ]:          0 :                 if (!up_req)
    3883                 :            :                         break;
    3884                 :            : 
    3885                 :          0 :                 send_hotplug |= drm_dp_mst_process_up_req(mgr, up_req);
    3886                 :          0 :                 kfree(up_req);
    3887                 :            :         }
    3888                 :          0 :         mutex_unlock(&mgr->probe_lock);
    3889                 :            : 
    3890         [ #  # ]:          0 :         if (send_hotplug)
    3891                 :          0 :                 drm_kms_helper_hotplug_event(mgr->dev);
    3892                 :          0 : }
    3893                 :            : 
    3894                 :          0 : static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
    3895                 :            : {
    3896                 :          0 :         struct drm_dp_sideband_msg_hdr *hdr = &mgr->up_req_recv.initial_hdr;
    3897                 :          0 :         struct drm_dp_pending_up_req *up_req;
    3898                 :          0 :         bool seqno;
    3899                 :            : 
    3900         [ #  # ]:          0 :         if (!drm_dp_get_one_sb_msg(mgr, true))
    3901                 :          0 :                 goto out;
    3902                 :            : 
    3903         [ #  # ]:          0 :         if (!mgr->up_req_recv.have_eomt)
    3904                 :            :                 return 0;
    3905                 :            : 
    3906                 :          0 :         up_req = kzalloc(sizeof(*up_req), GFP_KERNEL);
    3907         [ #  # ]:          0 :         if (!up_req) {
    3908                 :          0 :                 DRM_ERROR("Not enough memory to process MST up req\n");
    3909                 :          0 :                 return -ENOMEM;
    3910                 :            :         }
    3911                 :          0 :         INIT_LIST_HEAD(&up_req->next);
    3912                 :            : 
    3913                 :          0 :         seqno = hdr->seqno;
    3914                 :          0 :         drm_dp_sideband_parse_req(&mgr->up_req_recv, &up_req->msg);
    3915                 :            : 
    3916         [ #  # ]:          0 :         if (up_req->msg.req_type != DP_CONNECTION_STATUS_NOTIFY &&
    3917                 :            :             up_req->msg.req_type != DP_RESOURCE_STATUS_NOTIFY) {
    3918                 :          0 :                 DRM_DEBUG_KMS("Received unknown up req type, ignoring: %x\n",
    3919                 :            :                               up_req->msg.req_type);
    3920                 :          0 :                 kfree(up_req);
    3921                 :          0 :                 goto out;
    3922                 :            :         }
    3923                 :            : 
    3924                 :          0 :         drm_dp_send_up_ack_reply(mgr, mgr->mst_primary, up_req->msg.req_type,
    3925                 :            :                                  seqno, false);
    3926                 :            : 
    3927         [ #  # ]:          0 :         if (up_req->msg.req_type == DP_CONNECTION_STATUS_NOTIFY) {
    3928                 :          0 :                 const struct drm_dp_connection_status_notify *conn_stat =
    3929                 :            :                         &up_req->msg.u.conn_stat;
    3930                 :            : 
    3931                 :          0 :                 DRM_DEBUG_KMS("Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n",
    3932                 :            :                               conn_stat->port_number,
    3933                 :            :                               conn_stat->legacy_device_plug_status,
    3934                 :            :                               conn_stat->displayport_device_plug_status,
    3935                 :            :                               conn_stat->message_capability_status,
    3936                 :            :                               conn_stat->input_port,
    3937                 :            :                               conn_stat->peer_device_type);
    3938         [ #  # ]:          0 :         } else if (up_req->msg.req_type == DP_RESOURCE_STATUS_NOTIFY) {
    3939                 :          0 :                 const struct drm_dp_resource_status_notify *res_stat =
    3940                 :            :                         &up_req->msg.u.resource_stat;
    3941                 :            : 
    3942                 :          0 :                 DRM_DEBUG_KMS("Got RSN: pn: %d avail_pbn %d\n",
    3943                 :            :                               res_stat->port_number,
    3944                 :            :                               res_stat->available_pbn);
    3945                 :            :         }
    3946                 :            : 
    3947                 :          0 :         up_req->hdr = *hdr;
    3948                 :          0 :         mutex_lock(&mgr->up_req_lock);
    3949                 :          0 :         list_add_tail(&up_req->next, &mgr->up_req_list);
    3950                 :          0 :         mutex_unlock(&mgr->up_req_lock);
    3951                 :          0 :         queue_work(system_long_wq, &mgr->up_req_work);
    3952                 :            : 
    3953                 :          0 : out:
    3954                 :          0 :         memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
    3955                 :          0 :         return 0;
    3956                 :            : }
    3957                 :            : 
    3958                 :            : /**
    3959                 :            :  * drm_dp_mst_hpd_irq() - MST hotplug IRQ notify
    3960                 :            :  * @mgr: manager to notify irq for.
    3961                 :            :  * @esi: 4 bytes from SINK_COUNT_ESI
    3962                 :            :  * @handled: whether the hpd interrupt was consumed or not
    3963                 :            :  *
    3964                 :            :  * This should be called from the driver when it detects a short IRQ,
    3965                 :            :  * along with the value of the DEVICE_SERVICE_IRQ_VECTOR_ESI0. The
    3966                 :            :  * topology manager will process the sideband messages received as a result
    3967                 :            :  * of this.
    3968                 :            :  */
    3969                 :          0 : int drm_dp_mst_hpd_irq(struct drm_dp_mst_topology_mgr *mgr, u8 *esi, bool *handled)
    3970                 :            : {
    3971                 :          0 :         int ret = 0;
    3972                 :          0 :         int sc;
    3973                 :          0 :         *handled = false;
    3974                 :          0 :         sc = esi[0] & 0x3f;
    3975                 :            : 
    3976         [ #  # ]:          0 :         if (sc != mgr->sink_count) {
    3977                 :          0 :                 mgr->sink_count = sc;
    3978                 :          0 :                 *handled = true;
    3979                 :            :         }
    3980                 :            : 
    3981         [ #  # ]:          0 :         if (esi[1] & DP_DOWN_REP_MSG_RDY) {
    3982                 :          0 :                 ret = drm_dp_mst_handle_down_rep(mgr);
    3983                 :          0 :                 *handled = true;
    3984                 :            :         }
    3985                 :            : 
    3986         [ #  # ]:          0 :         if (esi[1] & DP_UP_REQ_MSG_RDY) {
    3987                 :          0 :                 ret |= drm_dp_mst_handle_up_req(mgr);
    3988                 :          0 :                 *handled = true;
    3989                 :            :         }
    3990                 :            : 
    3991                 :          0 :         drm_dp_mst_kick_tx(mgr);
    3992                 :          0 :         return ret;
    3993                 :            : }
    3994                 :            : EXPORT_SYMBOL(drm_dp_mst_hpd_irq);
    3995                 :            : 
    3996                 :            : /**
    3997                 :            :  * drm_dp_mst_detect_port() - get connection status for an MST port
    3998                 :            :  * @connector: DRM connector for this port
    3999                 :            :  * @ctx: The acquisition context to use for grabbing locks
    4000                 :            :  * @mgr: manager for this port
    4001                 :            :  * @port: pointer to a port
    4002                 :            :  *
    4003                 :            :  * This returns the current connection state for a port.
    4004                 :            :  */
    4005                 :            : int
    4006                 :          0 : drm_dp_mst_detect_port(struct drm_connector *connector,
    4007                 :            :                        struct drm_modeset_acquire_ctx *ctx,
    4008                 :            :                        struct drm_dp_mst_topology_mgr *mgr,
    4009                 :            :                        struct drm_dp_mst_port *port)
    4010                 :            : {
    4011                 :          0 :         int ret;
    4012                 :            : 
    4013                 :            :         /* we need to search for the port in the mgr in case it's gone */
    4014                 :          0 :         port = drm_dp_mst_topology_get_port_validated(mgr, port);
    4015         [ #  # ]:          0 :         if (!port)
    4016                 :            :                 return connector_status_disconnected;
    4017                 :            : 
    4018                 :          0 :         ret = drm_modeset_lock(&mgr->base.lock, ctx);
    4019         [ #  # ]:          0 :         if (ret)
    4020                 :          0 :                 goto out;
    4021                 :            : 
    4022                 :          0 :         ret = connector_status_disconnected;
    4023                 :            : 
    4024         [ #  # ]:          0 :         if (!port->ddps)
    4025                 :          0 :                 goto out;
    4026                 :            : 
    4027   [ #  #  #  # ]:          0 :         switch (port->pdt) {
    4028                 :          0 :         case DP_PEER_DEVICE_NONE:
    4029                 :            :         case DP_PEER_DEVICE_MST_BRANCHING:
    4030         [ #  # ]:          0 :                 if (!port->mcs)
    4031                 :          0 :                         ret = connector_status_connected;
    4032                 :            :                 break;
    4033                 :            : 
    4034                 :          0 :         case DP_PEER_DEVICE_SST_SINK:
    4035                 :          0 :                 ret = connector_status_connected;
    4036                 :            :                 /* for logical ports - cache the EDID */
    4037   [ #  #  #  # ]:          0 :                 if (port->port_num >= 8 && !port->cached_edid) {
    4038                 :          0 :                         port->cached_edid = drm_get_edid(connector, &port->aux.ddc);
    4039                 :            :                 }
    4040                 :            :                 break;
    4041                 :          0 :         case DP_PEER_DEVICE_DP_LEGACY_CONV:
    4042         [ #  # ]:          0 :                 if (port->ldps)
    4043                 :          0 :                         ret = connector_status_connected;
    4044                 :            :                 break;
    4045                 :            :         }
    4046                 :          0 : out:
    4047                 :          0 :         drm_dp_mst_topology_put_port(port);
    4048                 :          0 :         return ret;
    4049                 :            : }
    4050                 :            : EXPORT_SYMBOL(drm_dp_mst_detect_port);
    4051                 :            : 
    4052                 :            : /**
    4053                 :            :  * drm_dp_mst_port_has_audio() - Check whether port has audio capability or not
    4054                 :            :  * @mgr: manager for this port
    4055                 :            :  * @port: unverified pointer to a port.
    4056                 :            :  *
    4057                 :            :  * This returns whether the port supports audio or not.
    4058                 :            :  */
    4059                 :          0 : bool drm_dp_mst_port_has_audio(struct drm_dp_mst_topology_mgr *mgr,
    4060                 :            :                                         struct drm_dp_mst_port *port)
    4061                 :            : {
    4062                 :          0 :         bool ret = false;
    4063                 :            : 
    4064                 :          0 :         port = drm_dp_mst_topology_get_port_validated(mgr, port);
    4065         [ #  # ]:          0 :         if (!port)
    4066                 :            :                 return ret;
    4067                 :          0 :         ret = port->has_audio;
    4068                 :          0 :         drm_dp_mst_topology_put_port(port);
    4069                 :          0 :         return ret;
    4070                 :            : }
    4071                 :            : EXPORT_SYMBOL(drm_dp_mst_port_has_audio);
    4072                 :            : 
    4073                 :            : /**
    4074                 :            :  * drm_dp_mst_get_edid() - get EDID for an MST port
    4075                 :            :  * @connector: toplevel connector to get EDID for
    4076                 :            :  * @mgr: manager for this port
    4077                 :            :  * @port: unverified pointer to a port.
    4078                 :            :  *
    4079                 :            :  * This returns an EDID for the port connected to a connector,
    4080                 :            :  * It validates the pointer still exists so the caller doesn't require a
    4081                 :            :  * reference.
    4082                 :            :  */
    4083                 :          0 : struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
    4084                 :            : {
    4085                 :          0 :         struct edid *edid = NULL;
    4086                 :            : 
    4087                 :            :         /* we need to search for the port in the mgr in case it's gone */
    4088                 :          0 :         port = drm_dp_mst_topology_get_port_validated(mgr, port);
    4089         [ #  # ]:          0 :         if (!port)
    4090                 :            :                 return NULL;
    4091                 :            : 
    4092         [ #  # ]:          0 :         if (port->cached_edid)
    4093                 :          0 :                 edid = drm_edid_duplicate(port->cached_edid);
    4094                 :            :         else {
    4095                 :          0 :                 edid = drm_get_edid(connector, &port->aux.ddc);
    4096                 :            :         }
    4097                 :          0 :         port->has_audio = drm_detect_monitor_audio(edid);
    4098                 :          0 :         drm_dp_mst_topology_put_port(port);
    4099                 :          0 :         return edid;
    4100                 :            : }
    4101                 :            : EXPORT_SYMBOL(drm_dp_mst_get_edid);
    4102                 :            : 
    4103                 :            : /**
    4104                 :            :  * drm_dp_find_vcpi_slots() - Find VCPI slots for this PBN value
    4105                 :            :  * @mgr: manager to use
    4106                 :            :  * @pbn: payload bandwidth to convert into slots.
    4107                 :            :  *
    4108                 :            :  * Calculate the number of VCPI slots that will be required for the given PBN
    4109                 :            :  * value. This function is deprecated, and should not be used in atomic
    4110                 :            :  * drivers.
    4111                 :            :  *
    4112                 :            :  * RETURNS:
    4113                 :            :  * The total slots required for this port, or error.
    4114                 :            :  */
    4115                 :          0 : int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
    4116                 :            :                            int pbn)
    4117                 :            : {
    4118                 :          0 :         int num_slots;
    4119                 :            : 
    4120                 :          0 :         num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
    4121                 :            : 
    4122                 :            :         /* max. time slots - one slot for MTP header */
    4123         [ #  # ]:          0 :         if (num_slots > 63)
    4124                 :          0 :                 return -ENOSPC;
    4125                 :            :         return num_slots;
    4126                 :            : }
    4127                 :            : EXPORT_SYMBOL(drm_dp_find_vcpi_slots);
    4128                 :            : 
    4129                 :          0 : static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
    4130                 :            :                             struct drm_dp_vcpi *vcpi, int pbn, int slots)
    4131                 :            : {
    4132                 :          0 :         int ret;
    4133                 :            : 
    4134                 :            :         /* max. time slots - one slot for MTP header */
    4135                 :          0 :         if (slots > 63)
    4136                 :            :                 return -ENOSPC;
    4137                 :            : 
    4138                 :          0 :         vcpi->pbn = pbn;
    4139                 :          0 :         vcpi->aligned_pbn = slots * mgr->pbn_div;
    4140                 :          0 :         vcpi->num_slots = slots;
    4141                 :            : 
    4142                 :          0 :         ret = drm_dp_mst_assign_payload_id(mgr, vcpi);
    4143                 :          0 :         if (ret < 0)
    4144                 :            :                 return ret;
    4145                 :            :         return 0;
    4146                 :            : }
    4147                 :            : 
    4148                 :            : /**
    4149                 :            :  * drm_dp_atomic_find_vcpi_slots() - Find and add VCPI slots to the state
    4150                 :            :  * @state: global atomic state
    4151                 :            :  * @mgr: MST topology manager for the port
    4152                 :            :  * @port: port to find vcpi slots for
    4153                 :            :  * @pbn: bandwidth required for the mode in PBN
    4154                 :            :  * @pbn_div: divider for DSC mode that takes FEC into account
    4155                 :            :  *
    4156                 :            :  * Allocates VCPI slots to @port, replacing any previous VCPI allocations it
    4157                 :            :  * may have had. Any atomic drivers which support MST must call this function
    4158                 :            :  * in their &drm_encoder_helper_funcs.atomic_check() callback to change the
    4159                 :            :  * current VCPI allocation for the new state, but only when
    4160                 :            :  * &drm_crtc_state.mode_changed or &drm_crtc_state.connectors_changed is set
    4161                 :            :  * to ensure compatibility with userspace applications that still use the
    4162                 :            :  * legacy modesetting UAPI.
    4163                 :            :  *
    4164                 :            :  * Allocations set by this function are not checked against the bandwidth
    4165                 :            :  * restraints of @mgr until the driver calls drm_dp_mst_atomic_check().
    4166                 :            :  *
    4167                 :            :  * Additionally, it is OK to call this function multiple times on the same
    4168                 :            :  * @port as needed. It is not OK however, to call this function and
    4169                 :            :  * drm_dp_atomic_release_vcpi_slots() in the same atomic check phase.
    4170                 :            :  *
    4171                 :            :  * See also:
    4172                 :            :  * drm_dp_atomic_release_vcpi_slots()
    4173                 :            :  * drm_dp_mst_atomic_check()
    4174                 :            :  *
    4175                 :            :  * Returns:
    4176                 :            :  * Total slots in the atomic state assigned for this port, or a negative error
    4177                 :            :  * code if the port no longer exists
    4178                 :            :  */
    4179                 :          0 : int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state,
    4180                 :            :                                   struct drm_dp_mst_topology_mgr *mgr,
    4181                 :            :                                   struct drm_dp_mst_port *port, int pbn,
    4182                 :            :                                   int pbn_div)
    4183                 :            : {
    4184                 :          0 :         struct drm_dp_mst_topology_state *topology_state;
    4185                 :          0 :         struct drm_dp_vcpi_allocation *pos, *vcpi = NULL;
    4186                 :          0 :         int prev_slots, prev_bw, req_slots;
    4187                 :            : 
    4188                 :          0 :         topology_state = drm_atomic_get_mst_topology_state(state, mgr);
    4189                 :          0 :         if (IS_ERR(topology_state))
    4190                 :          0 :                 return PTR_ERR(topology_state);
    4191                 :            : 
    4192                 :            :         /* Find the current allocation for this port, if any */
    4193         [ #  # ]:          0 :         list_for_each_entry(pos, &topology_state->vcpis, next) {
    4194         [ #  # ]:          0 :                 if (pos->port == port) {
    4195                 :          0 :                         vcpi = pos;
    4196                 :          0 :                         prev_slots = vcpi->vcpi;
    4197                 :          0 :                         prev_bw = vcpi->pbn;
    4198                 :            : 
    4199                 :            :                         /*
    4200                 :            :                          * This should never happen, unless the driver tries
    4201                 :            :                          * releasing and allocating the same VCPI allocation,
    4202                 :            :                          * which is an error
    4203                 :            :                          */
    4204   [ #  #  #  # ]:          0 :                         if (WARN_ON(!prev_slots)) {
    4205                 :          0 :                                 DRM_ERROR("cannot allocate and release VCPI on [MST PORT:%p] in the same state\n",
    4206                 :            :                                           port);
    4207                 :          0 :                                 return -EINVAL;
    4208                 :            :                         }
    4209                 :            : 
    4210                 :            :                         break;
    4211                 :            :                 }
    4212                 :            :         }
    4213         [ #  # ]:          0 :         if (!vcpi) {
    4214                 :          0 :                 prev_slots = 0;
    4215                 :          0 :                 prev_bw = 0;
    4216                 :            :         }
    4217                 :            : 
    4218         [ #  # ]:          0 :         if (pbn_div <= 0)
    4219                 :          0 :                 pbn_div = mgr->pbn_div;
    4220                 :            : 
    4221                 :          0 :         req_slots = DIV_ROUND_UP(pbn, pbn_div);
    4222                 :            : 
    4223                 :          0 :         DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] [MST PORT:%p] VCPI %d -> %d\n",
    4224                 :            :                          port->connector->base.id, port->connector->name,
    4225                 :            :                          port, prev_slots, req_slots);
    4226                 :          0 :         DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] [MST PORT:%p] PBN %d -> %d\n",
    4227                 :            :                          port->connector->base.id, port->connector->name,
    4228                 :            :                          port, prev_bw, pbn);
    4229                 :            : 
    4230                 :            :         /* Add the new allocation to the state */
    4231         [ #  # ]:          0 :         if (!vcpi) {
    4232                 :          0 :                 vcpi = kzalloc(sizeof(*vcpi), GFP_KERNEL);
    4233         [ #  # ]:          0 :                 if (!vcpi)
    4234                 :            :                         return -ENOMEM;
    4235                 :            : 
    4236                 :          0 :                 drm_dp_mst_get_port_malloc(port);
    4237                 :          0 :                 vcpi->port = port;
    4238                 :          0 :                 list_add(&vcpi->next, &topology_state->vcpis);
    4239                 :            :         }
    4240                 :          0 :         vcpi->vcpi = req_slots;
    4241                 :          0 :         vcpi->pbn = pbn;
    4242                 :            : 
    4243                 :          0 :         return req_slots;
    4244                 :            : }
    4245                 :            : EXPORT_SYMBOL(drm_dp_atomic_find_vcpi_slots);
    4246                 :            : 
    4247                 :            : /**
    4248                 :            :  * drm_dp_atomic_release_vcpi_slots() - Release allocated vcpi slots
    4249                 :            :  * @state: global atomic state
    4250                 :            :  * @mgr: MST topology manager for the port
    4251                 :            :  * @port: The port to release the VCPI slots from
    4252                 :            :  *
    4253                 :            :  * Releases any VCPI slots that have been allocated to a port in the atomic
    4254                 :            :  * state. Any atomic drivers which support MST must call this function in
    4255                 :            :  * their &drm_connector_helper_funcs.atomic_check() callback when the
    4256                 :            :  * connector will no longer have VCPI allocated (e.g. because its CRTC was
    4257                 :            :  * removed) when it had VCPI allocated in the previous atomic state.
    4258                 :            :  *
    4259                 :            :  * It is OK to call this even if @port has been removed from the system.
    4260                 :            :  * Additionally, it is OK to call this function multiple times on the same
    4261                 :            :  * @port as needed. It is not OK however, to call this function and
    4262                 :            :  * drm_dp_atomic_find_vcpi_slots() on the same @port in a single atomic check
    4263                 :            :  * phase.
    4264                 :            :  *
    4265                 :            :  * See also:
    4266                 :            :  * drm_dp_atomic_find_vcpi_slots()
    4267                 :            :  * drm_dp_mst_atomic_check()
    4268                 :            :  *
    4269                 :            :  * Returns:
    4270                 :            :  * 0 if all slots for this port were added back to
    4271                 :            :  * &drm_dp_mst_topology_state.avail_slots or negative error code
    4272                 :            :  */
    4273                 :          0 : int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
    4274                 :            :                                      struct drm_dp_mst_topology_mgr *mgr,
    4275                 :            :                                      struct drm_dp_mst_port *port)
    4276                 :            : {
    4277                 :          0 :         struct drm_dp_mst_topology_state *topology_state;
    4278                 :          0 :         struct drm_dp_vcpi_allocation *pos;
    4279                 :          0 :         bool found = false;
    4280                 :            : 
    4281                 :          0 :         topology_state = drm_atomic_get_mst_topology_state(state, mgr);
    4282                 :          0 :         if (IS_ERR(topology_state))
    4283                 :          0 :                 return PTR_ERR(topology_state);
    4284                 :            : 
    4285         [ #  # ]:          0 :         list_for_each_entry(pos, &topology_state->vcpis, next) {
    4286         [ #  # ]:          0 :                 if (pos->port == port) {
    4287                 :            :                         found = true;
    4288                 :            :                         break;
    4289                 :            :                 }
    4290                 :            :         }
    4291   [ #  #  #  # ]:          0 :         if (WARN_ON(!found)) {
    4292                 :          0 :                 DRM_ERROR("no VCPI for [MST PORT:%p] found in mst state %p\n",
    4293                 :            :                           port, &topology_state->base);
    4294                 :          0 :                 return -EINVAL;
    4295                 :            :         }
    4296                 :            : 
    4297                 :          0 :         DRM_DEBUG_ATOMIC("[MST PORT:%p] VCPI %d -> 0\n", port, pos->vcpi);
    4298         [ #  # ]:          0 :         if (pos->vcpi) {
    4299                 :          0 :                 drm_dp_mst_put_port_malloc(port);
    4300                 :          0 :                 pos->vcpi = 0;
    4301                 :            :         }
    4302                 :            : 
    4303                 :            :         return 0;
    4304                 :            : }
    4305                 :            : EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
    4306                 :            : 
    4307                 :            : /**
    4308                 :            :  * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
    4309                 :            :  * @mgr: manager for this port
    4310                 :            :  * @port: port to allocate a virtual channel for.
    4311                 :            :  * @pbn: payload bandwidth number to request
    4312                 :            :  * @slots: returned number of slots for this PBN.
    4313                 :            :  */
    4314                 :          0 : bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
    4315                 :            :                               struct drm_dp_mst_port *port, int pbn, int slots)
    4316                 :            : {
    4317                 :          0 :         int ret;
    4318                 :            : 
    4319                 :          0 :         port = drm_dp_mst_topology_get_port_validated(mgr, port);
    4320         [ #  # ]:          0 :         if (!port)
    4321                 :            :                 return false;
    4322                 :            : 
    4323         [ #  # ]:          0 :         if (slots < 0)
    4324                 :            :                 return false;
    4325                 :            : 
    4326         [ #  # ]:          0 :         if (port->vcpi.vcpi > 0) {
    4327                 :          0 :                 DRM_DEBUG_KMS("payload: vcpi %d already allocated for pbn %d - requested pbn %d\n",
    4328                 :            :                               port->vcpi.vcpi, port->vcpi.pbn, pbn);
    4329         [ #  # ]:          0 :                 if (pbn == port->vcpi.pbn) {
    4330                 :          0 :                         drm_dp_mst_topology_put_port(port);
    4331                 :          0 :                         return true;
    4332                 :            :                 }
    4333                 :            :         }
    4334                 :            : 
    4335         [ #  # ]:          0 :         ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
    4336         [ #  # ]:          0 :         if (ret) {
    4337                 :          0 :                 DRM_DEBUG_KMS("failed to init vcpi slots=%d max=63 ret=%d\n",
    4338                 :            :                               DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
    4339                 :          0 :                 goto out;
    4340                 :            :         }
    4341                 :          0 :         DRM_DEBUG_KMS("initing vcpi for pbn=%d slots=%d\n",
    4342                 :            :                       pbn, port->vcpi.num_slots);
    4343                 :            : 
    4344                 :            :         /* Keep port allocated until its payload has been removed */
    4345                 :          0 :         drm_dp_mst_get_port_malloc(port);
    4346                 :          0 :         drm_dp_mst_topology_put_port(port);
    4347                 :          0 :         return true;
    4348                 :            : out:
    4349                 :          0 :         return false;
    4350                 :            : }
    4351                 :            : EXPORT_SYMBOL(drm_dp_mst_allocate_vcpi);
    4352                 :            : 
    4353                 :          0 : int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
    4354                 :            : {
    4355                 :          0 :         int slots = 0;
    4356                 :          0 :         port = drm_dp_mst_topology_get_port_validated(mgr, port);
    4357         [ #  # ]:          0 :         if (!port)
    4358                 :            :                 return slots;
    4359                 :            : 
    4360                 :          0 :         slots = port->vcpi.num_slots;
    4361                 :          0 :         drm_dp_mst_topology_put_port(port);
    4362                 :          0 :         return slots;
    4363                 :            : }
    4364                 :            : EXPORT_SYMBOL(drm_dp_mst_get_vcpi_slots);
    4365                 :            : 
    4366                 :            : /**
    4367                 :            :  * drm_dp_mst_reset_vcpi_slots() - Reset number of slots to 0 for VCPI
    4368                 :            :  * @mgr: manager for this port
    4369                 :            :  * @port: unverified pointer to a port.
    4370                 :            :  *
    4371                 :            :  * This just resets the number of slots for the ports VCPI for later programming.
    4372                 :            :  */
    4373                 :          0 : void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
    4374                 :            : {
    4375                 :            :         /*
    4376                 :            :          * A port with VCPI will remain allocated until its VCPI is
    4377                 :            :          * released, no verified ref needed
    4378                 :            :          */
    4379                 :            : 
    4380                 :          0 :         port->vcpi.num_slots = 0;
    4381                 :          0 : }
    4382                 :            : EXPORT_SYMBOL(drm_dp_mst_reset_vcpi_slots);
    4383                 :            : 
    4384                 :            : /**
    4385                 :            :  * drm_dp_mst_deallocate_vcpi() - deallocate a VCPI
    4386                 :            :  * @mgr: manager for this port
    4387                 :            :  * @port: port to deallocate vcpi for
    4388                 :            :  *
    4389                 :            :  * This can be called unconditionally, regardless of whether
    4390                 :            :  * drm_dp_mst_allocate_vcpi() succeeded or not.
    4391                 :            :  */
    4392                 :          0 : void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
    4393                 :            :                                 struct drm_dp_mst_port *port)
    4394                 :            : {
    4395         [ #  # ]:          0 :         if (!port->vcpi.vcpi)
    4396                 :            :                 return;
    4397                 :            : 
    4398                 :          0 :         drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
    4399                 :          0 :         port->vcpi.num_slots = 0;
    4400                 :          0 :         port->vcpi.pbn = 0;
    4401                 :          0 :         port->vcpi.aligned_pbn = 0;
    4402                 :          0 :         port->vcpi.vcpi = 0;
    4403                 :          0 :         drm_dp_mst_put_port_malloc(port);
    4404                 :            : }
    4405                 :            : EXPORT_SYMBOL(drm_dp_mst_deallocate_vcpi);
    4406                 :            : 
    4407                 :            : static int drm_dp_dpcd_write_payload(struct drm_dp_mst_topology_mgr *mgr,
    4408                 :            :                                      int id, struct drm_dp_payload *payload)
    4409                 :            : {
    4410                 :            :         u8 payload_alloc[3], status;
    4411                 :            :         int ret;
    4412                 :            :         int retries = 0;
    4413                 :            : 
    4414                 :            :         drm_dp_dpcd_writeb(mgr->aux, DP_PAYLOAD_TABLE_UPDATE_STATUS,
    4415                 :            :                            DP_PAYLOAD_TABLE_UPDATED);
    4416                 :            : 
    4417                 :            :         payload_alloc[0] = id;
    4418                 :            :         payload_alloc[1] = payload->start_slot;
    4419                 :            :         payload_alloc[2] = payload->num_slots;
    4420                 :            : 
    4421                 :            :         ret = drm_dp_dpcd_write(mgr->aux, DP_PAYLOAD_ALLOCATE_SET, payload_alloc, 3);
    4422                 :            :         if (ret != 3) {
    4423                 :            :                 DRM_DEBUG_KMS("failed to write payload allocation %d\n", ret);
    4424                 :            :                 goto fail;
    4425                 :            :         }
    4426                 :            : 
    4427                 :            : retry:
    4428                 :            :         ret = drm_dp_dpcd_readb(mgr->aux, DP_PAYLOAD_TABLE_UPDATE_STATUS, &status);
    4429                 :            :         if (ret < 0) {
    4430                 :            :                 DRM_DEBUG_KMS("failed to read payload table status %d\n", ret);
    4431                 :            :                 goto fail;
    4432                 :            :         }
    4433                 :            : 
    4434                 :            :         if (!(status & DP_PAYLOAD_TABLE_UPDATED)) {
    4435                 :            :                 retries++;
    4436                 :            :                 if (retries < 20) {
    4437                 :            :                         usleep_range(10000, 20000);
    4438                 :            :                         goto retry;
    4439                 :            :                 }
    4440                 :            :                 DRM_DEBUG_KMS("status not set after read payload table status %d\n", status);
    4441                 :            :                 ret = -EINVAL;
    4442                 :            :                 goto fail;
    4443                 :            :         }
    4444                 :            :         ret = 0;
    4445                 :            : fail:
    4446                 :            :         return ret;
    4447                 :            : }
    4448                 :            : 
    4449                 :            : 
    4450                 :            : /**
    4451                 :            :  * drm_dp_check_act_status() - Check ACT handled status.
    4452                 :            :  * @mgr: manager to use
    4453                 :            :  *
    4454                 :            :  * Check the payload status bits in the DPCD for ACT handled completion.
    4455                 :            :  */
    4456                 :          0 : int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr)
    4457                 :            : {
    4458                 :          0 :         u8 status;
    4459                 :          0 :         int ret;
    4460                 :          0 :         int count = 0;
    4461                 :            : 
    4462                 :          0 :         do {
    4463                 :          0 :                 ret = drm_dp_dpcd_readb(mgr->aux, DP_PAYLOAD_TABLE_UPDATE_STATUS, &status);
    4464                 :            : 
    4465         [ #  # ]:          0 :                 if (ret < 0) {
    4466                 :          0 :                         DRM_DEBUG_KMS("failed to read payload table status %d\n", ret);
    4467                 :          0 :                         goto fail;
    4468                 :            :                 }
    4469                 :            : 
    4470         [ #  # ]:          0 :                 if (status & DP_PAYLOAD_ACT_HANDLED)
    4471                 :            :                         break;
    4472                 :          0 :                 count++;
    4473                 :          0 :                 udelay(100);
    4474                 :            : 
    4475         [ #  # ]:          0 :         } while (count < 30);
    4476                 :            : 
    4477         [ #  # ]:          0 :         if (!(status & DP_PAYLOAD_ACT_HANDLED)) {
    4478                 :          0 :                 DRM_DEBUG_KMS("failed to get ACT bit %d after %d retries\n", status, count);
    4479                 :          0 :                 ret = -EINVAL;
    4480                 :          0 :                 goto fail;
    4481                 :            :         }
    4482                 :            :         return 0;
    4483                 :            : fail:
    4484                 :            :         return ret;
    4485                 :            : }
    4486                 :            : EXPORT_SYMBOL(drm_dp_check_act_status);
    4487                 :            : 
    4488                 :            : /**
    4489                 :            :  * drm_dp_calc_pbn_mode() - Calculate the PBN for a mode.
    4490                 :            :  * @clock: dot clock for the mode
    4491                 :            :  * @bpp: bpp for the mode.
    4492                 :            :  * @dsc: DSC mode. If true, bpp has units of 1/16 of a bit per pixel
    4493                 :            :  *
    4494                 :            :  * This uses the formula in the spec to calculate the PBN value for a mode.
    4495                 :            :  */
    4496                 :          0 : int drm_dp_calc_pbn_mode(int clock, int bpp, bool dsc)
    4497                 :            : {
    4498                 :            :         /*
    4499                 :            :          * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006
    4500                 :            :          * The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on
    4501                 :            :          * common multiplier to render an integer PBN for all link rate/lane
    4502                 :            :          * counts combinations
    4503                 :            :          * calculate
    4504                 :            :          * peak_kbps *= (1006/1000)
    4505                 :            :          * peak_kbps *= (64/54)
    4506                 :            :          * peak_kbps *= 8    convert to bytes
    4507                 :            :          *
    4508                 :            :          * If the bpp is in units of 1/16, further divide by 16. Put this
    4509                 :            :          * factor in the numerator rather than the denominator to avoid
    4510                 :            :          * integer overflow
    4511                 :            :          */
    4512                 :            : 
    4513         [ #  # ]:          0 :         if (dsc)
    4514                 :          0 :                 return DIV_ROUND_UP_ULL(mul_u32_u32(clock * (bpp / 16), 64 * 1006),
    4515                 :            :                                         8 * 54 * 1000 * 1000);
    4516                 :            : 
    4517                 :          0 :         return DIV_ROUND_UP_ULL(mul_u32_u32(clock * bpp, 64 * 1006),
    4518                 :            :                                 8 * 54 * 1000 * 1000);
    4519                 :            : }
    4520                 :            : EXPORT_SYMBOL(drm_dp_calc_pbn_mode);
    4521                 :            : 
    4522                 :            : /* we want to kick the TX after we've ack the up/down IRQs. */
    4523                 :          0 : static void drm_dp_mst_kick_tx(struct drm_dp_mst_topology_mgr *mgr)
    4524                 :            : {
    4525                 :          0 :         queue_work(system_long_wq, &mgr->tx_work);
    4526                 :            : }
    4527                 :            : 
    4528                 :          0 : static void drm_dp_mst_dump_mstb(struct seq_file *m,
    4529                 :            :                                  struct drm_dp_mst_branch *mstb)
    4530                 :            : {
    4531                 :          0 :         struct drm_dp_mst_port *port;
    4532                 :          0 :         int tabs = mstb->lct;
    4533                 :          0 :         char prefix[10];
    4534                 :          0 :         int i;
    4535                 :            : 
    4536         [ #  # ]:          0 :         for (i = 0; i < tabs; i++)
    4537                 :          0 :                 prefix[i] = '\t';
    4538                 :          0 :         prefix[i] = '\0';
    4539                 :            : 
    4540                 :          0 :         seq_printf(m, "%smst: %p, %d\n", prefix, mstb, mstb->num_ports);
    4541         [ #  # ]:          0 :         list_for_each_entry(port, &mstb->ports, next) {
    4542                 :          0 :                 seq_printf(m, "%sport: %d: input: %d: pdt: %d, ddps: %d ldps: %d, sdp: %d/%d, %p, conn: %p\n", prefix, port->port_num, port->input, port->pdt, port->ddps, port->ldps, port->num_sdp_streams, port->num_sdp_stream_sinks, port, port->connector);
    4543         [ #  # ]:          0 :                 if (port->mstb)
    4544                 :          0 :                         drm_dp_mst_dump_mstb(m, port->mstb);
    4545                 :            :         }
    4546                 :          0 : }
    4547                 :            : 
    4548                 :            : #define DP_PAYLOAD_TABLE_SIZE           64
    4549                 :            : 
    4550                 :            : static bool dump_dp_payload_table(struct drm_dp_mst_topology_mgr *mgr,
    4551                 :            :                                   char *buf)
    4552                 :            : {
    4553                 :            :         int i;
    4554                 :            : 
    4555                 :            :         for (i = 0; i < DP_PAYLOAD_TABLE_SIZE; i += 16) {
    4556                 :            :                 if (drm_dp_dpcd_read(mgr->aux,
    4557                 :            :                                      DP_PAYLOAD_TABLE_UPDATE_STATUS + i,
    4558                 :            :                                      &buf[i], 16) != 16)
    4559                 :            :                         return false;
    4560                 :            :         }
    4561                 :            :         return true;
    4562                 :            : }
    4563                 :            : 
    4564                 :          0 : static void fetch_monitor_name(struct drm_dp_mst_topology_mgr *mgr,
    4565                 :            :                                struct drm_dp_mst_port *port, char *name,
    4566                 :            :                                int namelen)
    4567                 :            : {
    4568                 :          0 :         struct edid *mst_edid;
    4569                 :            : 
    4570                 :          0 :         mst_edid = drm_dp_mst_get_edid(port->connector, mgr, port);
    4571                 :          0 :         drm_edid_get_monitor_name(mst_edid, name, namelen);
    4572                 :          0 : }
    4573                 :            : 
    4574                 :            : /**
    4575                 :            :  * drm_dp_mst_dump_topology(): dump topology to seq file.
    4576                 :            :  * @m: seq_file to dump output to
    4577                 :            :  * @mgr: manager to dump current topology for.
    4578                 :            :  *
    4579                 :            :  * helper to dump MST topology to a seq file for debugfs.
    4580                 :            :  */
    4581                 :          0 : void drm_dp_mst_dump_topology(struct seq_file *m,
    4582                 :            :                               struct drm_dp_mst_topology_mgr *mgr)
    4583                 :            : {
    4584                 :          0 :         int i;
    4585                 :          0 :         struct drm_dp_mst_port *port;
    4586                 :            : 
    4587                 :          0 :         mutex_lock(&mgr->lock);
    4588         [ #  # ]:          0 :         if (mgr->mst_primary)
    4589                 :          0 :                 drm_dp_mst_dump_mstb(m, mgr->mst_primary);
    4590                 :            : 
    4591                 :            :         /* dump VCPIs */
    4592                 :          0 :         mutex_unlock(&mgr->lock);
    4593                 :            : 
    4594                 :          0 :         mutex_lock(&mgr->payload_lock);
    4595                 :          0 :         seq_printf(m, "vcpi: %lx %lx %d\n", mgr->payload_mask, mgr->vcpi_mask,
    4596                 :            :                 mgr->max_payloads);
    4597                 :            : 
    4598         [ #  # ]:          0 :         for (i = 0; i < mgr->max_payloads; i++) {
    4599         [ #  # ]:          0 :                 if (mgr->proposed_vcpis[i]) {
    4600                 :          0 :                         char name[14];
    4601                 :            : 
    4602                 :          0 :                         port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi);
    4603                 :          0 :                         fetch_monitor_name(mgr, port, name, sizeof(name));
    4604                 :          0 :                         seq_printf(m, "vcpi %d: %d %d %d sink name: %s\n", i,
    4605                 :          0 :                                    port->port_num, port->vcpi.vcpi,
    4606                 :            :                                    port->vcpi.num_slots,
    4607         [ #  # ]:          0 :                                    (*name != 0) ? name :  "Unknown");
    4608                 :            :                 } else
    4609                 :          0 :                         seq_printf(m, "vcpi %d:unused\n", i);
    4610                 :            :         }
    4611         [ #  # ]:          0 :         for (i = 0; i < mgr->max_payloads; i++) {
    4612                 :          0 :                 seq_printf(m, "payload %d: %d, %d, %d\n",
    4613                 :            :                            i,
    4614                 :            :                            mgr->payloads[i].payload_state,
    4615                 :            :                            mgr->payloads[i].start_slot,
    4616                 :          0 :                            mgr->payloads[i].num_slots);
    4617                 :            : 
    4618                 :            : 
    4619                 :            :         }
    4620                 :          0 :         mutex_unlock(&mgr->payload_lock);
    4621                 :            : 
    4622                 :          0 :         mutex_lock(&mgr->lock);
    4623         [ #  # ]:          0 :         if (mgr->mst_primary) {
    4624                 :          0 :                 u8 buf[DP_PAYLOAD_TABLE_SIZE];
    4625                 :          0 :                 int ret;
    4626                 :            : 
    4627                 :          0 :                 ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, buf, DP_RECEIVER_CAP_SIZE);
    4628                 :          0 :                 seq_printf(m, "dpcd: %*ph\n", DP_RECEIVER_CAP_SIZE, buf);
    4629                 :          0 :                 ret = drm_dp_dpcd_read(mgr->aux, DP_FAUX_CAP, buf, 2);
    4630                 :          0 :                 seq_printf(m, "faux/mst: %*ph\n", 2, buf);
    4631                 :          0 :                 ret = drm_dp_dpcd_read(mgr->aux, DP_MSTM_CTRL, buf, 1);
    4632                 :          0 :                 seq_printf(m, "mst ctrl: %*ph\n", 1, buf);
    4633                 :            : 
    4634                 :            :                 /* dump the standard OUI branch header */
    4635                 :          0 :                 ret = drm_dp_dpcd_read(mgr->aux, DP_BRANCH_OUI, buf, DP_BRANCH_OUI_HEADER_SIZE);
    4636                 :          0 :                 seq_printf(m, "branch oui: %*phN devid: ", 3, buf);
    4637   [ #  #  #  # ]:          0 :                 for (i = 0x3; i < 0x8 && buf[i]; i++)
    4638                 :          0 :                         seq_printf(m, "%c", buf[i]);
    4639                 :          0 :                 seq_printf(m, " revision: hw: %x.%x sw: %x.%x\n",
    4640                 :          0 :                            buf[0x9] >> 4, buf[0x9] & 0xf, buf[0xa], buf[0xb]);
    4641         [ #  # ]:          0 :                 if (dump_dp_payload_table(mgr, buf))
    4642                 :          0 :                         seq_printf(m, "payload table: %*ph\n", DP_PAYLOAD_TABLE_SIZE, buf);
    4643                 :            :         }
    4644                 :            : 
    4645                 :          0 :         mutex_unlock(&mgr->lock);
    4646                 :            : 
    4647                 :          0 : }
    4648                 :            : EXPORT_SYMBOL(drm_dp_mst_dump_topology);
    4649                 :            : 
    4650                 :          0 : static void drm_dp_tx_work(struct work_struct *work)
    4651                 :            : {
    4652                 :          0 :         struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, tx_work);
    4653                 :            : 
    4654                 :          0 :         mutex_lock(&mgr->qlock);
    4655   [ #  #  #  # ]:          0 :         if (!list_empty(&mgr->tx_msg_downq) && !mgr->is_waiting_for_dwn_reply)
    4656                 :          0 :                 process_single_down_tx_qlock(mgr);
    4657                 :          0 :         mutex_unlock(&mgr->qlock);
    4658                 :          0 : }
    4659                 :            : 
    4660                 :            : static inline void
    4661                 :          0 : drm_dp_delayed_destroy_port(struct drm_dp_mst_port *port)
    4662                 :            : {
    4663         [ #  # ]:          0 :         if (port->connector)
    4664                 :          0 :                 port->mgr->cbs->destroy_connector(port->mgr, port->connector);
    4665                 :            : 
    4666                 :          0 :         drm_dp_port_set_pdt(port, DP_PEER_DEVICE_NONE, port->mcs);
    4667                 :          0 :         drm_dp_mst_put_port_malloc(port);
    4668                 :          0 : }
    4669                 :            : 
    4670                 :            : static inline void
    4671                 :          0 : drm_dp_delayed_destroy_mstb(struct drm_dp_mst_branch *mstb)
    4672                 :            : {
    4673                 :          0 :         struct drm_dp_mst_topology_mgr *mgr = mstb->mgr;
    4674                 :          0 :         struct drm_dp_mst_port *port, *tmp;
    4675                 :          0 :         bool wake_tx = false;
    4676                 :            : 
    4677                 :          0 :         mutex_lock(&mgr->lock);
    4678         [ #  # ]:          0 :         list_for_each_entry_safe(port, tmp, &mstb->ports, next) {
    4679                 :          0 :                 list_del(&port->next);
    4680                 :          0 :                 drm_dp_mst_topology_put_port(port);
    4681                 :            :         }
    4682                 :          0 :         mutex_unlock(&mgr->lock);
    4683                 :            : 
    4684                 :            :         /* drop any tx slots msg */
    4685                 :          0 :         mutex_lock(&mstb->mgr->qlock);
    4686         [ #  # ]:          0 :         if (mstb->tx_slots[0]) {
    4687                 :          0 :                 mstb->tx_slots[0]->state = DRM_DP_SIDEBAND_TX_TIMEOUT;
    4688                 :          0 :                 mstb->tx_slots[0] = NULL;
    4689                 :          0 :                 wake_tx = true;
    4690                 :            :         }
    4691         [ #  # ]:          0 :         if (mstb->tx_slots[1]) {
    4692                 :          0 :                 mstb->tx_slots[1]->state = DRM_DP_SIDEBAND_TX_TIMEOUT;
    4693                 :          0 :                 mstb->tx_slots[1] = NULL;
    4694                 :          0 :                 wake_tx = true;
    4695                 :            :         }
    4696                 :          0 :         mutex_unlock(&mstb->mgr->qlock);
    4697                 :            : 
    4698         [ #  # ]:          0 :         if (wake_tx)
    4699                 :          0 :                 wake_up_all(&mstb->mgr->tx_waitq);
    4700                 :            : 
    4701                 :          0 :         drm_dp_mst_put_mstb_malloc(mstb);
    4702                 :          0 : }
    4703                 :            : 
    4704                 :          0 : static void drm_dp_delayed_destroy_work(struct work_struct *work)
    4705                 :            : {
    4706                 :          0 :         struct drm_dp_mst_topology_mgr *mgr =
    4707                 :          0 :                 container_of(work, struct drm_dp_mst_topology_mgr,
    4708                 :            :                              delayed_destroy_work);
    4709                 :          0 :         bool send_hotplug = false, go_again;
    4710                 :            : 
    4711                 :            :         /*
    4712                 :            :          * Not a regular list traverse as we have to drop the destroy
    4713                 :            :          * connector lock before destroying the mstb/port, to avoid AB->BA
    4714                 :            :          * ordering between this lock and the config mutex.
    4715                 :            :          */
    4716                 :          0 :         do {
    4717                 :          0 :                 go_again = false;
    4718                 :            : 
    4719                 :          0 :                 for (;;) {
    4720                 :          0 :                         struct drm_dp_mst_branch *mstb;
    4721                 :            : 
    4722                 :          0 :                         mutex_lock(&mgr->delayed_destroy_lock);
    4723         [ #  # ]:          0 :                         mstb = list_first_entry_or_null(&mgr->destroy_branch_device_list,
    4724                 :            :                                                         struct drm_dp_mst_branch,
    4725                 :            :                                                         destroy_next);
    4726         [ #  # ]:          0 :                         if (mstb)
    4727                 :          0 :                                 list_del(&mstb->destroy_next);
    4728                 :          0 :                         mutex_unlock(&mgr->delayed_destroy_lock);
    4729                 :            : 
    4730         [ #  # ]:          0 :                         if (!mstb)
    4731                 :            :                                 break;
    4732                 :            : 
    4733                 :          0 :                         drm_dp_delayed_destroy_mstb(mstb);
    4734                 :          0 :                         go_again = true;
    4735                 :            :                 }
    4736                 :            : 
    4737                 :          0 :                 for (;;) {
    4738                 :          0 :                         struct drm_dp_mst_port *port;
    4739                 :            : 
    4740                 :          0 :                         mutex_lock(&mgr->delayed_destroy_lock);
    4741         [ #  # ]:          0 :                         port = list_first_entry_or_null(&mgr->destroy_port_list,
    4742                 :            :                                                         struct drm_dp_mst_port,
    4743                 :            :                                                         next);
    4744         [ #  # ]:          0 :                         if (port)
    4745                 :          0 :                                 list_del(&port->next);
    4746                 :          0 :                         mutex_unlock(&mgr->delayed_destroy_lock);
    4747                 :            : 
    4748         [ #  # ]:          0 :                         if (!port)
    4749                 :            :                                 break;
    4750                 :            : 
    4751                 :          0 :                         drm_dp_delayed_destroy_port(port);
    4752                 :          0 :                         send_hotplug = true;
    4753                 :          0 :                         go_again = true;
    4754                 :            :                 }
    4755         [ #  # ]:          0 :         } while (go_again);
    4756                 :            : 
    4757         [ #  # ]:          0 :         if (send_hotplug)
    4758                 :          0 :                 drm_kms_helper_hotplug_event(mgr->dev);
    4759                 :          0 : }
    4760                 :            : 
    4761                 :            : static struct drm_private_state *
    4762                 :          0 : drm_dp_mst_duplicate_state(struct drm_private_obj *obj)
    4763                 :            : {
    4764                 :          0 :         struct drm_dp_mst_topology_state *state, *old_state =
    4765                 :          0 :                 to_dp_mst_topology_state(obj->state);
    4766                 :          0 :         struct drm_dp_vcpi_allocation *pos, *vcpi;
    4767                 :            : 
    4768                 :          0 :         state = kmemdup(old_state, sizeof(*state), GFP_KERNEL);
    4769         [ #  # ]:          0 :         if (!state)
    4770                 :            :                 return NULL;
    4771                 :            : 
    4772                 :          0 :         __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
    4773                 :            : 
    4774                 :          0 :         INIT_LIST_HEAD(&state->vcpis);
    4775                 :            : 
    4776         [ #  # ]:          0 :         list_for_each_entry(pos, &old_state->vcpis, next) {
    4777                 :            :                 /* Prune leftover freed VCPI allocations */
    4778         [ #  # ]:          0 :                 if (!pos->vcpi)
    4779                 :          0 :                         continue;
    4780                 :            : 
    4781                 :          0 :                 vcpi = kmemdup(pos, sizeof(*vcpi), GFP_KERNEL);
    4782         [ #  # ]:          0 :                 if (!vcpi)
    4783                 :          0 :                         goto fail;
    4784                 :            : 
    4785                 :          0 :                 drm_dp_mst_get_port_malloc(vcpi->port);
    4786                 :          0 :                 list_add(&vcpi->next, &state->vcpis);
    4787                 :            :         }
    4788                 :            : 
    4789                 :            :         return &state->base;
    4790                 :            : 
    4791                 :            : fail:
    4792         [ #  # ]:          0 :         list_for_each_entry_safe(pos, vcpi, &state->vcpis, next) {
    4793                 :          0 :                 drm_dp_mst_put_port_malloc(pos->port);
    4794                 :          0 :                 kfree(pos);
    4795                 :            :         }
    4796                 :          0 :         kfree(state);
    4797                 :            : 
    4798                 :          0 :         return NULL;
    4799                 :            : }
    4800                 :            : 
    4801                 :          0 : static void drm_dp_mst_destroy_state(struct drm_private_obj *obj,
    4802                 :            :                                      struct drm_private_state *state)
    4803                 :            : {
    4804                 :          0 :         struct drm_dp_mst_topology_state *mst_state =
    4805                 :          0 :                 to_dp_mst_topology_state(state);
    4806                 :          0 :         struct drm_dp_vcpi_allocation *pos, *tmp;
    4807                 :            : 
    4808         [ #  # ]:          0 :         list_for_each_entry_safe(pos, tmp, &mst_state->vcpis, next) {
    4809                 :            :                 /* We only keep references to ports with non-zero VCPIs */
    4810         [ #  # ]:          0 :                 if (pos->vcpi)
    4811                 :          0 :                         drm_dp_mst_put_port_malloc(pos->port);
    4812                 :          0 :                 kfree(pos);
    4813                 :            :         }
    4814                 :            : 
    4815                 :          0 :         kfree(mst_state);
    4816                 :          0 : }
    4817                 :            : 
    4818                 :          0 : static bool drm_dp_mst_port_downstream_of_branch(struct drm_dp_mst_port *port,
    4819                 :            :                                                  struct drm_dp_mst_branch *branch)
    4820                 :            : {
    4821         [ #  # ]:          0 :         while (port->parent) {
    4822         [ #  # ]:          0 :                 if (port->parent == branch)
    4823                 :            :                         return true;
    4824                 :            : 
    4825         [ #  # ]:          0 :                 if (port->parent->port_parent)
    4826                 :            :                         port = port->parent->port_parent;
    4827                 :            :                 else
    4828                 :            :                         break;
    4829                 :            :         }
    4830                 :            :         return false;
    4831                 :            : }
    4832                 :            : 
    4833                 :            : static int
    4834                 :            : drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port,
    4835                 :            :                                       struct drm_dp_mst_topology_state *state);
    4836                 :            : 
    4837                 :            : static int
    4838                 :          0 : drm_dp_mst_atomic_check_mstb_bw_limit(struct drm_dp_mst_branch *mstb,
    4839                 :            :                                       struct drm_dp_mst_topology_state *state)
    4840                 :            : {
    4841                 :          0 :         struct drm_dp_vcpi_allocation *vcpi;
    4842                 :          0 :         struct drm_dp_mst_port *port;
    4843                 :          0 :         int pbn_used = 0, ret;
    4844                 :          0 :         bool found = false;
    4845                 :            : 
    4846                 :            :         /* Check that we have at least one port in our state that's downstream
    4847                 :            :          * of this branch, otherwise we can skip this branch
    4848                 :            :          */
    4849         [ #  # ]:          0 :         list_for_each_entry(vcpi, &state->vcpis, next) {
    4850   [ #  #  #  # ]:          0 :                 if (!vcpi->pbn ||
    4851                 :          0 :                     !drm_dp_mst_port_downstream_of_branch(vcpi->port, mstb))
    4852                 :          0 :                         continue;
    4853                 :            : 
    4854                 :            :                 found = true;
    4855                 :            :                 break;
    4856                 :            :         }
    4857         [ #  # ]:          0 :         if (!found)
    4858                 :            :                 return 0;
    4859                 :            : 
    4860         [ #  # ]:          0 :         if (mstb->port_parent)
    4861                 :          0 :                 DRM_DEBUG_ATOMIC("[MSTB:%p] [MST PORT:%p] Checking bandwidth limits on [MSTB:%p]\n",
    4862                 :            :                                  mstb->port_parent->parent, mstb->port_parent,
    4863                 :            :                                  mstb);
    4864                 :            :         else
    4865                 :          0 :                 DRM_DEBUG_ATOMIC("[MSTB:%p] Checking bandwidth limits\n",
    4866                 :            :                                  mstb);
    4867                 :            : 
    4868         [ #  # ]:          0 :         list_for_each_entry(port, &mstb->ports, next) {
    4869                 :          0 :                 ret = drm_dp_mst_atomic_check_port_bw_limit(port, state);
    4870         [ #  # ]:          0 :                 if (ret < 0)
    4871                 :          0 :                         return ret;
    4872                 :            : 
    4873                 :          0 :                 pbn_used += ret;
    4874                 :            :         }
    4875                 :            : 
    4876                 :            :         return pbn_used;
    4877                 :            : }
    4878                 :            : 
    4879                 :            : static int
    4880                 :          0 : drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port,
    4881                 :            :                                       struct drm_dp_mst_topology_state *state)
    4882                 :            : {
    4883                 :          0 :         struct drm_dp_vcpi_allocation *vcpi;
    4884                 :          0 :         int pbn_used = 0;
    4885                 :            : 
    4886         [ #  # ]:          0 :         if (port->pdt == DP_PEER_DEVICE_NONE)
    4887                 :            :                 return 0;
    4888                 :            : 
    4889         [ #  # ]:          0 :         if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) {
    4890                 :          0 :                 bool found = false;
    4891                 :            : 
    4892         [ #  # ]:          0 :                 list_for_each_entry(vcpi, &state->vcpis, next) {
    4893         [ #  # ]:          0 :                         if (vcpi->port != port)
    4894                 :          0 :                                 continue;
    4895         [ #  # ]:          0 :                         if (!vcpi->pbn)
    4896                 :            :                                 return 0;
    4897                 :            : 
    4898                 :            :                         found = true;
    4899                 :            :                         break;
    4900                 :            :                 }
    4901                 :          0 :                 if (!found)
    4902                 :            :                         return 0;
    4903                 :            : 
    4904                 :            :                 /* This should never happen, as it means we tried to
    4905                 :            :                  * set a mode before querying the full_pbn
    4906                 :            :                  */
    4907   [ #  #  #  # ]:          0 :                 if (WARN_ON(!port->full_pbn))
    4908                 :            :                         return -EINVAL;
    4909                 :            : 
    4910                 :          0 :                 pbn_used = vcpi->pbn;
    4911                 :            :         } else {
    4912                 :          0 :                 pbn_used = drm_dp_mst_atomic_check_mstb_bw_limit(port->mstb,
    4913                 :            :                                                                  state);
    4914         [ #  # ]:          0 :                 if (pbn_used <= 0)
    4915                 :            :                         return pbn_used;
    4916                 :            :         }
    4917                 :            : 
    4918         [ #  # ]:          0 :         if (pbn_used > port->full_pbn) {
    4919                 :          0 :                 DRM_DEBUG_ATOMIC("[MSTB:%p] [MST PORT:%p] required PBN of %d exceeds port limit of %d\n",
    4920                 :            :                                  port->parent, port, pbn_used,
    4921                 :            :                                  port->full_pbn);
    4922                 :          0 :                 return -ENOSPC;
    4923                 :            :         }
    4924                 :            : 
    4925                 :          0 :         DRM_DEBUG_ATOMIC("[MSTB:%p] [MST PORT:%p] uses %d out of %d PBN\n",
    4926                 :            :                          port->parent, port, pbn_used, port->full_pbn);
    4927                 :            : 
    4928                 :          0 :         return pbn_used;
    4929                 :            : }
    4930                 :            : 
    4931                 :            : static inline int
    4932                 :          0 : drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
    4933                 :            :                                          struct drm_dp_mst_topology_state *mst_state)
    4934                 :            : {
    4935                 :          0 :         struct drm_dp_vcpi_allocation *vcpi;
    4936                 :          0 :         int avail_slots = 63, payload_count = 0;
    4937                 :            : 
    4938         [ #  # ]:          0 :         list_for_each_entry(vcpi, &mst_state->vcpis, next) {
    4939                 :            :                 /* Releasing VCPI is always OK-even if the port is gone */
    4940         [ #  # ]:          0 :                 if (!vcpi->vcpi) {
    4941                 :          0 :                         DRM_DEBUG_ATOMIC("[MST PORT:%p] releases all VCPI slots\n",
    4942                 :            :                                          vcpi->port);
    4943                 :          0 :                         continue;
    4944                 :            :                 }
    4945                 :            : 
    4946                 :          0 :                 DRM_DEBUG_ATOMIC("[MST PORT:%p] requires %d vcpi slots\n",
    4947                 :            :                                  vcpi->port, vcpi->vcpi);
    4948                 :            : 
    4949                 :          0 :                 avail_slots -= vcpi->vcpi;
    4950         [ #  # ]:          0 :                 if (avail_slots < 0) {
    4951                 :          0 :                         DRM_DEBUG_ATOMIC("[MST PORT:%p] not enough VCPI slots in mst state %p (avail=%d)\n",
    4952                 :            :                                          vcpi->port, mst_state,
    4953                 :            :                                          avail_slots + vcpi->vcpi);
    4954                 :          0 :                         return -ENOSPC;
    4955                 :            :                 }
    4956                 :            : 
    4957         [ #  # ]:          0 :                 if (++payload_count > mgr->max_payloads) {
    4958                 :          0 :                         DRM_DEBUG_ATOMIC("[MST MGR:%p] state %p has too many payloads (max=%d)\n",
    4959                 :            :                                          mgr, mst_state, mgr->max_payloads);
    4960                 :          0 :                         return -EINVAL;
    4961                 :            :                 }
    4962                 :            :         }
    4963                 :          0 :         DRM_DEBUG_ATOMIC("[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
    4964                 :            :                          mgr, mst_state, avail_slots,
    4965                 :            :                          63 - avail_slots);
    4966                 :            : 
    4967                 :          0 :         return 0;
    4968                 :            : }
    4969                 :            : 
    4970                 :            : /**
    4971                 :            :  * drm_dp_mst_add_affected_dsc_crtcs
    4972                 :            :  * @state: Pointer to the new struct drm_dp_mst_topology_state
    4973                 :            :  * @mgr: MST topology manager
    4974                 :            :  *
    4975                 :            :  * Whenever there is a change in mst topology
    4976                 :            :  * DSC configuration would have to be recalculated
    4977                 :            :  * therefore we need to trigger modeset on all affected
    4978                 :            :  * CRTCs in that topology
    4979                 :            :  *
    4980                 :            :  * See also:
    4981                 :            :  * drm_dp_mst_atomic_enable_dsc()
    4982                 :            :  */
    4983                 :          0 : int drm_dp_mst_add_affected_dsc_crtcs(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr)
    4984                 :            : {
    4985                 :          0 :         struct drm_dp_mst_topology_state *mst_state;
    4986                 :          0 :         struct drm_dp_vcpi_allocation *pos;
    4987                 :          0 :         struct drm_connector *connector;
    4988                 :          0 :         struct drm_connector_state *conn_state;
    4989                 :          0 :         struct drm_crtc *crtc;
    4990                 :          0 :         struct drm_crtc_state *crtc_state;
    4991                 :            : 
    4992                 :          0 :         mst_state = drm_atomic_get_mst_topology_state(state, mgr);
    4993                 :            : 
    4994                 :          0 :         if (IS_ERR(mst_state))
    4995                 :            :                 return -EINVAL;
    4996                 :            : 
    4997         [ #  # ]:          0 :         list_for_each_entry(pos, &mst_state->vcpis, next) {
    4998                 :            : 
    4999                 :          0 :                 connector = pos->port->connector;
    5000                 :            : 
    5001         [ #  # ]:          0 :                 if (!connector)
    5002                 :            :                         return -EINVAL;
    5003                 :            : 
    5004                 :          0 :                 conn_state = drm_atomic_get_connector_state(state, connector);
    5005                 :            : 
    5006         [ #  # ]:          0 :                 if (IS_ERR(conn_state))
    5007                 :          0 :                         return PTR_ERR(conn_state);
    5008                 :            : 
    5009                 :          0 :                 crtc = conn_state->crtc;
    5010                 :            : 
    5011   [ #  #  #  # ]:          0 :                 if (WARN_ON(!crtc))
    5012                 :            :                         return -EINVAL;
    5013                 :            : 
    5014         [ #  # ]:          0 :                 if (!drm_dp_mst_dsc_aux_for_port(pos->port))
    5015                 :          0 :                         continue;
    5016                 :            : 
    5017                 :          0 :                 crtc_state = drm_atomic_get_crtc_state(mst_state->base.state, crtc);
    5018                 :            : 
    5019         [ #  # ]:          0 :                 if (IS_ERR(crtc_state))
    5020                 :          0 :                         return PTR_ERR(crtc_state);
    5021                 :            : 
    5022                 :          0 :                 DRM_DEBUG_ATOMIC("[MST MGR:%p] Setting mode_changed flag on CRTC %p\n",
    5023                 :            :                                  mgr, crtc);
    5024                 :            : 
    5025                 :          0 :                 crtc_state->mode_changed = true;
    5026                 :            :         }
    5027                 :            :         return 0;
    5028                 :            : }
    5029                 :            : EXPORT_SYMBOL(drm_dp_mst_add_affected_dsc_crtcs);
    5030                 :            : 
    5031                 :            : /**
    5032                 :            :  * drm_dp_mst_atomic_enable_dsc - Set DSC Enable Flag to On/Off
    5033                 :            :  * @state: Pointer to the new drm_atomic_state
    5034                 :            :  * @port: Pointer to the affected MST Port
    5035                 :            :  * @pbn: Newly recalculated bw required for link with DSC enabled
    5036                 :            :  * @pbn_div: Divider to calculate correct number of pbn per slot
    5037                 :            :  * @enable: Boolean flag to enable or disable DSC on the port
    5038                 :            :  *
    5039                 :            :  * This function enables DSC on the given Port
    5040                 :            :  * by recalculating its vcpi from pbn provided
    5041                 :            :  * and sets dsc_enable flag to keep track of which
    5042                 :            :  * ports have DSC enabled
    5043                 :            :  *
    5044                 :            :  */
    5045                 :          0 : int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state,
    5046                 :            :                                  struct drm_dp_mst_port *port,
    5047                 :            :                                  int pbn, int pbn_div,
    5048                 :            :                                  bool enable)
    5049                 :            : {
    5050                 :          0 :         struct drm_dp_mst_topology_state *mst_state;
    5051                 :          0 :         struct drm_dp_vcpi_allocation *pos;
    5052                 :          0 :         bool found = false;
    5053                 :          0 :         int vcpi = 0;
    5054                 :            : 
    5055                 :          0 :         mst_state = drm_atomic_get_mst_topology_state(state, port->mgr);
    5056                 :            : 
    5057                 :          0 :         if (IS_ERR(mst_state))
    5058                 :          0 :                 return PTR_ERR(mst_state);
    5059                 :            : 
    5060         [ #  # ]:          0 :         list_for_each_entry(pos, &mst_state->vcpis, next) {
    5061         [ #  # ]:          0 :                 if (pos->port == port) {
    5062                 :            :                         found = true;
    5063                 :            :                         break;
    5064                 :            :                 }
    5065                 :            :         }
    5066                 :            : 
    5067         [ #  # ]:          0 :         if (!found) {
    5068                 :          0 :                 DRM_DEBUG_ATOMIC("[MST PORT:%p] Couldn't find VCPI allocation in mst state %p\n",
    5069                 :            :                                  port, mst_state);
    5070                 :          0 :                 return -EINVAL;
    5071                 :            :         }
    5072                 :            : 
    5073         [ #  # ]:          0 :         if (pos->dsc_enabled == enable) {
    5074                 :          0 :                 DRM_DEBUG_ATOMIC("[MST PORT:%p] DSC flag is already set to %d, returning %d VCPI slots\n",
    5075                 :            :                                  port, enable, pos->vcpi);
    5076                 :          0 :                 vcpi = pos->vcpi;
    5077                 :            :         }
    5078                 :            : 
    5079         [ #  # ]:          0 :         if (enable) {
    5080                 :          0 :                 vcpi = drm_dp_atomic_find_vcpi_slots(state, port->mgr, port, pbn, pbn_div);
    5081                 :          0 :                 DRM_DEBUG_ATOMIC("[MST PORT:%p] Enabling DSC flag, reallocating %d VCPI slots on the port\n",
    5082                 :            :                                  port, vcpi);
    5083         [ #  # ]:          0 :                 if (vcpi < 0)
    5084                 :            :                         return -EINVAL;
    5085                 :            :         }
    5086                 :            : 
    5087                 :          0 :         pos->dsc_enabled = enable;
    5088                 :            : 
    5089                 :          0 :         return vcpi;
    5090                 :            : }
    5091                 :            : EXPORT_SYMBOL(drm_dp_mst_atomic_enable_dsc);
    5092                 :            : /**
    5093                 :            :  * drm_dp_mst_atomic_check - Check that the new state of an MST topology in an
    5094                 :            :  * atomic update is valid
    5095                 :            :  * @state: Pointer to the new &struct drm_dp_mst_topology_state
    5096                 :            :  *
    5097                 :            :  * Checks the given topology state for an atomic update to ensure that it's
    5098                 :            :  * valid. This includes checking whether there's enough bandwidth to support
    5099                 :            :  * the new VCPI allocations in the atomic update.
    5100                 :            :  *
    5101                 :            :  * Any atomic drivers supporting DP MST must make sure to call this after
    5102                 :            :  * checking the rest of their state in their
    5103                 :            :  * &drm_mode_config_funcs.atomic_check() callback.
    5104                 :            :  *
    5105                 :            :  * See also:
    5106                 :            :  * drm_dp_atomic_find_vcpi_slots()
    5107                 :            :  * drm_dp_atomic_release_vcpi_slots()
    5108                 :            :  *
    5109                 :            :  * Returns:
    5110                 :            :  *
    5111                 :            :  * 0 if the new state is valid, negative error code otherwise.
    5112                 :            :  */
    5113                 :          0 : int drm_dp_mst_atomic_check(struct drm_atomic_state *state)
    5114                 :            : {
    5115                 :          0 :         struct drm_dp_mst_topology_mgr *mgr;
    5116                 :          0 :         struct drm_dp_mst_topology_state *mst_state;
    5117                 :          0 :         int i, ret = 0;
    5118                 :            : 
    5119   [ #  #  #  #  :          0 :         for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
                   #  # ]
    5120         [ #  # ]:          0 :                 if (!mgr->mst_state)
    5121                 :          0 :                         continue;
    5122                 :            : 
    5123                 :          0 :                 ret = drm_dp_mst_atomic_check_vcpi_alloc_limit(mgr, mst_state);
    5124         [ #  # ]:          0 :                 if (ret)
    5125                 :            :                         break;
    5126                 :            : 
    5127                 :          0 :                 mutex_lock(&mgr->lock);
    5128                 :          0 :                 ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr->mst_primary,
    5129                 :            :                                                             mst_state);
    5130                 :          0 :                 mutex_unlock(&mgr->lock);
    5131         [ #  # ]:          0 :                 if (ret < 0)
    5132                 :            :                         break;
    5133                 :            :                 else
    5134                 :            :                         ret = 0;
    5135                 :            :         }
    5136                 :            : 
    5137                 :          0 :         return ret;
    5138                 :            : }
    5139                 :            : EXPORT_SYMBOL(drm_dp_mst_atomic_check);
    5140                 :            : 
    5141                 :            : const struct drm_private_state_funcs drm_dp_mst_topology_state_funcs = {
    5142                 :            :         .atomic_duplicate_state = drm_dp_mst_duplicate_state,
    5143                 :            :         .atomic_destroy_state = drm_dp_mst_destroy_state,
    5144                 :            : };
    5145                 :            : EXPORT_SYMBOL(drm_dp_mst_topology_state_funcs);
    5146                 :            : 
    5147                 :            : /**
    5148                 :            :  * drm_atomic_get_mst_topology_state: get MST topology state
    5149                 :            :  *
    5150                 :            :  * @state: global atomic state
    5151                 :            :  * @mgr: MST topology manager, also the private object in this case
    5152                 :            :  *
    5153                 :            :  * This function wraps drm_atomic_get_priv_obj_state() passing in the MST atomic
    5154                 :            :  * state vtable so that the private object state returned is that of a MST
    5155                 :            :  * topology object. Also, drm_atomic_get_private_obj_state() expects the caller
    5156                 :            :  * to care of the locking, so warn if don't hold the connection_mutex.
    5157                 :            :  *
    5158                 :            :  * RETURNS:
    5159                 :            :  *
    5160                 :            :  * The MST topology state or error pointer.
    5161                 :            :  */
    5162                 :          0 : struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_atomic_state *state,
    5163                 :            :                                                                     struct drm_dp_mst_topology_mgr *mgr)
    5164                 :            : {
    5165   [ #  #  #  #  :          0 :         return to_dp_mst_topology_state(drm_atomic_get_private_obj_state(state, &mgr->base));
             #  #  #  # ]
    5166                 :            : }
    5167                 :            : EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
    5168                 :            : 
    5169                 :            : /**
    5170                 :            :  * drm_dp_mst_topology_mgr_init - initialise a topology manager
    5171                 :            :  * @mgr: manager struct to initialise
    5172                 :            :  * @dev: device providing this structure - for i2c addition.
    5173                 :            :  * @aux: DP helper aux channel to talk to this device
    5174                 :            :  * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
    5175                 :            :  * @max_payloads: maximum number of payloads this GPU can source
    5176                 :            :  * @conn_base_id: the connector object ID the MST device is connected to.
    5177                 :            :  *
    5178                 :            :  * Return 0 for success, or negative error code on failure
    5179                 :            :  */
    5180                 :          0 : int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
    5181                 :            :                                  struct drm_device *dev, struct drm_dp_aux *aux,
    5182                 :            :                                  int max_dpcd_transaction_bytes,
    5183                 :            :                                  int max_payloads, int conn_base_id)
    5184                 :            : {
    5185                 :          0 :         struct drm_dp_mst_topology_state *mst_state;
    5186                 :            : 
    5187                 :          0 :         mutex_init(&mgr->lock);
    5188                 :          0 :         mutex_init(&mgr->qlock);
    5189                 :          0 :         mutex_init(&mgr->payload_lock);
    5190                 :          0 :         mutex_init(&mgr->delayed_destroy_lock);
    5191                 :          0 :         mutex_init(&mgr->up_req_lock);
    5192                 :          0 :         mutex_init(&mgr->probe_lock);
    5193                 :            : #if IS_ENABLED(CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS)
    5194                 :            :         mutex_init(&mgr->topology_ref_history_lock);
    5195                 :            : #endif
    5196                 :          0 :         INIT_LIST_HEAD(&mgr->tx_msg_downq);
    5197                 :          0 :         INIT_LIST_HEAD(&mgr->destroy_port_list);
    5198                 :          0 :         INIT_LIST_HEAD(&mgr->destroy_branch_device_list);
    5199                 :          0 :         INIT_LIST_HEAD(&mgr->up_req_list);
    5200                 :          0 :         INIT_WORK(&mgr->work, drm_dp_mst_link_probe_work);
    5201                 :          0 :         INIT_WORK(&mgr->tx_work, drm_dp_tx_work);
    5202                 :          0 :         INIT_WORK(&mgr->delayed_destroy_work, drm_dp_delayed_destroy_work);
    5203                 :          0 :         INIT_WORK(&mgr->up_req_work, drm_dp_mst_up_req_work);
    5204                 :          0 :         init_waitqueue_head(&mgr->tx_waitq);
    5205                 :          0 :         mgr->dev = dev;
    5206                 :          0 :         mgr->aux = aux;
    5207                 :          0 :         mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
    5208                 :          0 :         mgr->max_payloads = max_payloads;
    5209                 :          0 :         mgr->conn_base_id = conn_base_id;
    5210         [ #  # ]:          0 :         if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 ||
    5211                 :            :             max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8)
    5212                 :            :                 return -EINVAL;
    5213                 :          0 :         mgr->payloads = kcalloc(max_payloads, sizeof(struct drm_dp_payload), GFP_KERNEL);
    5214         [ #  # ]:          0 :         if (!mgr->payloads)
    5215                 :            :                 return -ENOMEM;
    5216                 :          0 :         mgr->proposed_vcpis = kcalloc(max_payloads, sizeof(struct drm_dp_vcpi *), GFP_KERNEL);
    5217         [ #  # ]:          0 :         if (!mgr->proposed_vcpis)
    5218                 :            :                 return -ENOMEM;
    5219                 :          0 :         set_bit(0, &mgr->payload_mask);
    5220                 :            : 
    5221                 :          0 :         mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
    5222         [ #  # ]:          0 :         if (mst_state == NULL)
    5223                 :            :                 return -ENOMEM;
    5224                 :            : 
    5225                 :          0 :         mst_state->mgr = mgr;
    5226                 :          0 :         INIT_LIST_HEAD(&mst_state->vcpis);
    5227                 :            : 
    5228                 :          0 :         drm_atomic_private_obj_init(dev, &mgr->base,
    5229                 :            :                                     &mst_state->base,
    5230                 :            :                                     &drm_dp_mst_topology_state_funcs);
    5231                 :            : 
    5232                 :          0 :         return 0;
    5233                 :            : }
    5234                 :            : EXPORT_SYMBOL(drm_dp_mst_topology_mgr_init);
    5235                 :            : 
    5236                 :            : /**
    5237                 :            :  * drm_dp_mst_topology_mgr_destroy() - destroy topology manager.
    5238                 :            :  * @mgr: manager to destroy
    5239                 :            :  */
    5240                 :          0 : void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr)
    5241                 :            : {
    5242                 :          0 :         drm_dp_mst_topology_mgr_set_mst(mgr, false);
    5243                 :          0 :         flush_work(&mgr->work);
    5244                 :          0 :         cancel_work_sync(&mgr->delayed_destroy_work);
    5245                 :          0 :         mutex_lock(&mgr->payload_lock);
    5246                 :          0 :         kfree(mgr->payloads);
    5247                 :          0 :         mgr->payloads = NULL;
    5248                 :          0 :         kfree(mgr->proposed_vcpis);
    5249                 :          0 :         mgr->proposed_vcpis = NULL;
    5250                 :          0 :         mutex_unlock(&mgr->payload_lock);
    5251                 :          0 :         mgr->dev = NULL;
    5252                 :          0 :         mgr->aux = NULL;
    5253                 :          0 :         drm_atomic_private_obj_fini(&mgr->base);
    5254                 :          0 :         mgr->funcs = NULL;
    5255                 :            : 
    5256                 :          0 :         mutex_destroy(&mgr->delayed_destroy_lock);
    5257                 :          0 :         mutex_destroy(&mgr->payload_lock);
    5258                 :          0 :         mutex_destroy(&mgr->qlock);
    5259                 :          0 :         mutex_destroy(&mgr->lock);
    5260                 :          0 :         mutex_destroy(&mgr->up_req_lock);
    5261                 :          0 :         mutex_destroy(&mgr->probe_lock);
    5262                 :            : #if IS_ENABLED(CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS)
    5263                 :            :         mutex_destroy(&mgr->topology_ref_history_lock);
    5264                 :            : #endif
    5265                 :          0 : }
    5266                 :            : EXPORT_SYMBOL(drm_dp_mst_topology_mgr_destroy);
    5267                 :            : 
    5268                 :          0 : static bool remote_i2c_read_ok(const struct i2c_msg msgs[], int num)
    5269                 :            : {
    5270                 :          0 :         int i;
    5271                 :            : 
    5272         [ #  # ]:          0 :         if (num - 1 > DP_REMOTE_I2C_READ_MAX_TRANSACTIONS)
    5273                 :            :                 return false;
    5274                 :            : 
    5275         [ #  # ]:          0 :         for (i = 0; i < num - 1; i++) {
    5276         [ #  # ]:          0 :                 if (msgs[i].flags & I2C_M_RD ||
    5277         [ #  # ]:          0 :                     msgs[i].len > 0xff)
    5278                 :            :                         return false;
    5279                 :            :         }
    5280                 :            : 
    5281         [ #  # ]:          0 :         return msgs[num - 1].flags & I2C_M_RD &&
    5282         [ #  # ]:          0 :                 msgs[num - 1].len <= 0xff;
    5283                 :            : }
    5284                 :            : 
    5285                 :            : /* I2C device */
    5286                 :          0 : static int drm_dp_mst_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
    5287                 :            :                                int num)
    5288                 :            : {
    5289                 :          0 :         struct drm_dp_aux *aux = adapter->algo_data;
    5290                 :          0 :         struct drm_dp_mst_port *port = container_of(aux, struct drm_dp_mst_port, aux);
    5291                 :          0 :         struct drm_dp_mst_branch *mstb;
    5292                 :          0 :         struct drm_dp_mst_topology_mgr *mgr = port->mgr;
    5293                 :          0 :         unsigned int i;
    5294                 :          0 :         struct drm_dp_sideband_msg_req_body msg;
    5295                 :          0 :         struct drm_dp_sideband_msg_tx *txmsg = NULL;
    5296                 :          0 :         int ret;
    5297                 :            : 
    5298                 :          0 :         mstb = drm_dp_mst_topology_get_mstb_validated(mgr, port->parent);
    5299         [ #  # ]:          0 :         if (!mstb)
    5300                 :            :                 return -EREMOTEIO;
    5301                 :            : 
    5302         [ #  # ]:          0 :         if (!remote_i2c_read_ok(msgs, num)) {
    5303                 :          0 :                 DRM_DEBUG_KMS("Unsupported I2C transaction for MST device\n");
    5304                 :          0 :                 ret = -EIO;
    5305                 :          0 :                 goto out;
    5306                 :            :         }
    5307                 :            : 
    5308                 :          0 :         memset(&msg, 0, sizeof(msg));
    5309                 :          0 :         msg.req_type = DP_REMOTE_I2C_READ;
    5310                 :          0 :         msg.u.i2c_read.num_transactions = num - 1;
    5311                 :          0 :         msg.u.i2c_read.port_number = port->port_num;
    5312         [ #  # ]:          0 :         for (i = 0; i < num - 1; i++) {
    5313                 :          0 :                 msg.u.i2c_read.transactions[i].i2c_dev_id = msgs[i].addr;
    5314                 :          0 :                 msg.u.i2c_read.transactions[i].num_bytes = msgs[i].len;
    5315                 :          0 :                 msg.u.i2c_read.transactions[i].bytes = msgs[i].buf;
    5316                 :          0 :                 msg.u.i2c_read.transactions[i].no_stop_bit = !(msgs[i].flags & I2C_M_STOP);
    5317                 :            :         }
    5318                 :          0 :         msg.u.i2c_read.read_i2c_device_id = msgs[num - 1].addr;
    5319                 :          0 :         msg.u.i2c_read.num_bytes_read = msgs[num - 1].len;
    5320                 :            : 
    5321                 :          0 :         txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
    5322         [ #  # ]:          0 :         if (!txmsg) {
    5323                 :          0 :                 ret = -ENOMEM;
    5324                 :          0 :                 goto out;
    5325                 :            :         }
    5326                 :            : 
    5327                 :          0 :         txmsg->dst = mstb;
    5328                 :          0 :         drm_dp_encode_sideband_req(&msg, txmsg);
    5329                 :            : 
    5330                 :          0 :         drm_dp_queue_down_tx(mgr, txmsg);
    5331                 :            : 
    5332                 :          0 :         ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
    5333         [ #  # ]:          0 :         if (ret > 0) {
    5334                 :            : 
    5335         [ #  # ]:          0 :                 if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
    5336                 :          0 :                         ret = -EREMOTEIO;
    5337                 :          0 :                         goto out;
    5338                 :            :                 }
    5339         [ #  # ]:          0 :                 if (txmsg->reply.u.remote_i2c_read_ack.num_bytes != msgs[num - 1].len) {
    5340                 :          0 :                         ret = -EIO;
    5341                 :          0 :                         goto out;
    5342                 :            :                 }
    5343                 :          0 :                 memcpy(msgs[num - 1].buf, txmsg->reply.u.remote_i2c_read_ack.bytes, msgs[num - 1].len);
    5344                 :          0 :                 ret = num;
    5345                 :            :         }
    5346                 :          0 : out:
    5347                 :          0 :         kfree(txmsg);
    5348                 :          0 :         drm_dp_mst_topology_put_mstb(mstb);
    5349                 :          0 :         return ret;
    5350                 :            : }
    5351                 :            : 
    5352                 :          0 : static u32 drm_dp_mst_i2c_functionality(struct i2c_adapter *adapter)
    5353                 :            : {
    5354                 :          0 :         return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
    5355                 :            :                I2C_FUNC_SMBUS_READ_BLOCK_DATA |
    5356                 :            :                I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
    5357                 :            :                I2C_FUNC_10BIT_ADDR;
    5358                 :            : }
    5359                 :            : 
    5360                 :            : static const struct i2c_algorithm drm_dp_mst_i2c_algo = {
    5361                 :            :         .functionality = drm_dp_mst_i2c_functionality,
    5362                 :            :         .master_xfer = drm_dp_mst_i2c_xfer,
    5363                 :            : };
    5364                 :            : 
    5365                 :            : /**
    5366                 :            :  * drm_dp_mst_register_i2c_bus() - register an I2C adapter for I2C-over-AUX
    5367                 :            :  * @aux: DisplayPort AUX channel
    5368                 :            :  *
    5369                 :            :  * Returns 0 on success or a negative error code on failure.
    5370                 :            :  */
    5371                 :          0 : static int drm_dp_mst_register_i2c_bus(struct drm_dp_aux *aux)
    5372                 :            : {
    5373                 :          0 :         aux->ddc.algo = &drm_dp_mst_i2c_algo;
    5374                 :          0 :         aux->ddc.algo_data = aux;
    5375                 :          0 :         aux->ddc.retries = 3;
    5376                 :            : 
    5377                 :          0 :         aux->ddc.class = I2C_CLASS_DDC;
    5378                 :          0 :         aux->ddc.owner = THIS_MODULE;
    5379                 :          0 :         aux->ddc.dev.parent = aux->dev;
    5380                 :          0 :         aux->ddc.dev.of_node = aux->dev->of_node;
    5381                 :            : 
    5382         [ #  # ]:          0 :         strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(aux->dev),
    5383                 :            :                 sizeof(aux->ddc.name));
    5384                 :            : 
    5385                 :          0 :         return i2c_add_adapter(&aux->ddc);
    5386                 :            : }
    5387                 :            : 
    5388                 :            : /**
    5389                 :            :  * drm_dp_mst_unregister_i2c_bus() - unregister an I2C-over-AUX adapter
    5390                 :            :  * @aux: DisplayPort AUX channel
    5391                 :            :  */
    5392                 :          0 : static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_aux *aux)
    5393                 :            : {
    5394                 :          0 :         i2c_del_adapter(&aux->ddc);
    5395                 :          0 : }
    5396                 :            : 
    5397                 :            : /**
    5398                 :            :  * drm_dp_mst_is_virtual_dpcd() - Is the given port a virtual DP Peer Device
    5399                 :            :  * @port: The port to check
    5400                 :            :  *
    5401                 :            :  * A single physical MST hub object can be represented in the topology
    5402                 :            :  * by multiple branches, with virtual ports between those branches.
    5403                 :            :  *
    5404                 :            :  * As of DP1.4, An MST hub with internal (virtual) ports must expose
    5405                 :            :  * certain DPCD registers over those ports. See sections 2.6.1.1.1
    5406                 :            :  * and 2.6.1.1.2 of Display Port specification v1.4 for details.
    5407                 :            :  *
    5408                 :            :  * May acquire mgr->lock
    5409                 :            :  *
    5410                 :            :  * Returns:
    5411                 :            :  * true if the port is a virtual DP peer device, false otherwise
    5412                 :            :  */
    5413                 :          0 : static bool drm_dp_mst_is_virtual_dpcd(struct drm_dp_mst_port *port)
    5414                 :            : {
    5415                 :          0 :         struct drm_dp_mst_port *downstream_port;
    5416                 :            : 
    5417   [ #  #  #  # ]:          0 :         if (!port || port->dpcd_rev < DP_DPCD_REV_14)
    5418                 :            :                 return false;
    5419                 :            : 
    5420                 :            :         /* Virtual DP Sink (Internal Display Panel) */
    5421         [ #  # ]:          0 :         if (port->port_num >= 8)
    5422                 :            :                 return true;
    5423                 :            : 
    5424                 :            :         /* DP-to-HDMI Protocol Converter */
    5425         [ #  # ]:          0 :         if (port->pdt == DP_PEER_DEVICE_DP_LEGACY_CONV &&
    5426         [ #  # ]:          0 :             !port->mcs &&
    5427         [ #  # ]:          0 :             port->ldps)
    5428                 :            :                 return true;
    5429                 :            : 
    5430                 :            :         /* DP-to-DP */
    5431                 :          0 :         mutex_lock(&port->mgr->lock);
    5432         [ #  # ]:          0 :         if (port->pdt == DP_PEER_DEVICE_MST_BRANCHING &&
    5433         [ #  # ]:          0 :             port->mstb &&
    5434         [ #  # ]:          0 :             port->mstb->num_ports == 2) {
    5435         [ #  # ]:          0 :                 list_for_each_entry(downstream_port, &port->mstb->ports, next) {
    5436         [ #  # ]:          0 :                         if (downstream_port->pdt == DP_PEER_DEVICE_SST_SINK &&
    5437         [ #  # ]:          0 :                             !downstream_port->input) {
    5438                 :          0 :                                 mutex_unlock(&port->mgr->lock);
    5439                 :          0 :                                 return true;
    5440                 :            :                         }
    5441                 :            :                 }
    5442                 :            :         }
    5443                 :          0 :         mutex_unlock(&port->mgr->lock);
    5444                 :            : 
    5445                 :          0 :         return false;
    5446                 :            : }
    5447                 :            : 
    5448                 :            : /**
    5449                 :            :  * drm_dp_mst_dsc_aux_for_port() - Find the correct aux for DSC
    5450                 :            :  * @port: The port to check. A leaf of the MST tree with an attached display.
    5451                 :            :  *
    5452                 :            :  * Depending on the situation, DSC may be enabled via the endpoint aux,
    5453                 :            :  * the immediately upstream aux, or the connector's physical aux.
    5454                 :            :  *
    5455                 :            :  * This is both the correct aux to read DSC_CAPABILITY and the
    5456                 :            :  * correct aux to write DSC_ENABLED.
    5457                 :            :  *
    5458                 :            :  * This operation can be expensive (up to four aux reads), so
    5459                 :            :  * the caller should cache the return.
    5460                 :            :  *
    5461                 :            :  * Returns:
    5462                 :            :  * NULL if DSC cannot be enabled on this port, otherwise the aux device
    5463                 :            :  */
    5464                 :          0 : struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
    5465                 :            : {
    5466                 :          0 :         struct drm_dp_mst_port *immediate_upstream_port;
    5467                 :          0 :         struct drm_dp_mst_port *fec_port;
    5468                 :          0 :         struct drm_dp_desc desc = { 0 };
    5469                 :          0 :         u8 endpoint_fec;
    5470                 :          0 :         u8 endpoint_dsc;
    5471                 :            : 
    5472         [ #  # ]:          0 :         if (!port)
    5473                 :            :                 return NULL;
    5474                 :            : 
    5475         [ #  # ]:          0 :         if (port->parent->port_parent)
    5476                 :          0 :                 immediate_upstream_port = port->parent->port_parent;
    5477                 :            :         else
    5478                 :            :                 immediate_upstream_port = NULL;
    5479                 :            : 
    5480                 :          0 :         fec_port = immediate_upstream_port;
    5481         [ #  # ]:          0 :         while (fec_port) {
    5482                 :            :                 /*
    5483                 :            :                  * Each physical link (i.e. not a virtual port) between the
    5484                 :            :                  * output and the primary device must support FEC
    5485                 :            :                  */
    5486         [ #  # ]:          0 :                 if (!drm_dp_mst_is_virtual_dpcd(fec_port) &&
    5487         [ #  # ]:          0 :                     !fec_port->fec_capable)
    5488                 :            :                         return NULL;
    5489                 :            : 
    5490                 :          0 :                 fec_port = fec_port->parent->port_parent;
    5491                 :            :         }
    5492                 :            : 
    5493                 :            :         /* DP-to-DP peer device */
    5494         [ #  # ]:          0 :         if (drm_dp_mst_is_virtual_dpcd(immediate_upstream_port)) {
    5495                 :          0 :                 u8 upstream_dsc;
    5496                 :            : 
    5497         [ #  # ]:          0 :                 if (drm_dp_dpcd_read(&port->aux,
    5498                 :            :                                      DP_DSC_SUPPORT, &endpoint_dsc, 1) != 1)
    5499                 :            :                         return NULL;
    5500         [ #  # ]:          0 :                 if (drm_dp_dpcd_read(&port->aux,
    5501                 :            :                                      DP_FEC_CAPABILITY, &endpoint_fec, 1) != 1)
    5502                 :            :                         return NULL;
    5503         [ #  # ]:          0 :                 if (drm_dp_dpcd_read(&immediate_upstream_port->aux,
    5504                 :            :                                      DP_DSC_SUPPORT, &upstream_dsc, 1) != 1)
    5505                 :            :                         return NULL;
    5506                 :            : 
    5507                 :            :                 /* Enpoint decompression with DP-to-DP peer device */
    5508         [ #  # ]:          0 :                 if ((endpoint_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED) &&
    5509         [ #  # ]:          0 :                     (endpoint_fec & DP_FEC_CAPABLE) &&
    5510         [ #  # ]:          0 :                     (upstream_dsc & 0x2) /* DSC passthrough */)
    5511                 :            :                         return &port->aux;
    5512                 :            : 
    5513                 :            :                 /* Virtual DPCD decompression with DP-to-DP peer device */
    5514                 :          0 :                 return &immediate_upstream_port->aux;
    5515                 :            :         }
    5516                 :            : 
    5517                 :            :         /* Virtual DPCD decompression with DP-to-HDMI or Virtual DP Sink */
    5518         [ #  # ]:          0 :         if (drm_dp_mst_is_virtual_dpcd(port))
    5519                 :          0 :                 return &port->aux;
    5520                 :            : 
    5521                 :            :         /*
    5522                 :            :          * Synaptics quirk
    5523                 :            :          * Applies to ports for which:
    5524                 :            :          * - Physical aux has Synaptics OUI
    5525                 :            :          * - DPv1.4 or higher
    5526                 :            :          * - Port is on primary branch device
    5527                 :            :          * - Not a VGA adapter (DP_DWN_STRM_PORT_TYPE_ANALOG)
    5528                 :            :          */
    5529         [ #  # ]:          0 :         if (drm_dp_read_desc(port->mgr->aux, &desc, true))
    5530                 :            :                 return NULL;
    5531                 :            : 
    5532         [ #  # ]:          0 :         if (drm_dp_has_quirk(&desc, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD) &&
    5533         [ #  # ]:          0 :             port->mgr->dpcd[DP_DPCD_REV] >= DP_DPCD_REV_14 &&
    5534         [ #  # ]:          0 :             port->parent == port->mgr->mst_primary) {
    5535                 :          0 :                 u8 downstreamport;
    5536                 :            : 
    5537         [ #  # ]:          0 :                 if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT,
    5538                 :            :                                      &downstreamport, 1) < 0)
    5539                 :          0 :                         return NULL;
    5540                 :            : 
    5541   [ #  #  #  # ]:          0 :                 if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) &&
    5542                 :            :                    ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK)
    5543                 :            :                      != DP_DWN_STRM_PORT_TYPE_ANALOG))
    5544                 :          0 :                         return port->mgr->aux;
    5545                 :            :         }
    5546                 :            : 
    5547                 :            :         /*
    5548                 :            :          * The check below verifies if the MST sink
    5549                 :            :          * connected to the GPU is capable of DSC -
    5550                 :            :          * therefore the endpoint needs to be
    5551                 :            :          * both DSC and FEC capable.
    5552                 :            :          */
    5553         [ #  # ]:          0 :         if (drm_dp_dpcd_read(&port->aux,
    5554                 :            :            DP_DSC_SUPPORT, &endpoint_dsc, 1) != 1)
    5555                 :            :                 return NULL;
    5556         [ #  # ]:          0 :         if (drm_dp_dpcd_read(&port->aux,
    5557                 :            :            DP_FEC_CAPABILITY, &endpoint_fec, 1) != 1)
    5558                 :            :                 return NULL;
    5559         [ #  # ]:          0 :         if ((endpoint_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED) &&
    5560         [ #  # ]:          0 :            (endpoint_fec & DP_FEC_CAPABLE))
    5561                 :          0 :                 return &port->aux;
    5562                 :            : 
    5563                 :            :         return NULL;
    5564                 :            : }
    5565                 :            : EXPORT_SYMBOL(drm_dp_mst_dsc_aux_for_port);

Generated by: LCOV version 1.14