LCOV - code coverage report
Current view: top level - dev/pci/drm - drm_dp_mst_topology.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 1474 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 102 0.0 %
Legend: Lines: hit not hit

          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             : #ifdef __linux__
      24             : #include <linux/kernel.h>
      25             : #include <linux/delay.h>
      26             : #include <linux/init.h>
      27             : #include <linux/errno.h>
      28             : #include <linux/sched.h>
      29             : #include <linux/seq_file.h>
      30             : #include <linux/i2c.h>
      31             : #endif
      32             : #include <dev/pci/drm/drm_dp_mst_helper.h>
      33             : #include <dev/pci/drm/drmP.h>
      34             : 
      35             : #include <dev/pci/drm/drm_fixed.h>
      36             : 
      37             : /**
      38             :  * DOC: dp mst helper
      39             :  *
      40             :  * These functions contain parts of the DisplayPort 1.2a MultiStream Transport
      41             :  * protocol. The helpers contain a topology manager and bandwidth manager.
      42             :  * The helpers encapsulate the sending and received of sideband msgs.
      43             :  */
      44             : #ifdef __linux__
      45             : static bool dump_dp_payload_table(struct drm_dp_mst_topology_mgr *mgr,
      46             :                                   char *buf);
      47             : #endif
      48             : static int test_calc_pbn_mode(void);
      49             : 
      50             : static void drm_dp_put_port(struct drm_dp_mst_port *port);
      51             : 
      52             : static int drm_dp_dpcd_write_payload(struct drm_dp_mst_topology_mgr *mgr,
      53             :                                      int id,
      54             :                                      struct drm_dp_payload *payload);
      55             : 
      56             : static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr,
      57             :                                   struct drm_dp_mst_port *port,
      58             :                                   int offset, int size, u8 *bytes);
      59             : 
      60             : static void drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
      61             :                                      struct drm_dp_mst_branch *mstb);
      62             : static int drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr,
      63             :                                            struct drm_dp_mst_branch *mstb,
      64             :                                            struct drm_dp_mst_port *port);
      65             : static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr,
      66             :                                  u8 *guid);
      67             : 
      68             : static int drm_dp_mst_register_i2c_bus(struct drm_dp_aux *aux);
      69             : static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_aux *aux);
      70             : static void drm_dp_mst_kick_tx(struct drm_dp_mst_topology_mgr *mgr);
      71             : /* sideband msg handling */
      72           0 : static u8 drm_dp_msg_header_crc4(const uint8_t *data, size_t num_nibbles)
      73             : {
      74             :         u8 bitmask = 0x80;
      75             :         u8 bitshift = 7;
      76             :         u8 array_index = 0;
      77           0 :         int number_of_bits = num_nibbles * 4;
      78             :         u8 remainder = 0;
      79             : 
      80           0 :         while (number_of_bits != 0) {
      81           0 :                 number_of_bits--;
      82           0 :                 remainder <<= 1;
      83           0 :                 remainder |= (data[array_index] & bitmask) >> bitshift;
      84           0 :                 bitmask >>= 1;
      85           0 :                 bitshift--;
      86           0 :                 if (bitmask == 0) {
      87             :                         bitmask = 0x80;
      88             :                         bitshift = 7;
      89           0 :                         array_index++;
      90           0 :                 }
      91           0 :                 if ((remainder & 0x10) == 0x10)
      92           0 :                         remainder ^= 0x13;
      93             :         }
      94             : 
      95             :         number_of_bits = 4;
      96           0 :         while (number_of_bits != 0) {
      97           0 :                 number_of_bits--;
      98           0 :                 remainder <<= 1;
      99           0 :                 if ((remainder & 0x10) != 0)
     100           0 :                         remainder ^= 0x13;
     101             :         }
     102             : 
     103           0 :         return remainder;
     104             : }
     105             : 
     106           0 : static u8 drm_dp_msg_data_crc4(const uint8_t *data, u8 number_of_bytes)
     107             : {
     108             :         u8 bitmask = 0x80;
     109             :         u8 bitshift = 7;
     110             :         u8 array_index = 0;
     111           0 :         int number_of_bits = number_of_bytes * 8;
     112             :         u16 remainder = 0;
     113             : 
     114           0 :         while (number_of_bits != 0) {
     115           0 :                 number_of_bits--;
     116           0 :                 remainder <<= 1;
     117           0 :                 remainder |= (data[array_index] & bitmask) >> bitshift;
     118           0 :                 bitmask >>= 1;
     119           0 :                 bitshift--;
     120           0 :                 if (bitmask == 0) {
     121             :                         bitmask = 0x80;
     122             :                         bitshift = 7;
     123           0 :                         array_index++;
     124           0 :                 }
     125           0 :                 if ((remainder & 0x100) == 0x100)
     126           0 :                         remainder ^= 0xd5;
     127             :         }
     128             : 
     129             :         number_of_bits = 8;
     130           0 :         while (number_of_bits != 0) {
     131           0 :                 number_of_bits--;
     132           0 :                 remainder <<= 1;
     133           0 :                 if ((remainder & 0x100) != 0)
     134           0 :                         remainder ^= 0xd5;
     135             :         }
     136             : 
     137           0 :         return remainder & 0xff;
     138             : }
     139           0 : static inline u8 drm_dp_calc_sb_hdr_size(struct drm_dp_sideband_msg_hdr *hdr)
     140             : {
     141             :         u8 size = 3;
     142           0 :         size += (hdr->lct / 2);
     143           0 :         return size;
     144             : }
     145             : 
     146           0 : static void drm_dp_encode_sideband_msg_hdr(struct drm_dp_sideband_msg_hdr *hdr,
     147             :                                            u8 *buf, int *len)
     148             : {
     149             :         int idx = 0;
     150             :         int i;
     151             :         u8 crc4;
     152           0 :         buf[idx++] = ((hdr->lct & 0xf) << 4) | (hdr->lcr & 0xf);
     153           0 :         for (i = 0; i < (hdr->lct / 2); i++)
     154           0 :                 buf[idx++] = hdr->rad[i];
     155           0 :         buf[idx++] = (hdr->broadcast << 7) | (hdr->path_msg << 6) |
     156           0 :                 (hdr->msg_len & 0x3f);
     157           0 :         buf[idx++] = (hdr->somt << 7) | (hdr->eomt << 6) | (hdr->seqno << 4);
     158             : 
     159           0 :         crc4 = drm_dp_msg_header_crc4(buf, (idx * 2) - 1);
     160           0 :         buf[idx - 1] |= (crc4 & 0xf);
     161             : 
     162           0 :         *len = idx;
     163           0 : }
     164             : 
     165           0 : static bool drm_dp_decode_sideband_msg_hdr(struct drm_dp_sideband_msg_hdr *hdr,
     166             :                                            u8 *buf, int buflen, u8 *hdrlen)
     167             : {
     168             :         u8 crc4;
     169             :         u8 len;
     170             :         int i;
     171             :         u8 idx;
     172           0 :         if (buf[0] == 0)
     173           0 :                 return false;
     174             :         len = 3;
     175           0 :         len += ((buf[0] & 0xf0) >> 4) / 2;
     176           0 :         if (len > buflen)
     177           0 :                 return false;
     178           0 :         crc4 = drm_dp_msg_header_crc4(buf, (len * 2) - 1);
     179             : 
     180           0 :         if ((crc4 & 0xf) != (buf[len - 1] & 0xf)) {
     181             :                 DRM_DEBUG_KMS("crc4 mismatch 0x%x 0x%x\n", crc4, buf[len - 1]);
     182           0 :                 return false;
     183             :         }
     184             : 
     185           0 :         hdr->lct = (buf[0] & 0xf0) >> 4;
     186           0 :         hdr->lcr = (buf[0] & 0xf);
     187             :         idx = 1;
     188           0 :         for (i = 0; i < (hdr->lct / 2); i++)
     189           0 :                 hdr->rad[i] = buf[idx++];
     190           0 :         hdr->broadcast = (buf[idx] >> 7) & 0x1;
     191           0 :         hdr->path_msg = (buf[idx] >> 6) & 0x1;
     192           0 :         hdr->msg_len = buf[idx] & 0x3f;
     193           0 :         idx++;
     194           0 :         hdr->somt = (buf[idx] >> 7) & 0x1;
     195           0 :         hdr->eomt = (buf[idx] >> 6) & 0x1;
     196           0 :         hdr->seqno = (buf[idx] >> 4) & 0x1;
     197           0 :         idx++;
     198           0 :         *hdrlen = idx;
     199           0 :         return true;
     200           0 : }
     201             : 
     202           0 : static void drm_dp_encode_sideband_req(struct drm_dp_sideband_msg_req_body *req,
     203             :                                        struct drm_dp_sideband_msg_tx *raw)
     204             : {
     205             :         int idx = 0;
     206             :         int i;
     207           0 :         u8 *buf = raw->msg;
     208           0 :         buf[idx++] = req->req_type & 0x7f;
     209             : 
     210           0 :         switch (req->req_type) {
     211             :         case DP_ENUM_PATH_RESOURCES:
     212           0 :                 buf[idx] = (req->u.port_num.port_number & 0xf) << 4;
     213             :                 idx++;
     214           0 :                 break;
     215             :         case DP_ALLOCATE_PAYLOAD:
     216           0 :                 buf[idx] = (req->u.allocate_payload.port_number & 0xf) << 4 |
     217           0 :                         (req->u.allocate_payload.number_sdp_streams & 0xf);
     218             :                 idx++;
     219           0 :                 buf[idx] = (req->u.allocate_payload.vcpi & 0x7f);
     220             :                 idx++;
     221           0 :                 buf[idx] = (req->u.allocate_payload.pbn >> 8);
     222             :                 idx++;
     223           0 :                 buf[idx] = (req->u.allocate_payload.pbn & 0xff);
     224             :                 idx++;
     225           0 :                 for (i = 0; i < req->u.allocate_payload.number_sdp_streams / 2; i++) {
     226           0 :                         buf[idx] = ((req->u.allocate_payload.sdp_stream_sink[i * 2] & 0xf) << 4) |
     227           0 :                                 (req->u.allocate_payload.sdp_stream_sink[i * 2 + 1] & 0xf);
     228           0 :                         idx++;
     229             :                 }
     230           0 :                 if (req->u.allocate_payload.number_sdp_streams & 1) {
     231           0 :                         i = req->u.allocate_payload.number_sdp_streams - 1;
     232           0 :                         buf[idx] = (req->u.allocate_payload.sdp_stream_sink[i] & 0xf) << 4;
     233           0 :                         idx++;
     234           0 :                 }
     235             :                 break;
     236             :         case DP_QUERY_PAYLOAD:
     237           0 :                 buf[idx] = (req->u.query_payload.port_number & 0xf) << 4;
     238             :                 idx++;
     239           0 :                 buf[idx] = (req->u.query_payload.vcpi & 0x7f);
     240             :                 idx++;
     241           0 :                 break;
     242             :         case DP_REMOTE_DPCD_READ:
     243           0 :                 buf[idx] = (req->u.dpcd_read.port_number & 0xf) << 4;
     244           0 :                 buf[idx] |= ((req->u.dpcd_read.dpcd_address & 0xf0000) >> 16) & 0xf;
     245             :                 idx++;
     246           0 :                 buf[idx] = (req->u.dpcd_read.dpcd_address & 0xff00) >> 8;
     247             :                 idx++;
     248           0 :                 buf[idx] = (req->u.dpcd_read.dpcd_address & 0xff);
     249             :                 idx++;
     250           0 :                 buf[idx] = (req->u.dpcd_read.num_bytes);
     251             :                 idx++;
     252           0 :                 break;
     253             : 
     254             :         case DP_REMOTE_DPCD_WRITE:
     255           0 :                 buf[idx] = (req->u.dpcd_write.port_number & 0xf) << 4;
     256           0 :                 buf[idx] |= ((req->u.dpcd_write.dpcd_address & 0xf0000) >> 16) & 0xf;
     257             :                 idx++;
     258           0 :                 buf[idx] = (req->u.dpcd_write.dpcd_address & 0xff00) >> 8;
     259             :                 idx++;
     260           0 :                 buf[idx] = (req->u.dpcd_write.dpcd_address & 0xff);
     261             :                 idx++;
     262           0 :                 buf[idx] = (req->u.dpcd_write.num_bytes);
     263             :                 idx++;
     264           0 :                 memcpy(&buf[idx], req->u.dpcd_write.bytes, req->u.dpcd_write.num_bytes);
     265           0 :                 idx += req->u.dpcd_write.num_bytes;
     266           0 :                 break;
     267             :         case DP_REMOTE_I2C_READ:
     268           0 :                 buf[idx] = (req->u.i2c_read.port_number & 0xf) << 4;
     269           0 :                 buf[idx] |= (req->u.i2c_read.num_transactions & 0x3);
     270             :                 idx++;
     271           0 :                 for (i = 0; i < (req->u.i2c_read.num_transactions & 0x3); i++) {
     272           0 :                         buf[idx] = req->u.i2c_read.transactions[i].i2c_dev_id & 0x7f;
     273           0 :                         idx++;
     274           0 :                         buf[idx] = req->u.i2c_read.transactions[i].num_bytes;
     275           0 :                         idx++;
     276           0 :                         memcpy(&buf[idx], req->u.i2c_read.transactions[i].bytes, req->u.i2c_read.transactions[i].num_bytes);
     277           0 :                         idx += req->u.i2c_read.transactions[i].num_bytes;
     278             : 
     279           0 :                         buf[idx] = (req->u.i2c_read.transactions[i].no_stop_bit & 0x1) << 5;
     280           0 :                         buf[idx] |= (req->u.i2c_read.transactions[i].i2c_transaction_delay & 0xf);
     281           0 :                         idx++;
     282             :                 }
     283           0 :                 buf[idx] = (req->u.i2c_read.read_i2c_device_id) & 0x7f;
     284           0 :                 idx++;
     285           0 :                 buf[idx] = (req->u.i2c_read.num_bytes_read);
     286           0 :                 idx++;
     287           0 :                 break;
     288             : 
     289             :         case DP_REMOTE_I2C_WRITE:
     290           0 :                 buf[idx] = (req->u.i2c_write.port_number & 0xf) << 4;
     291             :                 idx++;
     292           0 :                 buf[idx] = (req->u.i2c_write.write_i2c_device_id) & 0x7f;
     293             :                 idx++;
     294           0 :                 buf[idx] = (req->u.i2c_write.num_bytes);
     295             :                 idx++;
     296           0 :                 memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);
     297           0 :                 idx += req->u.i2c_write.num_bytes;
     298           0 :                 break;
     299             :         }
     300           0 :         raw->cur_len = idx;
     301           0 : }
     302             : 
     303           0 : static void drm_dp_crc_sideband_chunk_req(u8 *msg, u8 len)
     304             : {
     305             :         u8 crc4;
     306           0 :         crc4 = drm_dp_msg_data_crc4(msg, len);
     307           0 :         msg[len] = crc4;
     308           0 : }
     309             : 
     310           0 : static void drm_dp_encode_sideband_reply(struct drm_dp_sideband_msg_reply_body *rep,
     311             :                                          struct drm_dp_sideband_msg_tx *raw)
     312             : {
     313             :         int idx = 0;
     314           0 :         u8 *buf = raw->msg;
     315             : 
     316           0 :         buf[idx++] = (rep->reply_type & 0x1) << 7 | (rep->req_type & 0x7f);
     317             : 
     318           0 :         raw->cur_len = idx;
     319           0 : }
     320             : 
     321             : /* this adds a chunk of msg to the builder to get the final msg */
     322           0 : static bool drm_dp_sideband_msg_build(struct drm_dp_sideband_msg_rx *msg,
     323             :                                       u8 *replybuf, u8 replybuflen, bool hdr)
     324             : {
     325             :         int ret;
     326             :         u8 crc4;
     327             : 
     328           0 :         if (hdr) {
     329           0 :                 u8 hdrlen;
     330           0 :                 struct drm_dp_sideband_msg_hdr recv_hdr;
     331           0 :                 ret = drm_dp_decode_sideband_msg_hdr(&recv_hdr, replybuf, replybuflen, &hdrlen);
     332           0 :                 if (ret == false) {
     333           0 :                         print_hex_dump(KERN_DEBUG, "failed hdr", DUMP_PREFIX_NONE, 16, 1, replybuf, replybuflen, false);
     334           0 :                         return false;
     335             :                 }
     336             : 
     337             :                 /*
     338             :                  * ignore out-of-order messages or messages that are part of a
     339             :                  * failed transaction
     340             :                  */
     341           0 :                 if (!recv_hdr.somt && !msg->have_somt)
     342           0 :                         return false;
     343             : 
     344             :                 /* get length contained in this portion */
     345           0 :                 msg->curchunk_len = recv_hdr.msg_len;
     346           0 :                 msg->curchunk_hdrlen = hdrlen;
     347             : 
     348             :                 /* we have already gotten an somt - don't bother parsing */
     349           0 :                 if (recv_hdr.somt && msg->have_somt)
     350           0 :                         return false;
     351             : 
     352           0 :                 if (recv_hdr.somt) {
     353           0 :                         memcpy(&msg->initial_hdr, &recv_hdr, sizeof(struct drm_dp_sideband_msg_hdr));
     354           0 :                         msg->have_somt = true;
     355           0 :                 }
     356           0 :                 if (recv_hdr.eomt)
     357           0 :                         msg->have_eomt = true;
     358             : 
     359             :                 /* copy the bytes for the remainder of this header chunk */
     360           0 :                 msg->curchunk_idx = min(msg->curchunk_len, (u8)(replybuflen - hdrlen));
     361           0 :                 memcpy(&msg->chunk[0], replybuf + hdrlen, msg->curchunk_idx);
     362           0 :         } else {
     363           0 :                 memcpy(&msg->chunk[msg->curchunk_idx], replybuf, replybuflen);
     364           0 :                 msg->curchunk_idx += replybuflen;
     365             :         }
     366             : 
     367           0 :         if (msg->curchunk_idx >= msg->curchunk_len) {
     368             :                 /* do CRC */
     369           0 :                 crc4 = drm_dp_msg_data_crc4(msg->chunk, msg->curchunk_len - 1);
     370             :                 /* copy chunk into bigger msg */
     371           0 :                 memcpy(&msg->msg[msg->curlen], msg->chunk, msg->curchunk_len - 1);
     372           0 :                 msg->curlen += msg->curchunk_len - 1;
     373           0 :         }
     374           0 :         return true;
     375           0 : }
     376             : 
     377           0 : static bool drm_dp_sideband_parse_link_address(struct drm_dp_sideband_msg_rx *raw,
     378             :                                                struct drm_dp_sideband_msg_reply_body *repmsg)
     379             : {
     380             :         int idx = 1;
     381             :         int i;
     382           0 :         memcpy(repmsg->u.link_addr.guid, &raw->msg[idx], 16);
     383             :         idx += 16;
     384           0 :         repmsg->u.link_addr.nports = raw->msg[idx] & 0xf;
     385             :         idx++;
     386           0 :         if (idx > raw->curlen)
     387             :                 goto fail_len;
     388           0 :         for (i = 0; i < repmsg->u.link_addr.nports; i++) {
     389           0 :                 if (raw->msg[idx] & 0x80)
     390           0 :                         repmsg->u.link_addr.ports[i].input_port = 1;
     391             : 
     392           0 :                 repmsg->u.link_addr.ports[i].peer_device_type = (raw->msg[idx] >> 4) & 0x7;
     393           0 :                 repmsg->u.link_addr.ports[i].port_number = (raw->msg[idx] & 0xf);
     394             : 
     395           0 :                 idx++;
     396           0 :                 if (idx > raw->curlen)
     397             :                         goto fail_len;
     398           0 :                 repmsg->u.link_addr.ports[i].mcs = (raw->msg[idx] >> 7) & 0x1;
     399           0 :                 repmsg->u.link_addr.ports[i].ddps = (raw->msg[idx] >> 6) & 0x1;
     400           0 :                 if (repmsg->u.link_addr.ports[i].input_port == 0)
     401           0 :                         repmsg->u.link_addr.ports[i].legacy_device_plug_status = (raw->msg[idx] >> 5) & 0x1;
     402           0 :                 idx++;
     403           0 :                 if (idx > raw->curlen)
     404             :                         goto fail_len;
     405           0 :                 if (repmsg->u.link_addr.ports[i].input_port == 0) {
     406           0 :                         repmsg->u.link_addr.ports[i].dpcd_revision = (raw->msg[idx]);
     407           0 :                         idx++;
     408           0 :                         if (idx > raw->curlen)
     409             :                                 goto fail_len;
     410           0 :                         memcpy(repmsg->u.link_addr.ports[i].peer_guid, &raw->msg[idx], 16);
     411           0 :                         idx += 16;
     412           0 :                         if (idx > raw->curlen)
     413             :                                 goto fail_len;
     414           0 :                         repmsg->u.link_addr.ports[i].num_sdp_streams = (raw->msg[idx] >> 4) & 0xf;
     415           0 :                         repmsg->u.link_addr.ports[i].num_sdp_stream_sinks = (raw->msg[idx] & 0xf);
     416           0 :                         idx++;
     417             : 
     418           0 :                 }
     419           0 :                 if (idx > raw->curlen)
     420             :                         goto fail_len;
     421             :         }
     422             : 
     423           0 :         return true;
     424             : fail_len:
     425             :         DRM_DEBUG_KMS("link address reply parse length fail %d %d\n", idx, raw->curlen);
     426           0 :         return false;
     427           0 : }
     428             : 
     429           0 : static bool drm_dp_sideband_parse_remote_dpcd_read(struct drm_dp_sideband_msg_rx *raw,
     430             :                                                    struct drm_dp_sideband_msg_reply_body *repmsg)
     431             : {
     432             :         int idx = 1;
     433           0 :         repmsg->u.remote_dpcd_read_ack.port_number = raw->msg[idx] & 0xf;
     434             :         idx++;
     435           0 :         if (idx > raw->curlen)
     436             :                 goto fail_len;
     437           0 :         repmsg->u.remote_dpcd_read_ack.num_bytes = raw->msg[idx];
     438           0 :         if (idx > raw->curlen)
     439             :                 goto fail_len;
     440             : 
     441           0 :         memcpy(repmsg->u.remote_dpcd_read_ack.bytes, &raw->msg[idx], repmsg->u.remote_dpcd_read_ack.num_bytes);
     442           0 :         return true;
     443             : fail_len:
     444             :         DRM_DEBUG_KMS("link address reply parse length fail %d %d\n", idx, raw->curlen);
     445           0 :         return false;
     446           0 : }
     447             : 
     448           0 : static bool drm_dp_sideband_parse_remote_dpcd_write(struct drm_dp_sideband_msg_rx *raw,
     449             :                                                       struct drm_dp_sideband_msg_reply_body *repmsg)
     450             : {
     451             :         int idx = 1;
     452           0 :         repmsg->u.remote_dpcd_write_ack.port_number = raw->msg[idx] & 0xf;
     453             :         idx++;
     454           0 :         if (idx > raw->curlen)
     455             :                 goto fail_len;
     456           0 :         return true;
     457             : fail_len:
     458             :         DRM_DEBUG_KMS("parse length fail %d %d\n", idx, raw->curlen);
     459           0 :         return false;
     460           0 : }
     461             : 
     462           0 : static bool drm_dp_sideband_parse_remote_i2c_read_ack(struct drm_dp_sideband_msg_rx *raw,
     463             :                                                       struct drm_dp_sideband_msg_reply_body *repmsg)
     464             : {
     465             :         int idx = 1;
     466             : 
     467           0 :         repmsg->u.remote_i2c_read_ack.port_number = (raw->msg[idx] & 0xf);
     468             :         idx++;
     469           0 :         if (idx > raw->curlen)
     470             :                 goto fail_len;
     471           0 :         repmsg->u.remote_i2c_read_ack.num_bytes = raw->msg[idx];
     472             :         idx++;
     473             :         /* TODO check */
     474           0 :         memcpy(repmsg->u.remote_i2c_read_ack.bytes, &raw->msg[idx], repmsg->u.remote_i2c_read_ack.num_bytes);
     475           0 :         return true;
     476             : fail_len:
     477             :         DRM_DEBUG_KMS("remote i2c reply parse length fail %d %d\n", idx, raw->curlen);
     478           0 :         return false;
     479           0 : }
     480             : 
     481           0 : static bool drm_dp_sideband_parse_enum_path_resources_ack(struct drm_dp_sideband_msg_rx *raw,
     482             :                                                           struct drm_dp_sideband_msg_reply_body *repmsg)
     483             : {
     484             :         int idx = 1;
     485           0 :         repmsg->u.path_resources.port_number = (raw->msg[idx] >> 4) & 0xf;
     486             :         idx++;
     487           0 :         if (idx > raw->curlen)
     488             :                 goto fail_len;
     489           0 :         repmsg->u.path_resources.full_payload_bw_number = (raw->msg[idx] << 8) | (raw->msg[idx+1]);
     490             :         idx += 2;
     491           0 :         if (idx > raw->curlen)
     492             :                 goto fail_len;
     493           0 :         repmsg->u.path_resources.avail_payload_bw_number = (raw->msg[idx] << 8) | (raw->msg[idx+1]);
     494             :         idx += 2;
     495           0 :         if (idx > raw->curlen)
     496             :                 goto fail_len;
     497           0 :         return true;
     498             : fail_len:
     499             :         DRM_DEBUG_KMS("enum resource parse length fail %d %d\n", idx, raw->curlen);
     500           0 :         return false;
     501           0 : }
     502             : 
     503           0 : static bool drm_dp_sideband_parse_allocate_payload_ack(struct drm_dp_sideband_msg_rx *raw,
     504             :                                                           struct drm_dp_sideband_msg_reply_body *repmsg)
     505             : {
     506             :         int idx = 1;
     507           0 :         repmsg->u.allocate_payload.port_number = (raw->msg[idx] >> 4) & 0xf;
     508             :         idx++;
     509           0 :         if (idx > raw->curlen)
     510             :                 goto fail_len;
     511           0 :         repmsg->u.allocate_payload.vcpi = raw->msg[idx];
     512             :         idx++;
     513           0 :         if (idx > raw->curlen)
     514             :                 goto fail_len;
     515           0 :         repmsg->u.allocate_payload.allocated_pbn = (raw->msg[idx] << 8) | (raw->msg[idx+1]);
     516             :         idx += 2;
     517           0 :         if (idx > raw->curlen)
     518             :                 goto fail_len;
     519           0 :         return true;
     520             : fail_len:
     521             :         DRM_DEBUG_KMS("allocate payload parse length fail %d %d\n", idx, raw->curlen);
     522           0 :         return false;
     523           0 : }
     524             : 
     525           0 : static bool drm_dp_sideband_parse_query_payload_ack(struct drm_dp_sideband_msg_rx *raw,
     526             :                                                     struct drm_dp_sideband_msg_reply_body *repmsg)
     527             : {
     528             :         int idx = 1;
     529           0 :         repmsg->u.query_payload.port_number = (raw->msg[idx] >> 4) & 0xf;
     530             :         idx++;
     531           0 :         if (idx > raw->curlen)
     532             :                 goto fail_len;
     533           0 :         repmsg->u.query_payload.allocated_pbn = (raw->msg[idx] << 8) | (raw->msg[idx + 1]);
     534             :         idx += 2;
     535           0 :         if (idx > raw->curlen)
     536             :                 goto fail_len;
     537           0 :         return true;
     538             : fail_len:
     539             :         DRM_DEBUG_KMS("query payload parse length fail %d %d\n", idx, raw->curlen);
     540           0 :         return false;
     541           0 : }
     542             : 
     543           0 : static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
     544             :                                         struct drm_dp_sideband_msg_reply_body *msg)
     545             : {
     546           0 :         memset(msg, 0, sizeof(*msg));
     547           0 :         msg->reply_type = (raw->msg[0] & 0x80) >> 7;
     548           0 :         msg->req_type = (raw->msg[0] & 0x7f);
     549             : 
     550           0 :         if (msg->reply_type) {
     551           0 :                 memcpy(msg->u.nak.guid, &raw->msg[1], 16);
     552           0 :                 msg->u.nak.reason = raw->msg[17];
     553           0 :                 msg->u.nak.nak_data = raw->msg[18];
     554           0 :                 return false;
     555             :         }
     556             : 
     557           0 :         switch (msg->req_type) {
     558             :         case DP_LINK_ADDRESS:
     559           0 :                 return drm_dp_sideband_parse_link_address(raw, msg);
     560             :         case DP_QUERY_PAYLOAD:
     561           0 :                 return drm_dp_sideband_parse_query_payload_ack(raw, msg);
     562             :         case DP_REMOTE_DPCD_READ:
     563           0 :                 return drm_dp_sideband_parse_remote_dpcd_read(raw, msg);
     564             :         case DP_REMOTE_DPCD_WRITE:
     565           0 :                 return drm_dp_sideband_parse_remote_dpcd_write(raw, msg);
     566             :         case DP_REMOTE_I2C_READ:
     567           0 :                 return drm_dp_sideband_parse_remote_i2c_read_ack(raw, msg);
     568             :         case DP_ENUM_PATH_RESOURCES:
     569           0 :                 return drm_dp_sideband_parse_enum_path_resources_ack(raw, msg);
     570             :         case DP_ALLOCATE_PAYLOAD:
     571           0 :                 return drm_dp_sideband_parse_allocate_payload_ack(raw, msg);
     572             :         default:
     573           0 :                 DRM_ERROR("Got unknown reply 0x%02x\n", msg->req_type);
     574           0 :                 return false;
     575             :         }
     576           0 : }
     577             : 
     578           0 : static bool drm_dp_sideband_parse_connection_status_notify(struct drm_dp_sideband_msg_rx *raw,
     579             :                                                            struct drm_dp_sideband_msg_req_body *msg)
     580             : {
     581             :         int idx = 1;
     582             : 
     583           0 :         msg->u.conn_stat.port_number = (raw->msg[idx] & 0xf0) >> 4;
     584             :         idx++;
     585           0 :         if (idx > raw->curlen)
     586             :                 goto fail_len;
     587             : 
     588           0 :         memcpy(msg->u.conn_stat.guid, &raw->msg[idx], 16);
     589             :         idx += 16;
     590           0 :         if (idx > raw->curlen)
     591             :                 goto fail_len;
     592             : 
     593           0 :         msg->u.conn_stat.legacy_device_plug_status = (raw->msg[idx] >> 6) & 0x1;
     594           0 :         msg->u.conn_stat.displayport_device_plug_status = (raw->msg[idx] >> 5) & 0x1;
     595           0 :         msg->u.conn_stat.message_capability_status = (raw->msg[idx] >> 4) & 0x1;
     596           0 :         msg->u.conn_stat.input_port = (raw->msg[idx] >> 3) & 0x1;
     597           0 :         msg->u.conn_stat.peer_device_type = (raw->msg[idx] & 0x7);
     598             :         idx++;
     599           0 :         return true;
     600             : fail_len:
     601             :         DRM_DEBUG_KMS("connection status reply parse length fail %d %d\n", idx, raw->curlen);
     602           0 :         return false;
     603           0 : }
     604             : 
     605           0 : static bool drm_dp_sideband_parse_resource_status_notify(struct drm_dp_sideband_msg_rx *raw,
     606             :                                                            struct drm_dp_sideband_msg_req_body *msg)
     607             : {
     608             :         int idx = 1;
     609             : 
     610           0 :         msg->u.resource_stat.port_number = (raw->msg[idx] & 0xf0) >> 4;
     611             :         idx++;
     612           0 :         if (idx > raw->curlen)
     613             :                 goto fail_len;
     614             : 
     615           0 :         memcpy(msg->u.resource_stat.guid, &raw->msg[idx], 16);
     616             :         idx += 16;
     617           0 :         if (idx > raw->curlen)
     618             :                 goto fail_len;
     619             : 
     620           0 :         msg->u.resource_stat.available_pbn = (raw->msg[idx] << 8) | (raw->msg[idx + 1]);
     621             :         idx++;
     622           0 :         return true;
     623             : fail_len:
     624             :         DRM_DEBUG_KMS("resource status reply parse length fail %d %d\n", idx, raw->curlen);
     625           0 :         return false;
     626           0 : }
     627             : 
     628           0 : static bool drm_dp_sideband_parse_req(struct drm_dp_sideband_msg_rx *raw,
     629             :                                       struct drm_dp_sideband_msg_req_body *msg)
     630             : {
     631           0 :         memset(msg, 0, sizeof(*msg));
     632           0 :         msg->req_type = (raw->msg[0] & 0x7f);
     633             : 
     634           0 :         switch (msg->req_type) {
     635             :         case DP_CONNECTION_STATUS_NOTIFY:
     636           0 :                 return drm_dp_sideband_parse_connection_status_notify(raw, msg);
     637             :         case DP_RESOURCE_STATUS_NOTIFY:
     638           0 :                 return drm_dp_sideband_parse_resource_status_notify(raw, msg);
     639             :         default:
     640           0 :                 DRM_ERROR("Got unknown request 0x%02x\n", msg->req_type);
     641           0 :                 return false;
     642             :         }
     643           0 : }
     644             : 
     645           0 : static int build_dpcd_write(struct drm_dp_sideband_msg_tx *msg, u8 port_num, u32 offset, u8 num_bytes, u8 *bytes)
     646             : {
     647           0 :         struct drm_dp_sideband_msg_req_body req;
     648             : 
     649           0 :         req.req_type = DP_REMOTE_DPCD_WRITE;
     650           0 :         req.u.dpcd_write.port_number = port_num;
     651           0 :         req.u.dpcd_write.dpcd_address = offset;
     652           0 :         req.u.dpcd_write.num_bytes = num_bytes;
     653           0 :         req.u.dpcd_write.bytes = bytes;
     654           0 :         drm_dp_encode_sideband_req(&req, msg);
     655             : 
     656           0 :         return 0;
     657           0 : }
     658             : 
     659           0 : static int build_link_address(struct drm_dp_sideband_msg_tx *msg)
     660             : {
     661           0 :         struct drm_dp_sideband_msg_req_body req;
     662             : 
     663           0 :         req.req_type = DP_LINK_ADDRESS;
     664           0 :         drm_dp_encode_sideband_req(&req, msg);
     665           0 :         return 0;
     666           0 : }
     667             : 
     668           0 : static int build_enum_path_resources(struct drm_dp_sideband_msg_tx *msg, int port_num)
     669             : {
     670           0 :         struct drm_dp_sideband_msg_req_body req;
     671             : 
     672           0 :         req.req_type = DP_ENUM_PATH_RESOURCES;
     673           0 :         req.u.port_num.port_number = port_num;
     674           0 :         drm_dp_encode_sideband_req(&req, msg);
     675           0 :         msg->path_msg = true;
     676           0 :         return 0;
     677           0 : }
     678             : 
     679           0 : static int build_allocate_payload(struct drm_dp_sideband_msg_tx *msg, int port_num,
     680             :                                   u8 vcpi, uint16_t pbn)
     681             : {
     682           0 :         struct drm_dp_sideband_msg_req_body req;
     683           0 :         memset(&req, 0, sizeof(req));
     684           0 :         req.req_type = DP_ALLOCATE_PAYLOAD;
     685           0 :         req.u.allocate_payload.port_number = port_num;
     686           0 :         req.u.allocate_payload.vcpi = vcpi;
     687           0 :         req.u.allocate_payload.pbn = pbn;
     688           0 :         drm_dp_encode_sideband_req(&req, msg);
     689           0 :         msg->path_msg = true;
     690           0 :         return 0;
     691           0 : }
     692             : 
     693           0 : static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
     694             :                                         struct drm_dp_vcpi *vcpi)
     695             : {
     696             :         int ret, vcpi_ret;
     697             : 
     698           0 :         mutex_lock(&mgr->payload_lock);
     699           0 :         ret = find_first_zero_bit(&mgr->payload_mask, mgr->max_payloads + 1);
     700           0 :         if (ret > mgr->max_payloads) {
     701             :                 ret = -EINVAL;
     702             :                 DRM_DEBUG_KMS("out of payload ids %d\n", ret);
     703           0 :                 goto out_unlock;
     704             :         }
     705             : 
     706           0 :         vcpi_ret = find_first_zero_bit(&mgr->vcpi_mask, mgr->max_payloads + 1);
     707           0 :         if (vcpi_ret > mgr->max_payloads) {
     708             :                 ret = -EINVAL;
     709             :                 DRM_DEBUG_KMS("out of vcpi ids %d\n", ret);
     710           0 :                 goto out_unlock;
     711             :         }
     712             : 
     713           0 :         set_bit(ret, &mgr->payload_mask);
     714           0 :         set_bit(vcpi_ret, &mgr->vcpi_mask);
     715           0 :         vcpi->vcpi = vcpi_ret + 1;
     716           0 :         mgr->proposed_vcpis[ret - 1] = vcpi;
     717             : out_unlock:
     718           0 :         mutex_unlock(&mgr->payload_lock);
     719           0 :         return ret;
     720             : }
     721             : 
     722           0 : static void drm_dp_mst_put_payload_id(struct drm_dp_mst_topology_mgr *mgr,
     723             :                                       int vcpi)
     724             : {
     725             :         int i;
     726           0 :         if (vcpi == 0)
     727           0 :                 return;
     728             : 
     729           0 :         mutex_lock(&mgr->payload_lock);
     730             :         DRM_DEBUG_KMS("putting payload %d\n", vcpi);
     731           0 :         clear_bit(vcpi - 1, &mgr->vcpi_mask);
     732             : 
     733           0 :         for (i = 0; i < mgr->max_payloads; i++) {
     734           0 :                 if (mgr->proposed_vcpis[i])
     735           0 :                         if (mgr->proposed_vcpis[i]->vcpi == vcpi) {
     736           0 :                                 mgr->proposed_vcpis[i] = NULL;
     737           0 :                                 clear_bit(i + 1, &mgr->payload_mask);
     738           0 :                         }
     739             :         }
     740           0 :         mutex_unlock(&mgr->payload_lock);
     741           0 : }
     742             : 
     743           0 : static bool check_txmsg_state(struct drm_dp_mst_topology_mgr *mgr,
     744             :                               struct drm_dp_sideband_msg_tx *txmsg)
     745             : {
     746             :         bool ret;
     747             : 
     748             :         /*
     749             :          * All updates to txmsg->state are protected by mgr->qlock, and the two
     750             :          * cases we check here are terminal states. For those the barriers
     751             :          * provided by the wake_up/wait_event pair are enough.
     752             :          */
     753           0 :         ret = (txmsg->state == DRM_DP_SIDEBAND_TX_RX ||
     754           0 :                txmsg->state == DRM_DP_SIDEBAND_TX_TIMEOUT);
     755           0 :         return ret;
     756             : }
     757             : 
     758           0 : static int drm_dp_mst_wait_tx_reply(struct drm_dp_mst_branch *mstb,
     759             :                                     struct drm_dp_sideband_msg_tx *txmsg)
     760             : {
     761           0 :         struct drm_dp_mst_topology_mgr *mgr = mstb->mgr;
     762             :         int ret;
     763             : 
     764           0 :         ret = wait_event_timeout(mgr->tx_waitq,
     765             :                                  check_txmsg_state(mgr, txmsg),
     766             :                                  (4 * HZ));
     767           0 :         mutex_lock(&mstb->mgr->qlock);
     768           0 :         if (ret > 0) {
     769           0 :                 if (txmsg->state == DRM_DP_SIDEBAND_TX_TIMEOUT) {
     770             :                         ret = -EIO;
     771           0 :                         goto out;
     772             :                 }
     773             :         } else {
     774             :                 DRM_DEBUG_KMS("timedout msg send %p %d %d\n", txmsg, txmsg->state, txmsg->seqno);
     775             : 
     776             :                 /* dump some state */
     777             :                 ret = -EIO;
     778             : 
     779             :                 /* remove from q */
     780           0 :                 if (txmsg->state == DRM_DP_SIDEBAND_TX_QUEUED ||
     781           0 :                     txmsg->state == DRM_DP_SIDEBAND_TX_START_SEND) {
     782           0 :                         list_del(&txmsg->next);
     783           0 :                 }
     784             : 
     785           0 :                 if (txmsg->state == DRM_DP_SIDEBAND_TX_START_SEND ||
     786           0 :                     txmsg->state == DRM_DP_SIDEBAND_TX_SENT) {
     787           0 :                         mstb->tx_slots[txmsg->seqno] = NULL;
     788           0 :                 }
     789             :         }
     790             : out:
     791           0 :         mutex_unlock(&mgr->qlock);
     792             : 
     793           0 :         return ret;
     794             : }
     795             : 
     796           0 : static struct drm_dp_mst_branch *drm_dp_add_mst_branch_device(u8 lct, u8 *rad)
     797             : {
     798             :         struct drm_dp_mst_branch *mstb;
     799             : 
     800           0 :         mstb = kzalloc(sizeof(*mstb), GFP_KERNEL);
     801           0 :         if (!mstb)
     802           0 :                 return NULL;
     803             : 
     804           0 :         mstb->lct = lct;
     805           0 :         if (lct > 1)
     806           0 :                 memcpy(mstb->rad, rad, lct / 2);
     807           0 :         INIT_LIST_HEAD(&mstb->ports);
     808           0 :         kref_init(&mstb->kref);
     809           0 :         return mstb;
     810           0 : }
     811             : 
     812             : static void drm_dp_free_mst_port(struct kref *kref);
     813             : 
     814           0 : static void drm_dp_free_mst_branch_device(struct kref *kref)
     815             : {
     816           0 :         struct drm_dp_mst_branch *mstb = container_of(kref, struct drm_dp_mst_branch, kref);
     817           0 :         if (mstb->port_parent) {
     818           0 :                 if (list_empty(&mstb->port_parent->next))
     819           0 :                         kref_put(&mstb->port_parent->kref, drm_dp_free_mst_port);
     820             :         }
     821           0 :         kfree(mstb);
     822           0 : }
     823             : 
     824           0 : static void drm_dp_destroy_mst_branch_device(struct kref *kref)
     825             : {
     826           0 :         struct drm_dp_mst_branch *mstb = container_of(kref, struct drm_dp_mst_branch, kref);
     827             :         struct drm_dp_mst_port *port, *tmp;
     828             :         bool wake_tx = false;
     829             : 
     830             :         /*
     831             :          * init kref again to be used by ports to remove mst branch when it is
     832             :          * not needed anymore
     833             :          */
     834           0 :         kref_init(kref);
     835             : 
     836           0 :         if (mstb->port_parent && list_empty(&mstb->port_parent->next))
     837           0 :                 kref_get(&mstb->port_parent->kref);
     838             : 
     839             :         /*
     840             :          * destroy all ports - don't need lock
     841             :          * as there are no more references to the mst branch
     842             :          * device at this point.
     843             :          */
     844           0 :         list_for_each_entry_safe(port, tmp, &mstb->ports, next) {
     845           0 :                 list_del(&port->next);
     846           0 :                 drm_dp_put_port(port);
     847             :         }
     848             : 
     849             :         /* drop any tx slots msg */
     850           0 :         mutex_lock(&mstb->mgr->qlock);
     851           0 :         if (mstb->tx_slots[0]) {
     852           0 :                 mstb->tx_slots[0]->state = DRM_DP_SIDEBAND_TX_TIMEOUT;
     853           0 :                 mstb->tx_slots[0] = NULL;
     854             :                 wake_tx = true;
     855           0 :         }
     856           0 :         if (mstb->tx_slots[1]) {
     857           0 :                 mstb->tx_slots[1]->state = DRM_DP_SIDEBAND_TX_TIMEOUT;
     858           0 :                 mstb->tx_slots[1] = NULL;
     859             :                 wake_tx = true;
     860           0 :         }
     861           0 :         mutex_unlock(&mstb->mgr->qlock);
     862             : 
     863           0 :         if (wake_tx)
     864           0 :                 wake_up(&mstb->mgr->tx_waitq);
     865             : 
     866           0 :         kref_put(kref, drm_dp_free_mst_branch_device);
     867           0 : }
     868             : 
     869           0 : static void drm_dp_put_mst_branch_device(struct drm_dp_mst_branch *mstb)
     870             : {
     871           0 :         kref_put(&mstb->kref, drm_dp_destroy_mst_branch_device);
     872           0 : }
     873             : 
     874             : 
     875           0 : static void drm_dp_port_teardown_pdt(struct drm_dp_mst_port *port, int old_pdt)
     876             : {
     877             :         struct drm_dp_mst_branch *mstb;
     878             : 
     879           0 :         switch (old_pdt) {
     880             :         case DP_PEER_DEVICE_DP_LEGACY_CONV:
     881             :         case DP_PEER_DEVICE_SST_SINK:
     882             :                 /* remove i2c over sideband */
     883           0 :                 drm_dp_mst_unregister_i2c_bus(&port->aux);
     884           0 :                 break;
     885             :         case DP_PEER_DEVICE_MST_BRANCHING:
     886           0 :                 mstb = port->mstb;
     887           0 :                 port->mstb = NULL;
     888           0 :                 drm_dp_put_mst_branch_device(mstb);
     889           0 :                 break;
     890             :         }
     891           0 : }
     892             : 
     893           0 : static void drm_dp_destroy_port(struct kref *kref)
     894             : {
     895           0 :         struct drm_dp_mst_port *port = container_of(kref, struct drm_dp_mst_port, kref);
     896           0 :         struct drm_dp_mst_topology_mgr *mgr = port->mgr;
     897             : 
     898           0 :         if (!port->input) {
     899           0 :                 port->vcpi.num_slots = 0;
     900             : 
     901           0 :                 kfree(port->cached_edid);
     902             : 
     903             :                 /*
     904             :                  * The only time we don't have a connector
     905             :                  * on an output port is if the connector init
     906             :                  * fails.
     907             :                  */
     908           0 :                 if (port->connector) {
     909             :                         /* we can't destroy the connector here, as
     910             :                          * we might be holding the mode_config.mutex
     911             :                          * from an EDID retrieval */
     912             : 
     913           0 :                         mutex_lock(&mgr->destroy_connector_lock);
     914           0 :                         kref_get(&port->parent->kref);
     915           0 :                         list_add(&port->next, &mgr->destroy_connector_list);
     916           0 :                         mutex_unlock(&mgr->destroy_connector_lock);
     917           0 :                         schedule_work(&mgr->destroy_connector_work);
     918           0 :                         return;
     919             :                 }
     920             :                 /* no need to clean up vcpi
     921             :                  * as if we have no connector we never setup a vcpi */
     922           0 :                 drm_dp_port_teardown_pdt(port, port->pdt);
     923           0 :                 port->pdt = DP_PEER_DEVICE_NONE;
     924           0 :         }
     925           0 :         kfree(port);
     926           0 : }
     927             : 
     928           0 : static void drm_dp_put_port(struct drm_dp_mst_port *port)
     929             : {
     930           0 :         kref_put(&port->kref, drm_dp_destroy_port);
     931           0 : }
     932             : 
     933           0 : static struct drm_dp_mst_branch *drm_dp_mst_get_validated_mstb_ref_locked(struct drm_dp_mst_branch *mstb, struct drm_dp_mst_branch *to_find)
     934             : {
     935             :         struct drm_dp_mst_port *port;
     936             :         struct drm_dp_mst_branch *rmstb;
     937           0 :         if (to_find == mstb) {
     938           0 :                 kref_get(&mstb->kref);
     939           0 :                 return mstb;
     940             :         }
     941           0 :         list_for_each_entry(port, &mstb->ports, next) {
     942           0 :                 if (port->mstb) {
     943           0 :                         rmstb = drm_dp_mst_get_validated_mstb_ref_locked(port->mstb, to_find);
     944           0 :                         if (rmstb)
     945           0 :                                 return rmstb;
     946             :                 }
     947             :         }
     948           0 :         return NULL;
     949           0 : }
     950             : 
     951           0 : static struct drm_dp_mst_branch *drm_dp_get_validated_mstb_ref(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_branch *mstb)
     952             : {
     953             :         struct drm_dp_mst_branch *rmstb = NULL;
     954           0 :         mutex_lock(&mgr->lock);
     955           0 :         if (mgr->mst_primary)
     956           0 :                 rmstb = drm_dp_mst_get_validated_mstb_ref_locked(mgr->mst_primary, mstb);
     957           0 :         mutex_unlock(&mgr->lock);
     958           0 :         return rmstb;
     959             : }
     960             : 
     961           0 : static struct drm_dp_mst_port *drm_dp_mst_get_port_ref_locked(struct drm_dp_mst_branch *mstb, struct drm_dp_mst_port *to_find)
     962             : {
     963             :         struct drm_dp_mst_port *port, *mport;
     964             : 
     965           0 :         list_for_each_entry(port, &mstb->ports, next) {
     966           0 :                 if (port == to_find) {
     967           0 :                         kref_get(&port->kref);
     968           0 :                         return port;
     969             :                 }
     970           0 :                 if (port->mstb) {
     971           0 :                         mport = drm_dp_mst_get_port_ref_locked(port->mstb, to_find);
     972           0 :                         if (mport)
     973           0 :                                 return mport;
     974             :                 }
     975             :         }
     976           0 :         return NULL;
     977           0 : }
     978             : 
     979           0 : static struct drm_dp_mst_port *drm_dp_get_validated_port_ref(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
     980             : {
     981             :         struct drm_dp_mst_port *rport = NULL;
     982           0 :         mutex_lock(&mgr->lock);
     983           0 :         if (mgr->mst_primary)
     984           0 :                 rport = drm_dp_mst_get_port_ref_locked(mgr->mst_primary, port);
     985           0 :         mutex_unlock(&mgr->lock);
     986           0 :         return rport;
     987             : }
     988             : 
     989           0 : static struct drm_dp_mst_port *drm_dp_get_port(struct drm_dp_mst_branch *mstb, u8 port_num)
     990             : {
     991             :         struct drm_dp_mst_port *port;
     992             : 
     993           0 :         list_for_each_entry(port, &mstb->ports, next) {
     994           0 :                 if (port->port_num == port_num) {
     995           0 :                         kref_get(&port->kref);
     996           0 :                         return port;
     997             :                 }
     998             :         }
     999             : 
    1000           0 :         return NULL;
    1001           0 : }
    1002             : 
    1003             : /*
    1004             :  * calculate a new RAD for this MST branch device
    1005             :  * if parent has an LCT of 2 then it has 1 nibble of RAD,
    1006             :  * if parent has an LCT of 3 then it has 2 nibbles of RAD,
    1007             :  */
    1008           0 : static u8 drm_dp_calculate_rad(struct drm_dp_mst_port *port,
    1009             :                                  u8 *rad)
    1010             : {
    1011           0 :         int parent_lct = port->parent->lct;
    1012             :         int shift = 4;
    1013           0 :         int idx = (parent_lct - 1) / 2;
    1014           0 :         if (parent_lct > 1) {
    1015           0 :                 memcpy(rad, port->parent->rad, idx + 1);
    1016           0 :                 shift = (parent_lct % 2) ? 4 : 0;
    1017           0 :         } else
    1018           0 :                 rad[0] = 0;
    1019             : 
    1020           0 :         rad[idx] |= port->port_num << shift;
    1021           0 :         return parent_lct + 1;
    1022             : }
    1023             : 
    1024             : /*
    1025             :  * return sends link address for new mstb
    1026             :  */
    1027           0 : static bool drm_dp_port_setup_pdt(struct drm_dp_mst_port *port)
    1028             : {
    1029             :         int ret;
    1030           0 :         u8 rad[6], lct;
    1031             :         bool send_link = false;
    1032           0 :         switch (port->pdt) {
    1033             :         case DP_PEER_DEVICE_DP_LEGACY_CONV:
    1034             :         case DP_PEER_DEVICE_SST_SINK:
    1035             :                 /* add i2c over sideband */
    1036           0 :                 ret = drm_dp_mst_register_i2c_bus(&port->aux);
    1037           0 :                 break;
    1038             :         case DP_PEER_DEVICE_MST_BRANCHING:
    1039           0 :                 lct = drm_dp_calculate_rad(port, rad);
    1040             : 
    1041           0 :                 port->mstb = drm_dp_add_mst_branch_device(lct, rad);
    1042           0 :                 port->mstb->mgr = port->mgr;
    1043           0 :                 port->mstb->port_parent = port;
    1044             : 
    1045             :                 send_link = true;
    1046           0 :                 break;
    1047             :         }
    1048           0 :         return send_link;
    1049           0 : }
    1050             : 
    1051           0 : static void drm_dp_check_mstb_guid(struct drm_dp_mst_branch *mstb, u8 *guid)
    1052             : {
    1053             :         int ret;
    1054             : 
    1055           0 :         memcpy(mstb->guid, guid, 16);
    1056             : 
    1057           0 :         if (!drm_dp_validate_guid(mstb->mgr, mstb->guid)) {
    1058           0 :                 if (mstb->port_parent) {
    1059           0 :                         ret = drm_dp_send_dpcd_write(
    1060             :                                         mstb->mgr,
    1061             :                                         mstb->port_parent,
    1062             :                                         DP_GUID,
    1063             :                                         16,
    1064             :                                         mstb->guid);
    1065           0 :                 } else {
    1066             : 
    1067           0 :                         ret = drm_dp_dpcd_write(
    1068           0 :                                         mstb->mgr->aux,
    1069             :                                         DP_GUID,
    1070             :                                         mstb->guid,
    1071             :                                         16);
    1072             :                 }
    1073             :         }
    1074           0 : }
    1075             : 
    1076           0 : static void build_mst_prop_path(const struct drm_dp_mst_branch *mstb,
    1077             :                                 int pnum,
    1078             :                                 char *proppath,
    1079             :                                 size_t proppath_size)
    1080             : {
    1081             :         int i;
    1082           0 :         char temp[8];
    1083           0 :         snprintf(proppath, proppath_size, "mst:%d", mstb->mgr->conn_base_id);
    1084           0 :         for (i = 0; i < (mstb->lct - 1); i++) {
    1085           0 :                 int shift = (i % 2) ? 0 : 4;
    1086           0 :                 int port_num = (mstb->rad[i / 2] >> shift) & 0xf;
    1087           0 :                 snprintf(temp, sizeof(temp), "-%d", port_num);
    1088           0 :                 strlcat(proppath, temp, proppath_size);
    1089             :         }
    1090           0 :         snprintf(temp, sizeof(temp), "-%d", pnum);
    1091           0 :         strlcat(proppath, temp, proppath_size);
    1092           0 : }
    1093             : 
    1094           0 : static void drm_dp_add_port(struct drm_dp_mst_branch *mstb,
    1095             :                             struct device *dev,
    1096             :                             struct drm_dp_link_addr_reply_port *port_msg)
    1097             : {
    1098             :         struct drm_dp_mst_port *port;
    1099             :         bool ret;
    1100             :         bool created = false;
    1101             :         int old_pdt = 0;
    1102             :         int old_ddps = 0;
    1103           0 :         port = drm_dp_get_port(mstb, port_msg->port_number);
    1104           0 :         if (!port) {
    1105           0 :                 port = kzalloc(sizeof(*port), GFP_KERNEL);
    1106           0 :                 if (!port)
    1107           0 :                         return;
    1108           0 :                 kref_init(&port->kref);
    1109           0 :                 port->parent = mstb;
    1110           0 :                 port->port_num = port_msg->port_number;
    1111           0 :                 port->mgr = mstb->mgr;
    1112           0 :                 port->aux.name = "DPMST";
    1113           0 :                 port->aux.dev = dev;
    1114             :                 created = true;
    1115           0 :         } else {
    1116           0 :                 old_pdt = port->pdt;
    1117           0 :                 old_ddps = port->ddps;
    1118             :         }
    1119             : 
    1120           0 :         port->pdt = port_msg->peer_device_type;
    1121           0 :         port->input = port_msg->input_port;
    1122           0 :         port->mcs = port_msg->mcs;
    1123           0 :         port->ddps = port_msg->ddps;
    1124           0 :         port->ldps = port_msg->legacy_device_plug_status;
    1125           0 :         port->dpcd_rev = port_msg->dpcd_revision;
    1126           0 :         port->num_sdp_streams = port_msg->num_sdp_streams;
    1127           0 :         port->num_sdp_stream_sinks = port_msg->num_sdp_stream_sinks;
    1128             : 
    1129             :         /* manage mstb port lists with mgr lock - take a reference
    1130             :            for this list */
    1131           0 :         if (created) {
    1132           0 :                 mutex_lock(&mstb->mgr->lock);
    1133           0 :                 kref_get(&port->kref);
    1134           0 :                 list_add(&port->next, &mstb->ports);
    1135           0 :                 mutex_unlock(&mstb->mgr->lock);
    1136           0 :         }
    1137             : 
    1138           0 :         if (old_ddps != port->ddps) {
    1139           0 :                 if (port->ddps) {
    1140           0 :                         if (!port->input)
    1141           0 :                                 drm_dp_send_enum_path_resources(mstb->mgr, mstb, port);
    1142             :                 } else {
    1143           0 :                         port->available_pbn = 0;
    1144             :                         }
    1145             :         }
    1146             : 
    1147           0 :         if (old_pdt != port->pdt && !port->input) {
    1148           0 :                 drm_dp_port_teardown_pdt(port, old_pdt);
    1149             : 
    1150           0 :                 ret = drm_dp_port_setup_pdt(port);
    1151           0 :                 if (ret == true)
    1152           0 :                         drm_dp_send_link_address(mstb->mgr, port->mstb);
    1153             :         }
    1154             : 
    1155           0 :         if (created && !port->input) {
    1156           0 :                 char proppath[255];
    1157             : 
    1158           0 :                 build_mst_prop_path(mstb, port->port_num, proppath, sizeof(proppath));
    1159           0 :                 port->connector = (*mstb->mgr->cbs->add_connector)(mstb->mgr, port, proppath);
    1160           0 :                 if (!port->connector) {
    1161             :                         /* remove it from the port list */
    1162           0 :                         mutex_lock(&mstb->mgr->lock);
    1163           0 :                         list_del(&port->next);
    1164           0 :                         mutex_unlock(&mstb->mgr->lock);
    1165             :                         /* drop port list reference */
    1166           0 :                         drm_dp_put_port(port);
    1167           0 :                         goto out;
    1168             :                 }
    1169           0 :                 if ((port->pdt == DP_PEER_DEVICE_DP_LEGACY_CONV ||
    1170           0 :                      port->pdt == DP_PEER_DEVICE_SST_SINK) &&
    1171           0 :                     port->port_num >= DP_MST_LOGICAL_PORT_0) {
    1172           0 :                         port->cached_edid = drm_get_edid(port->connector, &port->aux.ddc);
    1173           0 :                         drm_mode_connector_set_tile_property(port->connector);
    1174           0 :                 }
    1175           0 :                 (*mstb->mgr->cbs->register_connector)(port->connector);
    1176           0 :         }
    1177             : 
    1178             : out:
    1179             :         /* put reference to this port */
    1180           0 :         drm_dp_put_port(port);
    1181           0 : }
    1182             : 
    1183           0 : static void drm_dp_update_port(struct drm_dp_mst_branch *mstb,
    1184             :                                struct drm_dp_connection_status_notify *conn_stat)
    1185             : {
    1186             :         struct drm_dp_mst_port *port;
    1187             :         int old_pdt;
    1188             :         int old_ddps;
    1189             :         bool dowork = false;
    1190           0 :         port = drm_dp_get_port(mstb, conn_stat->port_number);
    1191           0 :         if (!port)
    1192           0 :                 return;
    1193             : 
    1194           0 :         old_ddps = port->ddps;
    1195           0 :         old_pdt = port->pdt;
    1196           0 :         port->pdt = conn_stat->peer_device_type;
    1197           0 :         port->mcs = conn_stat->message_capability_status;
    1198           0 :         port->ldps = conn_stat->legacy_device_plug_status;
    1199           0 :         port->ddps = conn_stat->displayport_device_plug_status;
    1200             : 
    1201           0 :         if (old_ddps != port->ddps) {
    1202           0 :                 if (port->ddps) {
    1203             :                         dowork = true;
    1204           0 :                 } else {
    1205           0 :                         port->available_pbn = 0;
    1206             :                 }
    1207             :         }
    1208           0 :         if (old_pdt != port->pdt && !port->input) {
    1209           0 :                 drm_dp_port_teardown_pdt(port, old_pdt);
    1210             : 
    1211           0 :                 if (drm_dp_port_setup_pdt(port))
    1212           0 :                         dowork = true;
    1213             :         }
    1214             : 
    1215           0 :         drm_dp_put_port(port);
    1216           0 :         if (dowork)
    1217           0 :                 queue_work(system_long_wq, &mstb->mgr->work);
    1218             : 
    1219           0 : }
    1220             : 
    1221           0 : static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_topology_mgr *mgr,
    1222             :                                                                u8 lct, u8 *rad)
    1223             : {
    1224             :         struct drm_dp_mst_branch *mstb;
    1225             :         struct drm_dp_mst_port *port;
    1226             :         int i;
    1227             :         /* find the port by iterating down */
    1228             : 
    1229           0 :         mutex_lock(&mgr->lock);
    1230           0 :         mstb = mgr->mst_primary;
    1231             : 
    1232           0 :         for (i = 0; i < lct - 1; i++) {
    1233           0 :                 int shift = (i % 2) ? 0 : 4;
    1234           0 :                 int port_num = (rad[i / 2] >> shift) & 0xf;
    1235             : 
    1236           0 :                 list_for_each_entry(port, &mstb->ports, next) {
    1237           0 :                         if (port->port_num == port_num) {
    1238           0 :                                 mstb = port->mstb;
    1239           0 :                                 if (!mstb) {
    1240           0 :                                         DRM_ERROR("failed to lookup MSTB with lct %d, rad %02x\n", lct, rad[0]);
    1241           0 :                                         goto out;
    1242             :                                 }
    1243             : 
    1244             :                                 break;
    1245             :                         }
    1246             :                 }
    1247           0 :         }
    1248           0 :         kref_get(&mstb->kref);
    1249             : out:
    1250           0 :         mutex_unlock(&mgr->lock);
    1251           0 :         return mstb;
    1252           0 : }
    1253             : 
    1254           0 : static struct drm_dp_mst_branch *get_mst_branch_device_by_guid_helper(
    1255             :         struct drm_dp_mst_branch *mstb,
    1256             :         uint8_t *guid)
    1257             : {
    1258             :         struct drm_dp_mst_branch *found_mstb;
    1259             :         struct drm_dp_mst_port *port;
    1260             : 
    1261           0 :         if (memcmp(mstb->guid, guid, 16) == 0)
    1262           0 :                 return mstb;
    1263             : 
    1264             : 
    1265           0 :         list_for_each_entry(port, &mstb->ports, next) {
    1266           0 :                 if (!port->mstb)
    1267             :                         continue;
    1268             : 
    1269           0 :                 found_mstb = get_mst_branch_device_by_guid_helper(port->mstb, guid);
    1270             : 
    1271           0 :                 if (found_mstb)
    1272           0 :                         return found_mstb;
    1273             :         }
    1274             : 
    1275           0 :         return NULL;
    1276           0 : }
    1277             : 
    1278           0 : static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device_by_guid(
    1279             :         struct drm_dp_mst_topology_mgr *mgr,
    1280             :         uint8_t *guid)
    1281             : {
    1282             :         struct drm_dp_mst_branch *mstb;
    1283             : 
    1284             :         /* find the port by iterating down */
    1285           0 :         mutex_lock(&mgr->lock);
    1286             : 
    1287           0 :         mstb = get_mst_branch_device_by_guid_helper(mgr->mst_primary, guid);
    1288             : 
    1289           0 :         if (mstb)
    1290           0 :                 kref_get(&mstb->kref);
    1291             : 
    1292           0 :         mutex_unlock(&mgr->lock);
    1293           0 :         return mstb;
    1294             : }
    1295             : 
    1296           0 : static void drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
    1297             :                                                struct drm_dp_mst_branch *mstb)
    1298             : {
    1299             :         struct drm_dp_mst_port *port;
    1300             :         struct drm_dp_mst_branch *mstb_child;
    1301           0 :         if (!mstb->link_address_sent)
    1302           0 :                 drm_dp_send_link_address(mgr, mstb);
    1303             : 
    1304           0 :         list_for_each_entry(port, &mstb->ports, next) {
    1305           0 :                 if (port->input)
    1306             :                         continue;
    1307             : 
    1308           0 :                 if (!port->ddps)
    1309             :                         continue;
    1310             : 
    1311           0 :                 if (!port->available_pbn)
    1312           0 :                         drm_dp_send_enum_path_resources(mgr, mstb, port);
    1313             : 
    1314           0 :                 if (port->mstb) {
    1315           0 :                         mstb_child = drm_dp_get_validated_mstb_ref(mgr, port->mstb);
    1316           0 :                         if (mstb_child) {
    1317           0 :                                 drm_dp_check_and_send_link_address(mgr, mstb_child);
    1318           0 :                                 drm_dp_put_mst_branch_device(mstb_child);
    1319           0 :                         }
    1320             :                 }
    1321             :         }
    1322           0 : }
    1323             : 
    1324           0 : static void drm_dp_mst_link_probe_work(struct work_struct *work)
    1325             : {
    1326           0 :         struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, work);
    1327             :         struct drm_dp_mst_branch *mstb;
    1328             : 
    1329           0 :         mutex_lock(&mgr->lock);
    1330           0 :         mstb = mgr->mst_primary;
    1331           0 :         if (mstb) {
    1332           0 :                 kref_get(&mstb->kref);
    1333           0 :         }
    1334           0 :         mutex_unlock(&mgr->lock);
    1335           0 :         if (mstb) {
    1336           0 :                 drm_dp_check_and_send_link_address(mgr, mstb);
    1337           0 :                 drm_dp_put_mst_branch_device(mstb);
    1338           0 :         }
    1339           0 : }
    1340             : 
    1341           0 : static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr,
    1342             :                                  u8 *guid)
    1343             : {
    1344             :         static u8 zero_guid[16];
    1345             : 
    1346           0 :         if (!memcmp(guid, zero_guid, 16)) {
    1347           0 :                 u64 salt = get_jiffies_64();
    1348           0 :                 memcpy(&guid[0], &salt, sizeof(u64));
    1349           0 :                 memcpy(&guid[8], &salt, sizeof(u64));
    1350             :                 return false;
    1351             :         }
    1352           0 :         return true;
    1353           0 : }
    1354             : 
    1355             : #if 0
    1356             : static int build_dpcd_read(struct drm_dp_sideband_msg_tx *msg, u8 port_num, u32 offset, u8 num_bytes)
    1357             : {
    1358             :         struct drm_dp_sideband_msg_req_body req;
    1359             : 
    1360             :         req.req_type = DP_REMOTE_DPCD_READ;
    1361             :         req.u.dpcd_read.port_number = port_num;
    1362             :         req.u.dpcd_read.dpcd_address = offset;
    1363             :         req.u.dpcd_read.num_bytes = num_bytes;
    1364             :         drm_dp_encode_sideband_req(&req, msg);
    1365             : 
    1366             :         return 0;
    1367             : }
    1368             : #endif
    1369             : 
    1370           0 : static int drm_dp_send_sideband_msg(struct drm_dp_mst_topology_mgr *mgr,
    1371             :                                     bool up, u8 *msg, int len)
    1372             : {
    1373             :         int ret;
    1374           0 :         int regbase = up ? DP_SIDEBAND_MSG_UP_REP_BASE : DP_SIDEBAND_MSG_DOWN_REQ_BASE;
    1375             :         int tosend, total, offset;
    1376           0 :         int retries = 0;
    1377             : 
    1378             : retry:
    1379             :         total = len;
    1380             :         offset = 0;
    1381           0 :         do {
    1382           0 :                 tosend = min3(mgr->max_dpcd_transaction_bytes, 16, total);
    1383             : 
    1384           0 :                 ret = drm_dp_dpcd_write(mgr->aux, regbase + offset,
    1385           0 :                                         &msg[offset],
    1386           0 :                                         tosend);
    1387           0 :                 if (ret != tosend) {
    1388           0 :                         if (ret == -EIO && retries < 5) {
    1389           0 :                                 retries++;
    1390           0 :                                 goto retry;
    1391             :                         }
    1392             :                         DRM_DEBUG_KMS("failed to dpcd write %d %d\n", tosend, ret);
    1393             : 
    1394           0 :                         return -EIO;
    1395             :                 }
    1396           0 :                 offset += tosend;
    1397           0 :                 total -= tosend;
    1398           0 :         } while (total > 0);
    1399           0 :         return 0;
    1400           0 : }
    1401             : 
    1402           0 : static int set_hdr_from_dst_qlock(struct drm_dp_sideband_msg_hdr *hdr,
    1403             :                                   struct drm_dp_sideband_msg_tx *txmsg)
    1404             : {
    1405           0 :         struct drm_dp_mst_branch *mstb = txmsg->dst;
    1406             :         u8 req_type;
    1407             : 
    1408             :         /* both msg slots are full */
    1409           0 :         if (txmsg->seqno == -1) {
    1410           0 :                 if (mstb->tx_slots[0] && mstb->tx_slots[1]) {
    1411             :                         DRM_DEBUG_KMS("%s: failed to find slot\n", __func__);
    1412           0 :                         return -EAGAIN;
    1413             :                 }
    1414           0 :                 if (mstb->tx_slots[0] == NULL && mstb->tx_slots[1] == NULL) {
    1415           0 :                         txmsg->seqno = mstb->last_seqno;
    1416           0 :                         mstb->last_seqno ^= 1;
    1417           0 :                 } else if (mstb->tx_slots[0] == NULL)
    1418           0 :                         txmsg->seqno = 0;
    1419             :                 else
    1420           0 :                         txmsg->seqno = 1;
    1421           0 :                 mstb->tx_slots[txmsg->seqno] = txmsg;
    1422           0 :         }
    1423             : 
    1424           0 :         req_type = txmsg->msg[0] & 0x7f;
    1425           0 :         if (req_type == DP_CONNECTION_STATUS_NOTIFY ||
    1426           0 :                 req_type == DP_RESOURCE_STATUS_NOTIFY)
    1427           0 :                 hdr->broadcast = 1;
    1428             :         else
    1429           0 :                 hdr->broadcast = 0;
    1430           0 :         hdr->path_msg = txmsg->path_msg;
    1431           0 :         hdr->lct = mstb->lct;
    1432           0 :         hdr->lcr = mstb->lct - 1;
    1433           0 :         if (mstb->lct > 1)
    1434           0 :                 memcpy(hdr->rad, mstb->rad, mstb->lct / 2);
    1435           0 :         hdr->seqno = txmsg->seqno;
    1436           0 :         return 0;
    1437           0 : }
    1438             : /*
    1439             :  * process a single block of the next message in the sideband queue
    1440             :  */
    1441           0 : static int process_single_tx_qlock(struct drm_dp_mst_topology_mgr *mgr,
    1442             :                                    struct drm_dp_sideband_msg_tx *txmsg,
    1443             :                                    bool up)
    1444             : {
    1445           0 :         u8 chunk[48];
    1446           0 :         struct drm_dp_sideband_msg_hdr hdr;
    1447           0 :         int len, space, idx, tosend;
    1448             :         int ret;
    1449             : 
    1450           0 :         memset(&hdr, 0, sizeof(struct drm_dp_sideband_msg_hdr));
    1451             : 
    1452           0 :         if (txmsg->state == DRM_DP_SIDEBAND_TX_QUEUED) {
    1453           0 :                 txmsg->seqno = -1;
    1454           0 :                 txmsg->state = DRM_DP_SIDEBAND_TX_START_SEND;
    1455           0 :         }
    1456             : 
    1457             :         /* make hdr from dst mst - for replies use seqno
    1458             :            otherwise assign one */
    1459           0 :         ret = set_hdr_from_dst_qlock(&hdr, txmsg);
    1460           0 :         if (ret < 0)
    1461           0 :                 return ret;
    1462             : 
    1463             :         /* amount left to send in this message */
    1464           0 :         len = txmsg->cur_len - txmsg->cur_offset;
    1465             : 
    1466             :         /* 48 - sideband msg size - 1 byte for data CRC, x header bytes */
    1467           0 :         space = 48 - 1 - drm_dp_calc_sb_hdr_size(&hdr);
    1468             : 
    1469           0 :         tosend = min(len, space);
    1470           0 :         if (len == txmsg->cur_len)
    1471           0 :                 hdr.somt = 1;
    1472           0 :         if (space >= len)
    1473           0 :                 hdr.eomt = 1;
    1474             : 
    1475             : 
    1476           0 :         hdr.msg_len = tosend + 1;
    1477           0 :         drm_dp_encode_sideband_msg_hdr(&hdr, chunk, &idx);
    1478           0 :         memcpy(&chunk[idx], &txmsg->msg[txmsg->cur_offset], tosend);
    1479             :         /* add crc at end */
    1480           0 :         drm_dp_crc_sideband_chunk_req(&chunk[idx], tosend);
    1481           0 :         idx += tosend + 1;
    1482             : 
    1483           0 :         ret = drm_dp_send_sideband_msg(mgr, up, chunk, idx);
    1484           0 :         if (ret) {
    1485             :                 DRM_DEBUG_KMS("sideband msg failed to send\n");
    1486           0 :                 return ret;
    1487             :         }
    1488             : 
    1489           0 :         txmsg->cur_offset += tosend;
    1490           0 :         if (txmsg->cur_offset == txmsg->cur_len) {
    1491           0 :                 txmsg->state = DRM_DP_SIDEBAND_TX_SENT;
    1492           0 :                 return 1;
    1493             :         }
    1494           0 :         return 0;
    1495           0 : }
    1496             : 
    1497           0 : static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr)
    1498             : {
    1499             :         struct drm_dp_sideband_msg_tx *txmsg;
    1500             :         int ret;
    1501             : 
    1502           0 :         WARN_ON(!mutex_is_locked(&mgr->qlock));
    1503             : 
    1504             :         /* construct a chunk from the first msg in the tx_msg queue */
    1505           0 :         if (list_empty(&mgr->tx_msg_downq)) {
    1506           0 :                 mgr->tx_down_in_progress = false;
    1507           0 :                 return;
    1508             :         }
    1509           0 :         mgr->tx_down_in_progress = true;
    1510             : 
    1511           0 :         txmsg = list_first_entry(&mgr->tx_msg_downq, struct drm_dp_sideband_msg_tx, next);
    1512           0 :         ret = process_single_tx_qlock(mgr, txmsg, false);
    1513           0 :         if (ret == 1) {
    1514             :                 /* txmsg is sent it should be in the slots now */
    1515           0 :                 list_del(&txmsg->next);
    1516           0 :         } else if (ret) {
    1517             :                 DRM_DEBUG_KMS("failed to send msg in q %d\n", ret);
    1518           0 :                 list_del(&txmsg->next);
    1519           0 :                 if (txmsg->seqno != -1)
    1520           0 :                         txmsg->dst->tx_slots[txmsg->seqno] = NULL;
    1521           0 :                 txmsg->state = DRM_DP_SIDEBAND_TX_TIMEOUT;
    1522           0 :                 wake_up(&mgr->tx_waitq);
    1523           0 :         }
    1524           0 :         if (list_empty(&mgr->tx_msg_downq)) {
    1525           0 :                 mgr->tx_down_in_progress = false;
    1526           0 :                 return;
    1527             :         }
    1528           0 : }
    1529             : 
    1530             : /* called holding qlock */
    1531           0 : static void process_single_up_tx_qlock(struct drm_dp_mst_topology_mgr *mgr,
    1532             :                                        struct drm_dp_sideband_msg_tx *txmsg)
    1533             : {
    1534             :         int ret;
    1535             : 
    1536             :         /* construct a chunk from the first msg in the tx_msg queue */
    1537           0 :         ret = process_single_tx_qlock(mgr, txmsg, true);
    1538             : 
    1539             :         if (ret != 1)
    1540             :                 DRM_DEBUG_KMS("failed to send msg in q %d\n", ret);
    1541             : 
    1542           0 :         txmsg->dst->tx_slots[txmsg->seqno] = NULL;
    1543           0 : }
    1544             : 
    1545           0 : static void drm_dp_queue_down_tx(struct drm_dp_mst_topology_mgr *mgr,
    1546             :                                  struct drm_dp_sideband_msg_tx *txmsg)
    1547             : {
    1548           0 :         mutex_lock(&mgr->qlock);
    1549           0 :         list_add_tail(&txmsg->next, &mgr->tx_msg_downq);
    1550           0 :         if (!mgr->tx_down_in_progress)
    1551           0 :                 process_single_down_tx_qlock(mgr);
    1552           0 :         mutex_unlock(&mgr->qlock);
    1553           0 : }
    1554             : 
    1555           0 : static void drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
    1556             :                                      struct drm_dp_mst_branch *mstb)
    1557             : {
    1558             :         int len;
    1559             :         struct drm_dp_sideband_msg_tx *txmsg;
    1560             :         int ret;
    1561             : 
    1562           0 :         txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
    1563           0 :         if (!txmsg)
    1564           0 :                 return;
    1565             : 
    1566           0 :         txmsg->dst = mstb;
    1567           0 :         len = build_link_address(txmsg);
    1568             : 
    1569           0 :         mstb->link_address_sent = true;
    1570           0 :         drm_dp_queue_down_tx(mgr, txmsg);
    1571             : 
    1572           0 :         ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
    1573           0 :         if (ret > 0) {
    1574             :                 int i;
    1575             : 
    1576           0 :                 if (txmsg->reply.reply_type == 1)
    1577             :                         DRM_DEBUG_KMS("link address nak received\n");
    1578             :                 else {
    1579             :                         DRM_DEBUG_KMS("link address reply: %d\n", txmsg->reply.u.link_addr.nports);
    1580           0 :                         for (i = 0; i < txmsg->reply.u.link_addr.nports; i++) {
    1581             :                                 DRM_DEBUG_KMS("port %d: input %d, pdt: %d, pn: %d, dpcd_rev: %02x, mcs: %d, ddps: %d, ldps %d, sdp %d/%d\n", i,
    1582             :                                        txmsg->reply.u.link_addr.ports[i].input_port,
    1583             :                                        txmsg->reply.u.link_addr.ports[i].peer_device_type,
    1584             :                                        txmsg->reply.u.link_addr.ports[i].port_number,
    1585             :                                        txmsg->reply.u.link_addr.ports[i].dpcd_revision,
    1586             :                                        txmsg->reply.u.link_addr.ports[i].mcs,
    1587             :                                        txmsg->reply.u.link_addr.ports[i].ddps,
    1588             :                                        txmsg->reply.u.link_addr.ports[i].legacy_device_plug_status,
    1589             :                                        txmsg->reply.u.link_addr.ports[i].num_sdp_streams,
    1590             :                                        txmsg->reply.u.link_addr.ports[i].num_sdp_stream_sinks);
    1591             :                         }
    1592             : 
    1593           0 :                         drm_dp_check_mstb_guid(mstb, txmsg->reply.u.link_addr.guid);
    1594             : 
    1595           0 :                         for (i = 0; i < txmsg->reply.u.link_addr.nports; i++) {
    1596           0 :                                 drm_dp_add_port(mstb, mgr->dev, &txmsg->reply.u.link_addr.ports[i]);
    1597             :                         }
    1598           0 :                         (*mgr->cbs->hotplug)(mgr);
    1599             :                 }
    1600           0 :         } else {
    1601           0 :                 mstb->link_address_sent = false;
    1602             :                 DRM_DEBUG_KMS("link address failed %d\n", ret);
    1603             :         }
    1604             : 
    1605           0 :         kfree(txmsg);
    1606           0 : }
    1607             : 
    1608           0 : static int drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr,
    1609             :                                            struct drm_dp_mst_branch *mstb,
    1610             :                                            struct drm_dp_mst_port *port)
    1611             : {
    1612             :         int len;
    1613             :         struct drm_dp_sideband_msg_tx *txmsg;
    1614             :         int ret;
    1615             : 
    1616           0 :         txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
    1617           0 :         if (!txmsg)
    1618           0 :                 return -ENOMEM;
    1619             : 
    1620           0 :         txmsg->dst = mstb;
    1621           0 :         len = build_enum_path_resources(txmsg, port->port_num);
    1622             : 
    1623           0 :         drm_dp_queue_down_tx(mgr, txmsg);
    1624             : 
    1625           0 :         ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
    1626           0 :         if (ret > 0) {
    1627           0 :                 if (txmsg->reply.reply_type == 1)
    1628             :                         DRM_DEBUG_KMS("enum path resources nak received\n");
    1629             :                 else {
    1630           0 :                         if (port->port_num != txmsg->reply.u.path_resources.port_number)
    1631           0 :                                 DRM_ERROR("got incorrect port in response\n");
    1632             :                         DRM_DEBUG_KMS("enum path resources %d: %d %d\n", txmsg->reply.u.path_resources.port_number, txmsg->reply.u.path_resources.full_payload_bw_number,
    1633             :                                txmsg->reply.u.path_resources.avail_payload_bw_number);
    1634           0 :                         port->available_pbn = txmsg->reply.u.path_resources.avail_payload_bw_number;
    1635             :                 }
    1636             :         }
    1637             : 
    1638           0 :         kfree(txmsg);
    1639           0 :         return 0;
    1640           0 : }
    1641             : 
    1642           0 : static struct drm_dp_mst_port *drm_dp_get_last_connected_port_to_mstb(struct drm_dp_mst_branch *mstb)
    1643             : {
    1644           0 :         if (!mstb->port_parent)
    1645           0 :                 return NULL;
    1646             : 
    1647           0 :         if (mstb->port_parent->mstb != mstb)
    1648           0 :                 return mstb->port_parent;
    1649             : 
    1650           0 :         return drm_dp_get_last_connected_port_to_mstb(mstb->port_parent->parent);
    1651           0 : }
    1652             : 
    1653           0 : static struct drm_dp_mst_branch *drm_dp_get_last_connected_port_and_mstb(struct drm_dp_mst_topology_mgr *mgr,
    1654             :                                                                          struct drm_dp_mst_branch *mstb,
    1655             :                                                                          int *port_num)
    1656             : {
    1657             :         struct drm_dp_mst_branch *rmstb = NULL;
    1658             :         struct drm_dp_mst_port *found_port;
    1659           0 :         mutex_lock(&mgr->lock);
    1660           0 :         if (mgr->mst_primary) {
    1661           0 :                 found_port = drm_dp_get_last_connected_port_to_mstb(mstb);
    1662             : 
    1663           0 :                 if (found_port) {
    1664           0 :                         rmstb = found_port->parent;
    1665           0 :                         kref_get(&rmstb->kref);
    1666           0 :                         *port_num = found_port->port_num;
    1667           0 :                 }
    1668             :         }
    1669           0 :         mutex_unlock(&mgr->lock);
    1670           0 :         return rmstb;
    1671             : }
    1672             : 
    1673           0 : static int drm_dp_payload_send_msg(struct drm_dp_mst_topology_mgr *mgr,
    1674             :                                    struct drm_dp_mst_port *port,
    1675             :                                    int id,
    1676             :                                    int pbn)
    1677             : {
    1678             :         struct drm_dp_sideband_msg_tx *txmsg;
    1679             :         struct drm_dp_mst_branch *mstb;
    1680           0 :         int len, ret, port_num;
    1681             : 
    1682           0 :         port = drm_dp_get_validated_port_ref(mgr, port);
    1683           0 :         if (!port)
    1684           0 :                 return -EINVAL;
    1685             : 
    1686           0 :         port_num = port->port_num;
    1687           0 :         mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent);
    1688           0 :         if (!mstb) {
    1689           0 :                 mstb = drm_dp_get_last_connected_port_and_mstb(mgr, port->parent, &port_num);
    1690             : 
    1691           0 :                 if (!mstb) {
    1692           0 :                         drm_dp_put_port(port);
    1693           0 :                         return -EINVAL;
    1694             :                 }
    1695             :         }
    1696             : 
    1697           0 :         txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
    1698           0 :         if (!txmsg) {
    1699             :                 ret = -ENOMEM;
    1700           0 :                 goto fail_put;
    1701             :         }
    1702             : 
    1703           0 :         txmsg->dst = mstb;
    1704           0 :         len = build_allocate_payload(txmsg, port_num,
    1705           0 :                                      id,
    1706           0 :                                      pbn);
    1707             : 
    1708           0 :         drm_dp_queue_down_tx(mgr, txmsg);
    1709             : 
    1710           0 :         ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
    1711           0 :         if (ret > 0) {
    1712           0 :                 if (txmsg->reply.reply_type == 1) {
    1713             :                         ret = -EINVAL;
    1714           0 :                 } else
    1715             :                         ret = 0;
    1716             :         }
    1717           0 :         kfree(txmsg);
    1718             : fail_put:
    1719           0 :         drm_dp_put_mst_branch_device(mstb);
    1720           0 :         drm_dp_put_port(port);
    1721           0 :         return ret;
    1722           0 : }
    1723             : 
    1724           0 : static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
    1725             :                                        int id,
    1726             :                                        struct drm_dp_payload *payload)
    1727             : {
    1728             :         int ret;
    1729             : 
    1730           0 :         ret = drm_dp_dpcd_write_payload(mgr, id, payload);
    1731           0 :         if (ret < 0) {
    1732           0 :                 payload->payload_state = 0;
    1733           0 :                 return ret;
    1734             :         }
    1735           0 :         payload->payload_state = DP_PAYLOAD_LOCAL;
    1736           0 :         return 0;
    1737           0 : }
    1738             : 
    1739           0 : static int drm_dp_create_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
    1740             :                                        struct drm_dp_mst_port *port,
    1741             :                                        int id,
    1742             :                                        struct drm_dp_payload *payload)
    1743             : {
    1744             :         int ret;
    1745           0 :         ret = drm_dp_payload_send_msg(mgr, port, id, port->vcpi.pbn);
    1746           0 :         if (ret < 0)
    1747           0 :                 return ret;
    1748           0 :         payload->payload_state = DP_PAYLOAD_REMOTE;
    1749           0 :         return ret;
    1750           0 : }
    1751             : 
    1752           0 : static int drm_dp_destroy_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
    1753             :                                         struct drm_dp_mst_port *port,
    1754             :                                         int id,
    1755             :                                         struct drm_dp_payload *payload)
    1756             : {
    1757             :         DRM_DEBUG_KMS("\n");
    1758             :         /* its okay for these to fail */
    1759           0 :         if (port) {
    1760           0 :                 drm_dp_payload_send_msg(mgr, port, id, 0);
    1761           0 :         }
    1762             : 
    1763           0 :         drm_dp_dpcd_write_payload(mgr, id, payload);
    1764           0 :         payload->payload_state = DP_PAYLOAD_DELETE_LOCAL;
    1765           0 :         return 0;
    1766             : }
    1767             : 
    1768           0 : static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
    1769             :                                         int id,
    1770             :                                         struct drm_dp_payload *payload)
    1771             : {
    1772           0 :         payload->payload_state = 0;
    1773           0 :         return 0;
    1774             : }
    1775             : 
    1776             : /**
    1777             :  * drm_dp_update_payload_part1() - Execute payload update part 1
    1778             :  * @mgr: manager to use.
    1779             :  *
    1780             :  * This iterates over all proposed virtual channels, and tries to
    1781             :  * allocate space in the link for them. For 0->slots transitions,
    1782             :  * this step just writes the VCPI to the MST device. For slots->0
    1783             :  * transitions, this writes the updated VCPIs and removes the
    1784             :  * remote VC payloads.
    1785             :  *
    1786             :  * after calling this the driver should generate ACT and payload
    1787             :  * packets.
    1788             :  */
    1789           0 : int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
    1790             : {
    1791             :         int i, j;
    1792             :         int cur_slots = 1;
    1793           0 :         struct drm_dp_payload req_payload;
    1794             :         struct drm_dp_mst_port *port;
    1795             : 
    1796           0 :         mutex_lock(&mgr->payload_lock);
    1797           0 :         for (i = 0; i < mgr->max_payloads; i++) {
    1798             :                 /* solve the current payloads - compare to the hw ones
    1799             :                    - update the hw view */
    1800           0 :                 req_payload.start_slot = cur_slots;
    1801           0 :                 if (mgr->proposed_vcpis[i]) {
    1802           0 :                         port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi);
    1803           0 :                         port = drm_dp_get_validated_port_ref(mgr, port);
    1804           0 :                         if (!port) {
    1805           0 :                                 mutex_unlock(&mgr->payload_lock);
    1806           0 :                                 return -EINVAL;
    1807             :                         }
    1808           0 :                         req_payload.num_slots = mgr->proposed_vcpis[i]->num_slots;
    1809           0 :                         req_payload.vcpi = mgr->proposed_vcpis[i]->vcpi;
    1810           0 :                 } else {
    1811             :                         port = NULL;
    1812           0 :                         req_payload.num_slots = 0;
    1813             :                 }
    1814             : 
    1815           0 :                 if (mgr->payloads[i].start_slot != req_payload.start_slot) {
    1816           0 :                         mgr->payloads[i].start_slot = req_payload.start_slot;
    1817           0 :                 }
    1818             :                 /* work out what is required to happen with this payload */
    1819           0 :                 if (mgr->payloads[i].num_slots != req_payload.num_slots) {
    1820             : 
    1821             :                         /* need to push an update for this payload */
    1822           0 :                         if (req_payload.num_slots) {
    1823           0 :                                 drm_dp_create_payload_step1(mgr, mgr->proposed_vcpis[i]->vcpi, &req_payload);
    1824           0 :                                 mgr->payloads[i].num_slots = req_payload.num_slots;
    1825           0 :                                 mgr->payloads[i].vcpi = req_payload.vcpi;
    1826           0 :                         } else if (mgr->payloads[i].num_slots) {
    1827           0 :                                 mgr->payloads[i].num_slots = 0;
    1828           0 :                                 drm_dp_destroy_payload_step1(mgr, port, mgr->payloads[i].vcpi, &mgr->payloads[i]);
    1829           0 :                                 req_payload.payload_state = mgr->payloads[i].payload_state;
    1830           0 :                                 mgr->payloads[i].start_slot = 0;
    1831           0 :                         }
    1832           0 :                         mgr->payloads[i].payload_state = req_payload.payload_state;
    1833           0 :                 }
    1834           0 :                 cur_slots += req_payload.num_slots;
    1835             : 
    1836           0 :                 if (port)
    1837           0 :                         drm_dp_put_port(port);
    1838             :         }
    1839             : 
    1840           0 :         for (i = 0; i < mgr->max_payloads; i++) {
    1841           0 :                 if (mgr->payloads[i].payload_state == DP_PAYLOAD_DELETE_LOCAL) {
    1842             :                         DRM_DEBUG_KMS("removing payload %d\n", i);
    1843           0 :                         for (j = i; j < mgr->max_payloads - 1; j++) {
    1844           0 :                                 memcpy(&mgr->payloads[j], &mgr->payloads[j + 1], sizeof(struct drm_dp_payload));
    1845           0 :                                 mgr->proposed_vcpis[j] = mgr->proposed_vcpis[j + 1];
    1846           0 :                                 if (mgr->proposed_vcpis[j] && mgr->proposed_vcpis[j]->num_slots) {
    1847           0 :                                         set_bit(j + 1, &mgr->payload_mask);
    1848           0 :                                 } else {
    1849           0 :                                         clear_bit(j + 1, &mgr->payload_mask);
    1850             :                                 }
    1851             :                         }
    1852           0 :                         memset(&mgr->payloads[mgr->max_payloads - 1], 0, sizeof(struct drm_dp_payload));
    1853           0 :                         mgr->proposed_vcpis[mgr->max_payloads - 1] = NULL;
    1854           0 :                         clear_bit(mgr->max_payloads, &mgr->payload_mask);
    1855             : 
    1856           0 :                 }
    1857             :         }
    1858           0 :         mutex_unlock(&mgr->payload_lock);
    1859             : 
    1860           0 :         return 0;
    1861           0 : }
    1862             : EXPORT_SYMBOL(drm_dp_update_payload_part1);
    1863             : 
    1864             : /**
    1865             :  * drm_dp_update_payload_part2() - Execute payload update part 2
    1866             :  * @mgr: manager to use.
    1867             :  *
    1868             :  * This iterates over all proposed virtual channels, and tries to
    1869             :  * allocate space in the link for them. For 0->slots transitions,
    1870             :  * this step writes the remote VC payload commands. For slots->0
    1871             :  * this just resets some internal state.
    1872             :  */
    1873           0 : int drm_dp_update_payload_part2(struct drm_dp_mst_topology_mgr *mgr)
    1874             : {
    1875             :         struct drm_dp_mst_port *port;
    1876             :         int i;
    1877             :         int ret = 0;
    1878           0 :         mutex_lock(&mgr->payload_lock);
    1879           0 :         for (i = 0; i < mgr->max_payloads; i++) {
    1880             : 
    1881           0 :                 if (!mgr->proposed_vcpis[i])
    1882             :                         continue;
    1883             : 
    1884           0 :                 port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi);
    1885             : 
    1886             :                 DRM_DEBUG_KMS("payload %d %d\n", i, mgr->payloads[i].payload_state);
    1887           0 :                 if (mgr->payloads[i].payload_state == DP_PAYLOAD_LOCAL) {
    1888           0 :                         ret = drm_dp_create_payload_step2(mgr, port, mgr->proposed_vcpis[i]->vcpi, &mgr->payloads[i]);
    1889           0 :                 } else if (mgr->payloads[i].payload_state == DP_PAYLOAD_DELETE_LOCAL) {
    1890           0 :                         ret = drm_dp_destroy_payload_step2(mgr, mgr->proposed_vcpis[i]->vcpi, &mgr->payloads[i]);
    1891           0 :                 }
    1892           0 :                 if (ret) {
    1893           0 :                         mutex_unlock(&mgr->payload_lock);
    1894           0 :                         return ret;
    1895             :                 }
    1896             :         }
    1897           0 :         mutex_unlock(&mgr->payload_lock);
    1898           0 :         return 0;
    1899           0 : }
    1900             : EXPORT_SYMBOL(drm_dp_update_payload_part2);
    1901             : 
    1902             : #if 0 /* unused as of yet */
    1903             : static int drm_dp_send_dpcd_read(struct drm_dp_mst_topology_mgr *mgr,
    1904             :                                  struct drm_dp_mst_port *port,
    1905             :                                  int offset, int size)
    1906             : {
    1907             :         int len;
    1908             :         struct drm_dp_sideband_msg_tx *txmsg;
    1909             : 
    1910             :         txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
    1911             :         if (!txmsg)
    1912             :                 return -ENOMEM;
    1913             : 
    1914             :         len = build_dpcd_read(txmsg, port->port_num, 0, 8);
    1915             :         txmsg->dst = port->parent;
    1916             : 
    1917             :         drm_dp_queue_down_tx(mgr, txmsg);
    1918             : 
    1919             :         return 0;
    1920             : }
    1921             : #endif
    1922             : 
    1923           0 : static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr,
    1924             :                                   struct drm_dp_mst_port *port,
    1925             :                                   int offset, int size, u8 *bytes)
    1926             : {
    1927             :         int len;
    1928             :         int ret;
    1929             :         struct drm_dp_sideband_msg_tx *txmsg;
    1930             :         struct drm_dp_mst_branch *mstb;
    1931             : 
    1932           0 :         mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent);
    1933           0 :         if (!mstb)
    1934           0 :                 return -EINVAL;
    1935             : 
    1936           0 :         txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
    1937           0 :         if (!txmsg) {
    1938             :                 ret = -ENOMEM;
    1939           0 :                 goto fail_put;
    1940             :         }
    1941             : 
    1942           0 :         len = build_dpcd_write(txmsg, port->port_num, offset, size, bytes);
    1943           0 :         txmsg->dst = mstb;
    1944             : 
    1945           0 :         drm_dp_queue_down_tx(mgr, txmsg);
    1946             : 
    1947           0 :         ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
    1948           0 :         if (ret > 0) {
    1949           0 :                 if (txmsg->reply.reply_type == 1) {
    1950             :                         ret = -EINVAL;
    1951           0 :                 } else
    1952             :                         ret = 0;
    1953             :         }
    1954           0 :         kfree(txmsg);
    1955             : fail_put:
    1956           0 :         drm_dp_put_mst_branch_device(mstb);
    1957           0 :         return ret;
    1958           0 : }
    1959             : 
    1960           0 : static int drm_dp_encode_up_ack_reply(struct drm_dp_sideband_msg_tx *msg, u8 req_type)
    1961             : {
    1962           0 :         struct drm_dp_sideband_msg_reply_body reply;
    1963             : 
    1964           0 :         reply.reply_type = 1;
    1965           0 :         reply.req_type = req_type;
    1966           0 :         drm_dp_encode_sideband_reply(&reply, msg);
    1967           0 :         return 0;
    1968           0 : }
    1969             : 
    1970           0 : static int drm_dp_send_up_ack_reply(struct drm_dp_mst_topology_mgr *mgr,
    1971             :                                     struct drm_dp_mst_branch *mstb,
    1972             :                                     int req_type, int seqno, bool broadcast)
    1973             : {
    1974             :         struct drm_dp_sideband_msg_tx *txmsg;
    1975             : 
    1976           0 :         txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
    1977           0 :         if (!txmsg)
    1978           0 :                 return -ENOMEM;
    1979             : 
    1980           0 :         txmsg->dst = mstb;
    1981           0 :         txmsg->seqno = seqno;
    1982           0 :         drm_dp_encode_up_ack_reply(txmsg, req_type);
    1983             : 
    1984           0 :         mutex_lock(&mgr->qlock);
    1985             : 
    1986           0 :         process_single_up_tx_qlock(mgr, txmsg);
    1987             : 
    1988           0 :         mutex_unlock(&mgr->qlock);
    1989             : 
    1990           0 :         kfree(txmsg);
    1991           0 :         return 0;
    1992           0 : }
    1993             : 
    1994           0 : static bool drm_dp_get_vc_payload_bw(int dp_link_bw,
    1995             :                                      int dp_link_count,
    1996             :                                      int *out)
    1997             : {
    1998           0 :         switch (dp_link_bw) {
    1999             :         default:
    2000             :                 DRM_DEBUG_KMS("invalid link bandwidth in DPCD: %x (link count: %d)\n",
    2001             :                               dp_link_bw, dp_link_count);
    2002           0 :                 return false;
    2003             : 
    2004             :         case DP_LINK_BW_1_62:
    2005           0 :                 *out = 3 * dp_link_count;
    2006           0 :                 break;
    2007             :         case DP_LINK_BW_2_7:
    2008           0 :                 *out = 5 * dp_link_count;
    2009           0 :                 break;
    2010             :         case DP_LINK_BW_5_4:
    2011           0 :                 *out = 10 * dp_link_count;
    2012           0 :                 break;
    2013             :         }
    2014           0 :         return true;
    2015           0 : }
    2016             : 
    2017             : /**
    2018             :  * drm_dp_mst_topology_mgr_set_mst() - Set the MST state for a topology manager
    2019             :  * @mgr: manager to set state for
    2020             :  * @mst_state: true to enable MST on this connector - false to disable.
    2021             :  *
    2022             :  * This is called by the driver when it detects an MST capable device plugged
    2023             :  * into a DP MST capable port, or when a DP MST capable device is unplugged.
    2024             :  */
    2025           0 : int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool mst_state)
    2026             : {
    2027             :         int ret = 0;
    2028             :         struct drm_dp_mst_branch *mstb = NULL;
    2029             : 
    2030           0 :         mutex_lock(&mgr->lock);
    2031           0 :         if (mst_state == mgr->mst_state)
    2032             :                 goto out_unlock;
    2033             : 
    2034           0 :         mgr->mst_state = mst_state;
    2035             :         /* set the device into MST mode */
    2036           0 :         if (mst_state) {
    2037           0 :                 WARN_ON(mgr->mst_primary);
    2038             : 
    2039             :                 /* get dpcd info */
    2040           0 :                 ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE);
    2041           0 :                 if (ret != DP_RECEIVER_CAP_SIZE) {
    2042             :                         DRM_DEBUG_KMS("failed to read DPCD\n");
    2043             :                         goto out_unlock;
    2044             :                 }
    2045             : 
    2046           0 :                 if (!drm_dp_get_vc_payload_bw(mgr->dpcd[1],
    2047           0 :                                               mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK,
    2048           0 :                                               &mgr->pbn_div)) {
    2049             :                         ret = -EINVAL;
    2050           0 :                         goto out_unlock;
    2051             :                 }
    2052             : 
    2053           0 :                 mgr->total_pbn = 2560;
    2054           0 :                 mgr->total_slots = DIV_ROUND_UP(mgr->total_pbn, mgr->pbn_div);
    2055           0 :                 mgr->avail_slots = mgr->total_slots;
    2056             : 
    2057             :                 /* add initial branch device at LCT 1 */
    2058           0 :                 mstb = drm_dp_add_mst_branch_device(1, NULL);
    2059           0 :                 if (mstb == NULL) {
    2060             :                         ret = -ENOMEM;
    2061           0 :                         goto out_unlock;
    2062             :                 }
    2063           0 :                 mstb->mgr = mgr;
    2064             : 
    2065             :                 /* give this the main reference */
    2066           0 :                 mgr->mst_primary = mstb;
    2067           0 :                 kref_get(&mgr->mst_primary->kref);
    2068             : 
    2069           0 :                 ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,
    2070             :                                                          DP_MST_EN | DP_UP_REQ_EN | DP_UPSTREAM_IS_SRC);
    2071           0 :                 if (ret < 0) {
    2072             :                         goto out_unlock;
    2073             :                 }
    2074             : 
    2075             :                 {
    2076           0 :                         struct drm_dp_payload reset_pay;
    2077           0 :                         reset_pay.start_slot = 0;
    2078           0 :                         reset_pay.num_slots = 0x3f;
    2079           0 :                         drm_dp_dpcd_write_payload(mgr, 0, &reset_pay);
    2080           0 :                 }
    2081             : 
    2082           0 :                 queue_work(system_long_wq, &mgr->work);
    2083             : 
    2084             :                 ret = 0;
    2085           0 :         } else {
    2086             :                 /* disable MST on the device */
    2087           0 :                 mstb = mgr->mst_primary;
    2088           0 :                 mgr->mst_primary = NULL;
    2089             :                 /* this can fail if the device is gone */
    2090           0 :                 drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL, 0);
    2091             :                 ret = 0;
    2092           0 :                 memset(mgr->payloads, 0, mgr->max_payloads * sizeof(struct drm_dp_payload));
    2093           0 :                 mgr->payload_mask = 0;
    2094           0 :                 set_bit(0, &mgr->payload_mask);
    2095           0 :                 mgr->vcpi_mask = 0;
    2096             :         }
    2097             : 
    2098             : out_unlock:
    2099           0 :         mutex_unlock(&mgr->lock);
    2100           0 :         if (mstb)
    2101           0 :                 drm_dp_put_mst_branch_device(mstb);
    2102           0 :         return ret;
    2103             : 
    2104             : }
    2105             : EXPORT_SYMBOL(drm_dp_mst_topology_mgr_set_mst);
    2106             : 
    2107             : /**
    2108             :  * drm_dp_mst_topology_mgr_suspend() - suspend the MST manager
    2109             :  * @mgr: manager to suspend
    2110             :  *
    2111             :  * This function tells the MST device that we can't handle UP messages
    2112             :  * anymore. This should stop it from sending any since we are suspended.
    2113             :  */
    2114           0 : void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr)
    2115             : {
    2116           0 :         mutex_lock(&mgr->lock);
    2117           0 :         drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,
    2118             :                            DP_MST_EN | DP_UPSTREAM_IS_SRC);
    2119           0 :         mutex_unlock(&mgr->lock);
    2120           0 :         flush_work(&mgr->work);
    2121           0 :         flush_work(&mgr->destroy_connector_work);
    2122           0 : }
    2123             : EXPORT_SYMBOL(drm_dp_mst_topology_mgr_suspend);
    2124             : 
    2125             : /**
    2126             :  * drm_dp_mst_topology_mgr_resume() - resume the MST manager
    2127             :  * @mgr: manager to resume
    2128             :  *
    2129             :  * This will fetch DPCD and see if the device is still there,
    2130             :  * if it is, it will rewrite the MSTM control bits, and return.
    2131             :  *
    2132             :  * if the device fails this returns -1, and the driver should do
    2133             :  * a full MST reprobe, in case we were undocked.
    2134             :  */
    2135           0 : int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr)
    2136             : {
    2137             :         int ret = 0;
    2138             : 
    2139           0 :         mutex_lock(&mgr->lock);
    2140             : 
    2141           0 :         if (mgr->mst_primary) {
    2142             :                 int sret;
    2143           0 :                 u8 guid[16];
    2144             : 
    2145           0 :                 sret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE);
    2146           0 :                 if (sret != DP_RECEIVER_CAP_SIZE) {
    2147             :                         DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n");
    2148             :                         ret = -1;
    2149           0 :                         goto out_unlock;
    2150             :                 }
    2151             : 
    2152           0 :                 ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,
    2153             :                                          DP_MST_EN | DP_UP_REQ_EN | DP_UPSTREAM_IS_SRC);
    2154           0 :                 if (ret < 0) {
    2155             :                         DRM_DEBUG_KMS("mst write failed - undocked during suspend?\n");
    2156             :                         ret = -1;
    2157           0 :                         goto out_unlock;
    2158             :                 }
    2159             : 
    2160             :                 /* Some hubs forget their guids after they resume */
    2161           0 :                 sret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16);
    2162           0 :                 if (sret != 16) {
    2163             :                         DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n");
    2164             :                         ret = -1;
    2165           0 :                         goto out_unlock;
    2166             :                 }
    2167           0 :                 drm_dp_check_mstb_guid(mgr->mst_primary, guid);
    2168             : 
    2169             :                 ret = 0;
    2170           0 :         } else
    2171             :                 ret = -1;
    2172             : 
    2173             : out_unlock:
    2174           0 :         mutex_unlock(&mgr->lock);
    2175           0 :         return ret;
    2176           0 : }
    2177             : EXPORT_SYMBOL(drm_dp_mst_topology_mgr_resume);
    2178             : 
    2179           0 : static bool drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up)
    2180             : {
    2181             :         int len;
    2182           0 :         u8 replyblock[32];
    2183             :         int replylen, origlen, curreply;
    2184             :         int ret;
    2185             :         struct drm_dp_sideband_msg_rx *msg;
    2186           0 :         int basereg = up ? DP_SIDEBAND_MSG_UP_REQ_BASE : DP_SIDEBAND_MSG_DOWN_REP_BASE;
    2187           0 :         msg = up ? &mgr->up_req_recv : &mgr->down_rep_recv;
    2188             : 
    2189           0 :         len = min(mgr->max_dpcd_transaction_bytes, 16);
    2190           0 :         ret = drm_dp_dpcd_read(mgr->aux, basereg,
    2191           0 :                                replyblock, len);
    2192           0 :         if (ret != len) {
    2193             :                 DRM_DEBUG_KMS("failed to read DPCD down rep %d %d\n", len, ret);
    2194           0 :                 return false;
    2195             :         }
    2196           0 :         ret = drm_dp_sideband_msg_build(msg, replyblock, len, true);
    2197           0 :         if (!ret) {
    2198             :                 DRM_DEBUG_KMS("sideband msg build failed %d\n", replyblock[0]);
    2199           0 :                 return false;
    2200             :         }
    2201           0 :         replylen = msg->curchunk_len + msg->curchunk_hdrlen;
    2202             : 
    2203             :         origlen = replylen;
    2204           0 :         replylen -= len;
    2205             :         curreply = len;
    2206           0 :         while (replylen > 0) {
    2207           0 :                 len = min3(replylen, mgr->max_dpcd_transaction_bytes, 16);
    2208           0 :                 ret = drm_dp_dpcd_read(mgr->aux, basereg + curreply,
    2209           0 :                                     replyblock, len);
    2210           0 :                 if (ret != len) {
    2211             :                         DRM_DEBUG_KMS("failed to read a chunk (len %d, ret %d)\n",
    2212             :                                       len, ret);
    2213           0 :                         return false;
    2214             :                 }
    2215             : 
    2216           0 :                 ret = drm_dp_sideband_msg_build(msg, replyblock, len, false);
    2217           0 :                 if (!ret) {
    2218             :                         DRM_DEBUG_KMS("failed to build sideband msg\n");
    2219           0 :                         return false;
    2220             :                 }
    2221             : 
    2222           0 :                 curreply += len;
    2223           0 :                 replylen -= len;
    2224             :         }
    2225           0 :         return true;
    2226           0 : }
    2227             : 
    2228           0 : static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)
    2229             : {
    2230             :         int ret = 0;
    2231             : 
    2232           0 :         if (!drm_dp_get_one_sb_msg(mgr, false)) {
    2233           0 :                 memset(&mgr->down_rep_recv, 0,
    2234             :                        sizeof(struct drm_dp_sideband_msg_rx));
    2235           0 :                 return 0;
    2236             :         }
    2237             : 
    2238           0 :         if (mgr->down_rep_recv.have_eomt) {
    2239             :                 struct drm_dp_sideband_msg_tx *txmsg;
    2240             :                 struct drm_dp_mst_branch *mstb;
    2241             :                 int slot = -1;
    2242           0 :                 mstb = drm_dp_get_mst_branch_device(mgr,
    2243           0 :                                                     mgr->down_rep_recv.initial_hdr.lct,
    2244           0 :                                                     mgr->down_rep_recv.initial_hdr.rad);
    2245             : 
    2246           0 :                 if (!mstb) {
    2247             :                         DRM_DEBUG_KMS("Got MST reply from unknown device %d\n", mgr->down_rep_recv.initial_hdr.lct);
    2248           0 :                         memset(&mgr->down_rep_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
    2249           0 :                         return 0;
    2250             :                 }
    2251             : 
    2252             :                 /* find the message */
    2253           0 :                 slot = mgr->down_rep_recv.initial_hdr.seqno;
    2254           0 :                 mutex_lock(&mgr->qlock);
    2255           0 :                 txmsg = mstb->tx_slots[slot];
    2256             :                 /* remove from slots */
    2257           0 :                 mutex_unlock(&mgr->qlock);
    2258             : 
    2259           0 :                 if (!txmsg) {
    2260             :                         DRM_DEBUG_KMS("Got MST reply with no msg %p %d %d %02x %02x\n",
    2261             :                                mstb,
    2262             :                                mgr->down_rep_recv.initial_hdr.seqno,
    2263             :                                mgr->down_rep_recv.initial_hdr.lct,
    2264             :                                       mgr->down_rep_recv.initial_hdr.rad[0],
    2265             :                                       mgr->down_rep_recv.msg[0]);
    2266           0 :                         drm_dp_put_mst_branch_device(mstb);
    2267           0 :                         memset(&mgr->down_rep_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
    2268           0 :                         return 0;
    2269             :                 }
    2270             : 
    2271           0 :                 drm_dp_sideband_parse_reply(&mgr->down_rep_recv, &txmsg->reply);
    2272           0 :                 if (txmsg->reply.reply_type == 1) {
    2273             :                         DRM_DEBUG_KMS("Got NAK reply: req 0x%02x, reason 0x%02x, nak data 0x%02x\n", txmsg->reply.req_type, txmsg->reply.u.nak.reason, txmsg->reply.u.nak.nak_data);
    2274             :                 }
    2275             : 
    2276           0 :                 memset(&mgr->down_rep_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
    2277           0 :                 drm_dp_put_mst_branch_device(mstb);
    2278             : 
    2279           0 :                 mutex_lock(&mgr->qlock);
    2280           0 :                 txmsg->state = DRM_DP_SIDEBAND_TX_RX;
    2281           0 :                 mstb->tx_slots[slot] = NULL;
    2282           0 :                 mutex_unlock(&mgr->qlock);
    2283             : 
    2284           0 :                 wake_up(&mgr->tx_waitq);
    2285           0 :         }
    2286           0 :         return ret;
    2287           0 : }
    2288             : 
    2289           0 : static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
    2290             : {
    2291             :         int ret = 0;
    2292             : 
    2293           0 :         if (!drm_dp_get_one_sb_msg(mgr, true)) {
    2294           0 :                 memset(&mgr->up_req_recv, 0,
    2295             :                        sizeof(struct drm_dp_sideband_msg_rx));
    2296           0 :                 return 0;
    2297             :         }
    2298             : 
    2299           0 :         if (mgr->up_req_recv.have_eomt) {
    2300           0 :                 struct drm_dp_sideband_msg_req_body msg;
    2301             :                 struct drm_dp_mst_branch *mstb = NULL;
    2302             :                 bool seqno;
    2303             : 
    2304           0 :                 if (!mgr->up_req_recv.initial_hdr.broadcast) {
    2305           0 :                         mstb = drm_dp_get_mst_branch_device(mgr,
    2306           0 :                                                             mgr->up_req_recv.initial_hdr.lct,
    2307           0 :                                                             mgr->up_req_recv.initial_hdr.rad);
    2308           0 :                         if (!mstb) {
    2309             :                                 DRM_DEBUG_KMS("Got MST reply from unknown device %d\n", mgr->up_req_recv.initial_hdr.lct);
    2310           0 :                                 memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
    2311           0 :                                 return 0;
    2312             :                         }
    2313             :                 }
    2314             : 
    2315           0 :                 seqno = mgr->up_req_recv.initial_hdr.seqno;
    2316           0 :                 drm_dp_sideband_parse_req(&mgr->up_req_recv, &msg);
    2317             : 
    2318           0 :                 if (msg.req_type == DP_CONNECTION_STATUS_NOTIFY) {
    2319           0 :                         drm_dp_send_up_ack_reply(mgr, mgr->mst_primary, msg.req_type, seqno, false);
    2320             : 
    2321           0 :                         if (!mstb)
    2322           0 :                                 mstb = drm_dp_get_mst_branch_device_by_guid(mgr, msg.u.conn_stat.guid);
    2323             : 
    2324           0 :                         if (!mstb) {
    2325             :                                 DRM_DEBUG_KMS("Got MST reply from unknown device %d\n", mgr->up_req_recv.initial_hdr.lct);
    2326           0 :                                 memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
    2327           0 :                                 return 0;
    2328             :                         }
    2329             : 
    2330           0 :                         drm_dp_update_port(mstb, &msg.u.conn_stat);
    2331             : 
    2332             :                         DRM_DEBUG_KMS("Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n", msg.u.conn_stat.port_number, msg.u.conn_stat.legacy_device_plug_status, msg.u.conn_stat.displayport_device_plug_status, msg.u.conn_stat.message_capability_status, msg.u.conn_stat.input_port, msg.u.conn_stat.peer_device_type);
    2333           0 :                         (*mgr->cbs->hotplug)(mgr);
    2334             : 
    2335           0 :                 } else if (msg.req_type == DP_RESOURCE_STATUS_NOTIFY) {
    2336           0 :                         drm_dp_send_up_ack_reply(mgr, mgr->mst_primary, msg.req_type, seqno, false);
    2337           0 :                         if (!mstb)
    2338           0 :                                 mstb = drm_dp_get_mst_branch_device_by_guid(mgr, msg.u.resource_stat.guid);
    2339             : 
    2340           0 :                         if (!mstb) {
    2341             :                                 DRM_DEBUG_KMS("Got MST reply from unknown device %d\n", mgr->up_req_recv.initial_hdr.lct);
    2342           0 :                                 memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
    2343           0 :                                 return 0;
    2344             :                         }
    2345             : 
    2346             :                         DRM_DEBUG_KMS("Got RSN: pn: %d avail_pbn %d\n", msg.u.resource_stat.port_number, msg.u.resource_stat.available_pbn);
    2347             :                 }
    2348             : 
    2349           0 :                 if (mstb)
    2350           0 :                         drm_dp_put_mst_branch_device(mstb);
    2351             : 
    2352           0 :                 memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
    2353           0 :         }
    2354           0 :         return ret;
    2355           0 : }
    2356             : 
    2357             : /**
    2358             :  * drm_dp_mst_hpd_irq() - MST hotplug IRQ notify
    2359             :  * @mgr: manager to notify irq for.
    2360             :  * @esi: 4 bytes from SINK_COUNT_ESI
    2361             :  * @handled: whether the hpd interrupt was consumed or not
    2362             :  *
    2363             :  * This should be called from the driver when it detects a short IRQ,
    2364             :  * along with the value of the DEVICE_SERVICE_IRQ_VECTOR_ESI0. The
    2365             :  * topology manager will process the sideband messages received as a result
    2366             :  * of this.
    2367             :  */
    2368           0 : int drm_dp_mst_hpd_irq(struct drm_dp_mst_topology_mgr *mgr, u8 *esi, bool *handled)
    2369             : {
    2370             :         int ret = 0;
    2371             :         int sc;
    2372           0 :         *handled = false;
    2373           0 :         sc = esi[0] & 0x3f;
    2374             : 
    2375           0 :         if (sc != mgr->sink_count) {
    2376           0 :                 mgr->sink_count = sc;
    2377           0 :                 *handled = true;
    2378           0 :         }
    2379             : 
    2380           0 :         if (esi[1] & DP_DOWN_REP_MSG_RDY) {
    2381           0 :                 ret = drm_dp_mst_handle_down_rep(mgr);
    2382           0 :                 *handled = true;
    2383           0 :         }
    2384             : 
    2385           0 :         if (esi[1] & DP_UP_REQ_MSG_RDY) {
    2386           0 :                 ret |= drm_dp_mst_handle_up_req(mgr);
    2387           0 :                 *handled = true;
    2388           0 :         }
    2389             : 
    2390           0 :         drm_dp_mst_kick_tx(mgr);
    2391           0 :         return ret;
    2392             : }
    2393             : EXPORT_SYMBOL(drm_dp_mst_hpd_irq);
    2394             : 
    2395             : /**
    2396             :  * drm_dp_mst_detect_port() - get connection status for an MST port
    2397             :  * @mgr: manager for this port
    2398             :  * @port: unverified pointer to a port
    2399             :  *
    2400             :  * This returns the current connection state for a port. It validates the
    2401             :  * port pointer still exists so the caller doesn't require a reference
    2402             :  */
    2403           0 : enum drm_connector_status drm_dp_mst_detect_port(struct drm_connector *connector,
    2404             :                                                  struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
    2405             : {
    2406             :         enum drm_connector_status status = connector_status_disconnected;
    2407             : 
    2408             :         /* we need to search for the port in the mgr in case its gone */
    2409           0 :         port = drm_dp_get_validated_port_ref(mgr, port);
    2410           0 :         if (!port)
    2411           0 :                 return connector_status_disconnected;
    2412             : 
    2413           0 :         if (!port->ddps)
    2414             :                 goto out;
    2415             : 
    2416           0 :         switch (port->pdt) {
    2417             :         case DP_PEER_DEVICE_NONE:
    2418             :         case DP_PEER_DEVICE_MST_BRANCHING:
    2419             :                 break;
    2420             : 
    2421             :         case DP_PEER_DEVICE_SST_SINK:
    2422             :                 status = connector_status_connected;
    2423             :                 /* for logical ports - cache the EDID */
    2424           0 :                 if (port->port_num >= 8 && !port->cached_edid) {
    2425           0 :                         port->cached_edid = drm_get_edid(connector, &port->aux.ddc);
    2426           0 :                 }
    2427             :                 break;
    2428             :         case DP_PEER_DEVICE_DP_LEGACY_CONV:
    2429           0 :                 if (port->ldps)
    2430           0 :                         status = connector_status_connected;
    2431             :                 break;
    2432             :         }
    2433             : out:
    2434           0 :         drm_dp_put_port(port);
    2435           0 :         return status;
    2436           0 : }
    2437             : EXPORT_SYMBOL(drm_dp_mst_detect_port);
    2438             : 
    2439             : /**
    2440             :  * drm_dp_mst_get_edid() - get EDID for an MST port
    2441             :  * @connector: toplevel connector to get EDID for
    2442             :  * @mgr: manager for this port
    2443             :  * @port: unverified pointer to a port.
    2444             :  *
    2445             :  * This returns an EDID for the port connected to a connector,
    2446             :  * It validates the pointer still exists so the caller doesn't require a
    2447             :  * reference.
    2448             :  */
    2449           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)
    2450             : {
    2451             :         struct edid *edid = NULL;
    2452             : 
    2453             :         /* we need to search for the port in the mgr in case its gone */
    2454           0 :         port = drm_dp_get_validated_port_ref(mgr, port);
    2455           0 :         if (!port)
    2456           0 :                 return NULL;
    2457             : 
    2458           0 :         if (port->cached_edid)
    2459           0 :                 edid = drm_edid_duplicate(port->cached_edid);
    2460             :         else {
    2461           0 :                 edid = drm_get_edid(connector, &port->aux.ddc);
    2462           0 :                 drm_mode_connector_set_tile_property(connector);
    2463             :         }
    2464           0 :         drm_dp_put_port(port);
    2465           0 :         return edid;
    2466           0 : }
    2467             : EXPORT_SYMBOL(drm_dp_mst_get_edid);
    2468             : 
    2469             : /**
    2470             :  * drm_dp_find_vcpi_slots() - find slots for this PBN value
    2471             :  * @mgr: manager to use
    2472             :  * @pbn: payload bandwidth to convert into slots.
    2473             :  */
    2474           0 : int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
    2475             :                            int pbn)
    2476             : {
    2477             :         int num_slots;
    2478             : 
    2479           0 :         num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
    2480             : 
    2481           0 :         if (num_slots > mgr->avail_slots)
    2482           0 :                 return -ENOSPC;
    2483           0 :         return num_slots;
    2484           0 : }
    2485             : EXPORT_SYMBOL(drm_dp_find_vcpi_slots);
    2486             : 
    2487           0 : static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
    2488             :                             struct drm_dp_vcpi *vcpi, int pbn)
    2489             : {
    2490             :         int num_slots;
    2491             :         int ret;
    2492             : 
    2493           0 :         num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
    2494             : 
    2495           0 :         if (num_slots > mgr->avail_slots)
    2496           0 :                 return -ENOSPC;
    2497             : 
    2498           0 :         vcpi->pbn = pbn;
    2499           0 :         vcpi->aligned_pbn = num_slots * mgr->pbn_div;
    2500           0 :         vcpi->num_slots = num_slots;
    2501             : 
    2502           0 :         ret = drm_dp_mst_assign_payload_id(mgr, vcpi);
    2503           0 :         if (ret < 0)
    2504           0 :                 return ret;
    2505           0 :         return 0;
    2506           0 : }
    2507             : 
    2508             : /**
    2509             :  * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
    2510             :  * @mgr: manager for this port
    2511             :  * @port: port to allocate a virtual channel for.
    2512             :  * @pbn: payload bandwidth number to request
    2513             :  * @slots: returned number of slots for this PBN.
    2514             :  */
    2515           0 : bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, int pbn, int *slots)
    2516             : {
    2517             :         int ret;
    2518             : 
    2519           0 :         port = drm_dp_get_validated_port_ref(mgr, port);
    2520           0 :         if (!port)
    2521           0 :                 return false;
    2522             : 
    2523           0 :         if (port->vcpi.vcpi > 0) {
    2524             :                 DRM_DEBUG_KMS("payload: vcpi %d already allocated for pbn %d - requested pbn %d\n", port->vcpi.vcpi, port->vcpi.pbn, pbn);
    2525           0 :                 if (pbn == port->vcpi.pbn) {
    2526           0 :                         *slots = port->vcpi.num_slots;
    2527           0 :                         drm_dp_put_port(port);
    2528           0 :                         return true;
    2529             :                 }
    2530             :         }
    2531             : 
    2532           0 :         ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn);
    2533           0 :         if (ret) {
    2534             :                 DRM_DEBUG_KMS("failed to init vcpi %d %d %d\n", DIV_ROUND_UP(pbn, mgr->pbn_div), mgr->avail_slots, ret);
    2535             :                 goto out;
    2536             :         }
    2537             :         DRM_DEBUG_KMS("initing vcpi for %d %d\n", pbn, port->vcpi.num_slots);
    2538           0 :         *slots = port->vcpi.num_slots;
    2539             : 
    2540           0 :         drm_dp_put_port(port);
    2541           0 :         return true;
    2542             : out:
    2543           0 :         return false;
    2544           0 : }
    2545             : EXPORT_SYMBOL(drm_dp_mst_allocate_vcpi);
    2546             : 
    2547           0 : int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
    2548             : {
    2549             :         int slots = 0;
    2550           0 :         port = drm_dp_get_validated_port_ref(mgr, port);
    2551           0 :         if (!port)
    2552           0 :                 return slots;
    2553             : 
    2554           0 :         slots = port->vcpi.num_slots;
    2555           0 :         drm_dp_put_port(port);
    2556           0 :         return slots;
    2557           0 : }
    2558             : EXPORT_SYMBOL(drm_dp_mst_get_vcpi_slots);
    2559             : 
    2560             : /**
    2561             :  * drm_dp_mst_reset_vcpi_slots() - Reset number of slots to 0 for VCPI
    2562             :  * @mgr: manager for this port
    2563             :  * @port: unverified pointer to a port.
    2564             :  *
    2565             :  * This just resets the number of slots for the ports VCPI for later programming.
    2566             :  */
    2567           0 : void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
    2568             : {
    2569           0 :         port = drm_dp_get_validated_port_ref(mgr, port);
    2570           0 :         if (!port)
    2571             :                 return;
    2572           0 :         port->vcpi.num_slots = 0;
    2573           0 :         drm_dp_put_port(port);
    2574           0 : }
    2575             : EXPORT_SYMBOL(drm_dp_mst_reset_vcpi_slots);
    2576             : 
    2577             : /**
    2578             :  * drm_dp_mst_deallocate_vcpi() - deallocate a VCPI
    2579             :  * @mgr: manager for this port
    2580             :  * @port: unverified port to deallocate vcpi for
    2581             :  */
    2582           0 : void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
    2583             : {
    2584           0 :         port = drm_dp_get_validated_port_ref(mgr, port);
    2585           0 :         if (!port)
    2586             :                 return;
    2587             : 
    2588           0 :         drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
    2589           0 :         port->vcpi.num_slots = 0;
    2590           0 :         port->vcpi.pbn = 0;
    2591           0 :         port->vcpi.aligned_pbn = 0;
    2592           0 :         port->vcpi.vcpi = 0;
    2593           0 :         drm_dp_put_port(port);
    2594           0 : }
    2595             : EXPORT_SYMBOL(drm_dp_mst_deallocate_vcpi);
    2596             : 
    2597           0 : static int drm_dp_dpcd_write_payload(struct drm_dp_mst_topology_mgr *mgr,
    2598             :                                      int id, struct drm_dp_payload *payload)
    2599             : {
    2600           0 :         u8 payload_alloc[3], status;
    2601             :         int ret;
    2602             :         int retries = 0;
    2603             : 
    2604           0 :         drm_dp_dpcd_writeb(mgr->aux, DP_PAYLOAD_TABLE_UPDATE_STATUS,
    2605             :                            DP_PAYLOAD_TABLE_UPDATED);
    2606             : 
    2607           0 :         payload_alloc[0] = id;
    2608           0 :         payload_alloc[1] = payload->start_slot;
    2609           0 :         payload_alloc[2] = payload->num_slots;
    2610             : 
    2611           0 :         ret = drm_dp_dpcd_write(mgr->aux, DP_PAYLOAD_ALLOCATE_SET, payload_alloc, 3);
    2612           0 :         if (ret != 3) {
    2613             :                 DRM_DEBUG_KMS("failed to write payload allocation %d\n", ret);
    2614             :                 goto fail;
    2615             :         }
    2616             : 
    2617             : retry:
    2618           0 :         ret = drm_dp_dpcd_readb(mgr->aux, DP_PAYLOAD_TABLE_UPDATE_STATUS, &status);
    2619           0 :         if (ret < 0) {
    2620             :                 DRM_DEBUG_KMS("failed to read payload table status %d\n", ret);
    2621             :                 goto fail;
    2622             :         }
    2623             : 
    2624           0 :         if (!(status & DP_PAYLOAD_TABLE_UPDATED)) {
    2625           0 :                 retries++;
    2626           0 :                 if (retries < 20) {
    2627           0 :                         usleep_range(10000, 20000);
    2628           0 :                         goto retry;
    2629             :                 }
    2630             :                 DRM_DEBUG_KMS("status not set after read payload table status %d\n", status);
    2631             :                 ret = -EINVAL;
    2632           0 :                 goto fail;
    2633             :         }
    2634           0 :         ret = 0;
    2635             : fail:
    2636           0 :         return ret;
    2637           0 : }
    2638             : 
    2639             : 
    2640             : /**
    2641             :  * drm_dp_check_act_status() - Check ACT handled status.
    2642             :  * @mgr: manager to use
    2643             :  *
    2644             :  * Check the payload status bits in the DPCD for ACT handled completion.
    2645             :  */
    2646           0 : int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr)
    2647             : {
    2648           0 :         u8 status;
    2649             :         int ret;
    2650             :         int count = 0;
    2651             : 
    2652           0 :         do {
    2653           0 :                 ret = drm_dp_dpcd_readb(mgr->aux, DP_PAYLOAD_TABLE_UPDATE_STATUS, &status);
    2654             : 
    2655           0 :                 if (ret < 0) {
    2656             :                         DRM_DEBUG_KMS("failed to read payload table status %d\n", ret);
    2657             :                         goto fail;
    2658             :                 }
    2659             : 
    2660           0 :                 if (status & DP_PAYLOAD_ACT_HANDLED)
    2661             :                         break;
    2662           0 :                 count++;
    2663           0 :                 udelay(100);
    2664             : 
    2665           0 :         } while (count < 30);
    2666             : 
    2667           0 :         if (!(status & DP_PAYLOAD_ACT_HANDLED)) {
    2668             :                 DRM_DEBUG_KMS("failed to get ACT bit %d after %d retries\n", status, count);
    2669             :                 ret = -EINVAL;
    2670           0 :                 goto fail;
    2671             :         }
    2672           0 :         return 0;
    2673             : fail:
    2674           0 :         return ret;
    2675           0 : }
    2676             : EXPORT_SYMBOL(drm_dp_check_act_status);
    2677             : 
    2678             : /**
    2679             :  * drm_dp_calc_pbn_mode() - Calculate the PBN for a mode.
    2680             :  * @clock: dot clock for the mode
    2681             :  * @bpp: bpp for the mode.
    2682             :  *
    2683             :  * This uses the formula in the spec to calculate the PBN value for a mode.
    2684             :  */
    2685           0 : int drm_dp_calc_pbn_mode(int clock, int bpp)
    2686             : {
    2687             :         u64 kbps;
    2688             :         s64 peak_kbps;
    2689             :         u32 numerator;
    2690             :         u32 denominator;
    2691             : 
    2692           0 :         kbps = clock * bpp;
    2693             : 
    2694             :         /*
    2695             :          * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006
    2696             :          * The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on
    2697             :          * common multiplier to render an integer PBN for all link rate/lane
    2698             :          * counts combinations
    2699             :          * calculate
    2700             :          * peak_kbps *= (1006/1000)
    2701             :          * peak_kbps *= (64/54)
    2702             :          * peak_kbps *= 8    convert to bytes
    2703             :          */
    2704             : 
    2705             :         numerator = 64 * 1006;
    2706             :         denominator = 54 * 8 * 1000 * 1000;
    2707             : 
    2708           0 :         kbps *= numerator;
    2709           0 :         peak_kbps = drm_fixp_from_fraction(kbps, denominator);
    2710             : 
    2711           0 :         return drm_fixp2int_ceil(peak_kbps);
    2712             : }
    2713             : EXPORT_SYMBOL(drm_dp_calc_pbn_mode);
    2714             : 
    2715           0 : static int test_calc_pbn_mode(void)
    2716             : {
    2717             :         int ret;
    2718           0 :         ret = drm_dp_calc_pbn_mode(154000, 30);
    2719           0 :         if (ret != 689) {
    2720           0 :                 DRM_ERROR("PBN calculation test failed - clock %d, bpp %d, expected PBN %d, actual PBN %d.\n",
    2721             :                                 154000, 30, 689, ret);
    2722           0 :                 return -EINVAL;
    2723             :         }
    2724           0 :         ret = drm_dp_calc_pbn_mode(234000, 30);
    2725           0 :         if (ret != 1047) {
    2726           0 :                 DRM_ERROR("PBN calculation test failed - clock %d, bpp %d, expected PBN %d, actual PBN %d.\n",
    2727             :                                 234000, 30, 1047, ret);
    2728           0 :                 return -EINVAL;
    2729             :         }
    2730           0 :         ret = drm_dp_calc_pbn_mode(297000, 24);
    2731           0 :         if (ret != 1063) {
    2732           0 :                 DRM_ERROR("PBN calculation test failed - clock %d, bpp %d, expected PBN %d, actual PBN %d.\n",
    2733             :                                 297000, 24, 1063, ret);
    2734           0 :                 return -EINVAL;
    2735             :         }
    2736           0 :         return 0;
    2737           0 : }
    2738             : 
    2739             : /* we want to kick the TX after we've ack the up/down IRQs. */
    2740           0 : static void drm_dp_mst_kick_tx(struct drm_dp_mst_topology_mgr *mgr)
    2741             : {
    2742           0 :         queue_work(system_long_wq, &mgr->tx_work);
    2743           0 : }
    2744             : 
    2745             : #ifdef __linux__
    2746             : static void drm_dp_mst_dump_mstb(struct seq_file *m,
    2747             :                                  struct drm_dp_mst_branch *mstb)
    2748             : {
    2749             :         struct drm_dp_mst_port *port;
    2750             :         int tabs = mstb->lct;
    2751             :         char prefix[10];
    2752             :         int i;
    2753             : 
    2754             :         for (i = 0; i < tabs; i++)
    2755             :                 prefix[i] = '\t';
    2756             :         prefix[i] = '\0';
    2757             : 
    2758             :         seq_printf(m, "%smst: %p, %d\n", prefix, mstb, mstb->num_ports);
    2759             :         list_for_each_entry(port, &mstb->ports, next) {
    2760             :                 seq_printf(m, "%sport: %d: ddps: %d ldps: %d, %p, conn: %p\n", prefix, port->port_num, port->ddps, port->ldps, port, port->connector);
    2761             :                 if (port->mstb)
    2762             :                         drm_dp_mst_dump_mstb(m, port->mstb);
    2763             :         }
    2764             : }
    2765             : 
    2766             : static bool dump_dp_payload_table(struct drm_dp_mst_topology_mgr *mgr,
    2767             :                                   char *buf)
    2768             : {
    2769             :         int ret;
    2770             :         int i;
    2771             :         for (i = 0; i < 4; i++) {
    2772             :                 ret = drm_dp_dpcd_read(mgr->aux, DP_PAYLOAD_TABLE_UPDATE_STATUS + (i * 16), &buf[i * 16], 16);
    2773             :                 if (ret != 16)
    2774             :                         break;
    2775             :         }
    2776             :         if (i == 4)
    2777             :                 return true;
    2778             :         return false;
    2779             : }
    2780             : 
    2781             : /**
    2782             :  * drm_dp_mst_dump_topology(): dump topology to seq file.
    2783             :  * @m: seq_file to dump output to
    2784             :  * @mgr: manager to dump current topology for.
    2785             :  *
    2786             :  * helper to dump MST topology to a seq file for debugfs.
    2787             :  */
    2788             : void drm_dp_mst_dump_topology(struct seq_file *m,
    2789             :                               struct drm_dp_mst_topology_mgr *mgr)
    2790             : {
    2791             :         int i;
    2792             :         struct drm_dp_mst_port *port;
    2793             :         mutex_lock(&mgr->lock);
    2794             :         if (mgr->mst_primary)
    2795             :                 drm_dp_mst_dump_mstb(m, mgr->mst_primary);
    2796             : 
    2797             :         /* dump VCPIs */
    2798             :         mutex_unlock(&mgr->lock);
    2799             : 
    2800             :         mutex_lock(&mgr->payload_lock);
    2801             :         seq_printf(m, "vcpi: %lx %lx\n", mgr->payload_mask, mgr->vcpi_mask);
    2802             : 
    2803             :         for (i = 0; i < mgr->max_payloads; i++) {
    2804             :                 if (mgr->proposed_vcpis[i]) {
    2805             :                         port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi);
    2806             :                         seq_printf(m, "vcpi %d: %d %d %d\n", i, port->port_num, port->vcpi.vcpi, port->vcpi.num_slots);
    2807             :                 } else
    2808             :                         seq_printf(m, "vcpi %d:unsed\n", i);
    2809             :         }
    2810             :         for (i = 0; i < mgr->max_payloads; i++) {
    2811             :                 seq_printf(m, "payload %d: %d, %d, %d\n",
    2812             :                            i,
    2813             :                            mgr->payloads[i].payload_state,
    2814             :                            mgr->payloads[i].start_slot,
    2815             :                            mgr->payloads[i].num_slots);
    2816             : 
    2817             : 
    2818             :         }
    2819             :         mutex_unlock(&mgr->payload_lock);
    2820             : 
    2821             :         mutex_lock(&mgr->lock);
    2822             :         if (mgr->mst_primary) {
    2823             :                 u8 buf[64];
    2824             :                 bool bret;
    2825             :                 int ret;
    2826             :                 ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, buf, DP_RECEIVER_CAP_SIZE);
    2827             :                 seq_printf(m, "dpcd: ");
    2828             :                 for (i = 0; i < DP_RECEIVER_CAP_SIZE; i++)
    2829             :                         seq_printf(m, "%02x ", buf[i]);
    2830             :                 seq_printf(m, "\n");
    2831             :                 ret = drm_dp_dpcd_read(mgr->aux, DP_FAUX_CAP, buf, 2);
    2832             :                 seq_printf(m, "faux/mst: ");
    2833             :                 for (i = 0; i < 2; i++)
    2834             :                         seq_printf(m, "%02x ", buf[i]);
    2835             :                 seq_printf(m, "\n");
    2836             :                 ret = drm_dp_dpcd_read(mgr->aux, DP_MSTM_CTRL, buf, 1);
    2837             :                 seq_printf(m, "mst ctrl: ");
    2838             :                 for (i = 0; i < 1; i++)
    2839             :                         seq_printf(m, "%02x ", buf[i]);
    2840             :                 seq_printf(m, "\n");
    2841             : 
    2842             :                 /* dump the standard OUI branch header */
    2843             :                 ret = drm_dp_dpcd_read(mgr->aux, DP_BRANCH_OUI, buf, DP_BRANCH_OUI_HEADER_SIZE);
    2844             :                 seq_printf(m, "branch oui: ");
    2845             :                 for (i = 0; i < 0x3; i++)
    2846             :                         seq_printf(m, "%02x", buf[i]);
    2847             :                 seq_printf(m, " devid: ");
    2848             :                 for (i = 0x3; i < 0x8; i++)
    2849             :                         seq_printf(m, "%c", buf[i]);
    2850             :                 seq_printf(m, " revision: hw: %x.%x sw: %x.%x", buf[0x9] >> 4, buf[0x9] & 0xf, buf[0xa], buf[0xb]);
    2851             :                 seq_printf(m, "\n");
    2852             :                 bret = dump_dp_payload_table(mgr, buf);
    2853             :                 if (bret == true) {
    2854             :                         seq_printf(m, "payload table: ");
    2855             :                         for (i = 0; i < 63; i++)
    2856             :                                 seq_printf(m, "%02x ", buf[i]);
    2857             :                         seq_printf(m, "\n");
    2858             :                 }
    2859             : 
    2860             :         }
    2861             : 
    2862             :         mutex_unlock(&mgr->lock);
    2863             : 
    2864             : }
    2865             : EXPORT_SYMBOL(drm_dp_mst_dump_topology);
    2866             : #endif
    2867             : 
    2868           0 : static void drm_dp_tx_work(struct work_struct *work)
    2869             : {
    2870           0 :         struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, tx_work);
    2871             : 
    2872           0 :         mutex_lock(&mgr->qlock);
    2873           0 :         if (mgr->tx_down_in_progress)
    2874           0 :                 process_single_down_tx_qlock(mgr);
    2875           0 :         mutex_unlock(&mgr->qlock);
    2876           0 : }
    2877             : 
    2878           0 : static void drm_dp_free_mst_port(struct kref *kref)
    2879             : {
    2880           0 :         struct drm_dp_mst_port *port = container_of(kref, struct drm_dp_mst_port, kref);
    2881           0 :         kref_put(&port->parent->kref, drm_dp_free_mst_branch_device);
    2882           0 :         kfree(port);
    2883           0 : }
    2884             : 
    2885           0 : static void drm_dp_destroy_connector_work(struct work_struct *work)
    2886             : {
    2887           0 :         struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, destroy_connector_work);
    2888             :         struct drm_dp_mst_port *port;
    2889             :         bool send_hotplug = false;
    2890             :         /*
    2891             :          * Not a regular list traverse as we have to drop the destroy
    2892             :          * connector lock before destroying the connector, to avoid AB->BA
    2893             :          * ordering between this lock and the config mutex.
    2894             :          */
    2895           0 :         for (;;) {
    2896           0 :                 mutex_lock(&mgr->destroy_connector_lock);
    2897           0 :                 port = list_first_entry_or_null(&mgr->destroy_connector_list, struct drm_dp_mst_port, next);
    2898           0 :                 if (!port) {
    2899           0 :                         mutex_unlock(&mgr->destroy_connector_lock);
    2900             :                         break;
    2901             :                 }
    2902           0 :                 list_del(&port->next);
    2903           0 :                 mutex_unlock(&mgr->destroy_connector_lock);
    2904             : 
    2905           0 :                 kref_init(&port->kref);
    2906           0 :                 INIT_LIST_HEAD(&port->next);
    2907             : 
    2908           0 :                 mgr->cbs->destroy_connector(mgr, port->connector);
    2909             : 
    2910           0 :                 drm_dp_port_teardown_pdt(port, port->pdt);
    2911           0 :                 port->pdt = DP_PEER_DEVICE_NONE;
    2912             : 
    2913           0 :                 if (!port->input && port->vcpi.vcpi > 0) {
    2914           0 :                         drm_dp_mst_reset_vcpi_slots(mgr, port);
    2915           0 :                         drm_dp_update_payload_part1(mgr);
    2916           0 :                         drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
    2917           0 :                 }
    2918             : 
    2919           0 :                 kref_put(&port->kref, drm_dp_free_mst_port);
    2920             :                 send_hotplug = true;
    2921             :         }
    2922           0 :         if (send_hotplug)
    2923           0 :                 (*mgr->cbs->hotplug)(mgr);
    2924           0 : }
    2925             : 
    2926             : /**
    2927             :  * drm_dp_mst_topology_mgr_init - initialise a topology manager
    2928             :  * @mgr: manager struct to initialise
    2929             :  * @dev: device providing this structure - for i2c addition.
    2930             :  * @aux: DP helper aux channel to talk to this device
    2931             :  * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
    2932             :  * @max_payloads: maximum number of payloads this GPU can source
    2933             :  * @conn_base_id: the connector object ID the MST device is connected to.
    2934             :  *
    2935             :  * Return 0 for success, or negative error code on failure
    2936             :  */
    2937           0 : int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
    2938             :                                  struct device *dev, struct drm_dp_aux *aux,
    2939             :                                  int max_dpcd_transaction_bytes,
    2940             :                                  int max_payloads, int conn_base_id)
    2941             : {
    2942           0 :         rw_init(&mgr->lock, "mst");
    2943           0 :         rw_init(&mgr->qlock, "mstq");
    2944           0 :         rw_init(&mgr->payload_lock, "mstpl");
    2945           0 :         rw_init(&mgr->destroy_connector_lock, "mstdc");
    2946           0 :         INIT_LIST_HEAD(&mgr->tx_msg_downq);
    2947           0 :         INIT_LIST_HEAD(&mgr->destroy_connector_list);
    2948           0 :         INIT_WORK(&mgr->work, drm_dp_mst_link_probe_work);
    2949           0 :         INIT_WORK(&mgr->tx_work, drm_dp_tx_work);
    2950           0 :         INIT_WORK(&mgr->destroy_connector_work, drm_dp_destroy_connector_work);
    2951           0 :         init_waitqueue_head(&mgr->tx_waitq);
    2952           0 :         mgr->dev = dev;
    2953           0 :         mgr->aux = aux;
    2954           0 :         mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
    2955           0 :         mgr->max_payloads = max_payloads;
    2956           0 :         mgr->conn_base_id = conn_base_id;
    2957           0 :         mgr->payloads = kcalloc(max_payloads, sizeof(struct drm_dp_payload), GFP_KERNEL);
    2958           0 :         if (!mgr->payloads)
    2959           0 :                 return -ENOMEM;
    2960           0 :         mgr->proposed_vcpis = kcalloc(max_payloads, sizeof(struct drm_dp_vcpi *), GFP_KERNEL);
    2961           0 :         if (!mgr->proposed_vcpis)
    2962           0 :                 return -ENOMEM;
    2963           0 :         set_bit(0, &mgr->payload_mask);
    2964           0 :         test_calc_pbn_mode();
    2965           0 :         return 0;
    2966           0 : }
    2967             : EXPORT_SYMBOL(drm_dp_mst_topology_mgr_init);
    2968             : 
    2969             : /**
    2970             :  * drm_dp_mst_topology_mgr_destroy() - destroy topology manager.
    2971             :  * @mgr: manager to destroy
    2972             :  */
    2973           0 : void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr)
    2974             : {
    2975           0 :         flush_work(&mgr->work);
    2976           0 :         flush_work(&mgr->destroy_connector_work);
    2977           0 :         mutex_lock(&mgr->payload_lock);
    2978           0 :         kfree(mgr->payloads);
    2979           0 :         mgr->payloads = NULL;
    2980           0 :         kfree(mgr->proposed_vcpis);
    2981           0 :         mgr->proposed_vcpis = NULL;
    2982           0 :         mutex_unlock(&mgr->payload_lock);
    2983           0 :         mgr->dev = NULL;
    2984           0 :         mgr->aux = NULL;
    2985           0 : }
    2986             : EXPORT_SYMBOL(drm_dp_mst_topology_mgr_destroy);
    2987             : 
    2988             : /* I2C device */
    2989           0 : static int drm_dp_mst_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
    2990             :                                int num)
    2991             : {
    2992           0 :         struct drm_dp_aux *aux = adapter->algo_data;
    2993           0 :         struct drm_dp_mst_port *port = container_of(aux, struct drm_dp_mst_port, aux);
    2994             :         struct drm_dp_mst_branch *mstb;
    2995           0 :         struct drm_dp_mst_topology_mgr *mgr = port->mgr;
    2996             :         unsigned int i;
    2997             :         bool reading = false;
    2998           0 :         struct drm_dp_sideband_msg_req_body msg;
    2999             :         struct drm_dp_sideband_msg_tx *txmsg = NULL;
    3000             :         int ret;
    3001             : 
    3002           0 :         mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent);
    3003           0 :         if (!mstb)
    3004           0 :                 return -EREMOTEIO;
    3005             : 
    3006             :         /* construct i2c msg */
    3007             :         /* see if last msg is a read */
    3008           0 :         if (msgs[num - 1].flags & I2C_M_RD)
    3009           0 :                 reading = true;
    3010             : 
    3011           0 :         if (!reading || (num - 1 > DP_REMOTE_I2C_READ_MAX_TRANSACTIONS)) {
    3012             :                 DRM_DEBUG_KMS("Unsupported I2C transaction for MST device\n");
    3013             :                 ret = -EIO;
    3014           0 :                 goto out;
    3015             :         }
    3016             : 
    3017           0 :         memset(&msg, 0, sizeof(msg));
    3018           0 :         msg.req_type = DP_REMOTE_I2C_READ;
    3019           0 :         msg.u.i2c_read.num_transactions = num - 1;
    3020           0 :         msg.u.i2c_read.port_number = port->port_num;
    3021           0 :         for (i = 0; i < num - 1; i++) {
    3022           0 :                 msg.u.i2c_read.transactions[i].i2c_dev_id = msgs[i].addr;
    3023           0 :                 msg.u.i2c_read.transactions[i].num_bytes = msgs[i].len;
    3024           0 :                 msg.u.i2c_read.transactions[i].bytes = msgs[i].buf;
    3025             :         }
    3026           0 :         msg.u.i2c_read.read_i2c_device_id = msgs[num - 1].addr;
    3027           0 :         msg.u.i2c_read.num_bytes_read = msgs[num - 1].len;
    3028             : 
    3029           0 :         txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
    3030           0 :         if (!txmsg) {
    3031             :                 ret = -ENOMEM;
    3032           0 :                 goto out;
    3033             :         }
    3034             : 
    3035           0 :         txmsg->dst = mstb;
    3036           0 :         drm_dp_encode_sideband_req(&msg, txmsg);
    3037             : 
    3038           0 :         drm_dp_queue_down_tx(mgr, txmsg);
    3039             : 
    3040           0 :         ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
    3041           0 :         if (ret > 0) {
    3042             : 
    3043           0 :                 if (txmsg->reply.reply_type == 1) { /* got a NAK back */
    3044             :                         ret = -EREMOTEIO;
    3045           0 :                         goto out;
    3046             :                 }
    3047           0 :                 if (txmsg->reply.u.remote_i2c_read_ack.num_bytes != msgs[num - 1].len) {
    3048             :                         ret = -EIO;
    3049           0 :                         goto out;
    3050             :                 }
    3051           0 :                 memcpy(msgs[num - 1].buf, txmsg->reply.u.remote_i2c_read_ack.bytes, msgs[num - 1].len);
    3052             :                 ret = num;
    3053           0 :         }
    3054             : out:
    3055           0 :         kfree(txmsg);
    3056           0 :         drm_dp_put_mst_branch_device(mstb);
    3057           0 :         return ret;
    3058           0 : }
    3059             : 
    3060           0 : static u32 drm_dp_mst_i2c_functionality(struct i2c_adapter *adapter)
    3061             : {
    3062           0 :         return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
    3063             :                I2C_FUNC_SMBUS_READ_BLOCK_DATA |
    3064             :                I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
    3065             :                I2C_FUNC_10BIT_ADDR;
    3066             : }
    3067             : 
    3068             : static const struct i2c_algorithm drm_dp_mst_i2c_algo = {
    3069             :         .functionality = drm_dp_mst_i2c_functionality,
    3070             :         .master_xfer = drm_dp_mst_i2c_xfer,
    3071             : };
    3072             : 
    3073             : /**
    3074             :  * drm_dp_mst_register_i2c_bus() - register an I2C adapter for I2C-over-AUX
    3075             :  * @aux: DisplayPort AUX channel
    3076             :  *
    3077             :  * Returns 0 on success or a negative error code on failure.
    3078             :  */
    3079           0 : static int drm_dp_mst_register_i2c_bus(struct drm_dp_aux *aux)
    3080             : {
    3081           0 :         aux->ddc.algo = &drm_dp_mst_i2c_algo;
    3082           0 :         aux->ddc.algo_data = aux;
    3083           0 :         aux->ddc.retries = 3;
    3084             : 
    3085             : #ifdef __linux__
    3086             :         aux->ddc.class = I2C_CLASS_DDC;
    3087             :         aux->ddc.owner = THIS_MODULE;
    3088             :         aux->ddc.dev.parent = aux->dev;
    3089             :         aux->ddc.dev.of_node = aux->dev->of_node;
    3090             : #endif
    3091             : 
    3092           0 :         strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(aux->dev),
    3093             :                 sizeof(aux->ddc.name));
    3094             : 
    3095           0 :         return i2c_add_adapter(&aux->ddc);
    3096             : }
    3097             : 
    3098             : /**
    3099             :  * drm_dp_mst_unregister_i2c_bus() - unregister an I2C-over-AUX adapter
    3100             :  * @aux: DisplayPort AUX channel
    3101             :  */
    3102           0 : static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_aux *aux)
    3103             : {
    3104             :         i2c_del_adapter(&aux->ddc);
    3105           0 : }

Generated by: LCOV version 1.13