6194 lines · c
1/*2 * Copyright © 2014 Red Hat3 *4 * Permission to use, copy, modify, distribute, and sell this software and its5 * documentation for any purpose is hereby granted without fee, provided that6 * the above copyright notice appear in all copies and that both that copyright7 * notice and this permission notice appear in supporting documentation, and8 * that the name of the copyright holders not be used in advertising or9 * publicity pertaining to distribution of the software without specific,10 * written prior permission. The copyright holders make no representations11 * about the suitability of this software for any purpose. It is provided "as12 * 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 NO16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE20 * OF THIS SOFTWARE.21 */22 23#include <linux/bitfield.h>24#include <linux/delay.h>25#include <linux/errno.h>26#include <linux/i2c.h>27#include <linux/init.h>28#include <linux/kernel.h>29#include <linux/random.h>30#include <linux/sched.h>31#include <linux/seq_file.h>32#include <linux/iopoll.h>33 34#if IS_ENABLED(CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS)35#include <linux/stacktrace.h>36#include <linux/sort.h>37#include <linux/timekeeping.h>38#include <linux/math64.h>39#endif40 41#include <drm/display/drm_dp_mst_helper.h>42#include <drm/drm_atomic.h>43#include <drm/drm_atomic_helper.h>44#include <drm/drm_drv.h>45#include <drm/drm_edid.h>46#include <drm/drm_fixed.h>47#include <drm/drm_print.h>48#include <drm/drm_probe_helper.h>49 50#include "drm_dp_helper_internal.h"51#include "drm_dp_mst_topology_internal.h"52 53/**54 * DOC: dp mst helper55 *56 * These functions contain parts of the DisplayPort 1.2a MultiStream Transport57 * protocol. The helpers contain a topology manager and bandwidth manager.58 * The helpers encapsulate the sending and received of sideband msgs.59 */60struct drm_dp_pending_up_req {61 struct drm_dp_sideband_msg_hdr hdr;62 struct drm_dp_sideband_msg_req_body msg;63 struct list_head next;64};65 66static bool dump_dp_payload_table(struct drm_dp_mst_topology_mgr *mgr,67 char *buf);68 69static void drm_dp_mst_topology_put_port(struct drm_dp_mst_port *port);70 71static int drm_dp_dpcd_write_payload(struct drm_dp_mst_topology_mgr *mgr,72 int id, u8 start_slot, u8 num_slots);73 74static int drm_dp_send_dpcd_read(struct drm_dp_mst_topology_mgr *mgr,75 struct drm_dp_mst_port *port,76 int offset, int size, u8 *bytes);77static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr,78 struct drm_dp_mst_port *port,79 int offset, int size, u8 *bytes);80 81static int drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr,82 struct drm_dp_mst_branch *mstb);83 84static void85drm_dp_send_clear_payload_id_table(struct drm_dp_mst_topology_mgr *mgr,86 struct drm_dp_mst_branch *mstb);87 88static int drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr,89 struct drm_dp_mst_branch *mstb,90 struct drm_dp_mst_port *port);91static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr,92 guid_t *guid);93 94static int drm_dp_mst_register_i2c_bus(struct drm_dp_mst_port *port);95static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_mst_port *port);96static void drm_dp_mst_kick_tx(struct drm_dp_mst_topology_mgr *mgr);97 98static bool drm_dp_mst_port_downstream_of_branch(struct drm_dp_mst_port *port,99 struct drm_dp_mst_branch *branch);100 101#define DBG_PREFIX "[dp_mst]"102 103#define DP_STR(x) [DP_ ## x] = #x104 105static const char *drm_dp_mst_req_type_str(u8 req_type)106{107 static const char * const req_type_str[] = {108 DP_STR(GET_MSG_TRANSACTION_VERSION),109 DP_STR(LINK_ADDRESS),110 DP_STR(CONNECTION_STATUS_NOTIFY),111 DP_STR(ENUM_PATH_RESOURCES),112 DP_STR(ALLOCATE_PAYLOAD),113 DP_STR(QUERY_PAYLOAD),114 DP_STR(RESOURCE_STATUS_NOTIFY),115 DP_STR(CLEAR_PAYLOAD_ID_TABLE),116 DP_STR(REMOTE_DPCD_READ),117 DP_STR(REMOTE_DPCD_WRITE),118 DP_STR(REMOTE_I2C_READ),119 DP_STR(REMOTE_I2C_WRITE),120 DP_STR(POWER_UP_PHY),121 DP_STR(POWER_DOWN_PHY),122 DP_STR(SINK_EVENT_NOTIFY),123 DP_STR(QUERY_STREAM_ENC_STATUS),124 };125 126 if (req_type >= ARRAY_SIZE(req_type_str) ||127 !req_type_str[req_type])128 return "unknown";129 130 return req_type_str[req_type];131}132 133#undef DP_STR134#define DP_STR(x) [DP_NAK_ ## x] = #x135 136static const char *drm_dp_mst_nak_reason_str(u8 nak_reason)137{138 static const char * const nak_reason_str[] = {139 DP_STR(WRITE_FAILURE),140 DP_STR(INVALID_READ),141 DP_STR(CRC_FAILURE),142 DP_STR(BAD_PARAM),143 DP_STR(DEFER),144 DP_STR(LINK_FAILURE),145 DP_STR(NO_RESOURCES),146 DP_STR(DPCD_FAIL),147 DP_STR(I2C_NAK),148 DP_STR(ALLOCATE_FAIL),149 };150 151 if (nak_reason >= ARRAY_SIZE(nak_reason_str) ||152 !nak_reason_str[nak_reason])153 return "unknown";154 155 return nak_reason_str[nak_reason];156}157 158#undef DP_STR159#define DP_STR(x) [DRM_DP_SIDEBAND_TX_ ## x] = #x160 161static const char *drm_dp_mst_sideband_tx_state_str(int state)162{163 static const char * const sideband_reason_str[] = {164 DP_STR(QUEUED),165 DP_STR(START_SEND),166 DP_STR(SENT),167 DP_STR(RX),168 DP_STR(TIMEOUT),169 };170 171 if (state >= ARRAY_SIZE(sideband_reason_str) ||172 !sideband_reason_str[state])173 return "unknown";174 175 return sideband_reason_str[state];176}177 178static int179drm_dp_mst_rad_to_str(const u8 rad[8], u8 lct, char *out, size_t len)180{181 int i;182 u8 unpacked_rad[16];183 184 for (i = 0; i < lct; i++) {185 if (i % 2)186 unpacked_rad[i] = rad[i / 2] >> 4;187 else188 unpacked_rad[i] = rad[i / 2] & BIT_MASK(4);189 }190 191 /* TODO: Eventually add something to printk so we can format the rad192 * like this: 1.2.3193 */194 return snprintf(out, len, "%*phC", lct, unpacked_rad);195}196 197/* sideband msg handling */198static u8 drm_dp_msg_header_crc4(const uint8_t *data, size_t num_nibbles)199{200 u8 bitmask = 0x80;201 u8 bitshift = 7;202 u8 array_index = 0;203 int number_of_bits = num_nibbles * 4;204 u8 remainder = 0;205 206 while (number_of_bits != 0) {207 number_of_bits--;208 remainder <<= 1;209 remainder |= (data[array_index] & bitmask) >> bitshift;210 bitmask >>= 1;211 bitshift--;212 if (bitmask == 0) {213 bitmask = 0x80;214 bitshift = 7;215 array_index++;216 }217 if ((remainder & 0x10) == 0x10)218 remainder ^= 0x13;219 }220 221 number_of_bits = 4;222 while (number_of_bits != 0) {223 number_of_bits--;224 remainder <<= 1;225 if ((remainder & 0x10) != 0)226 remainder ^= 0x13;227 }228 229 return remainder;230}231 232static u8 drm_dp_msg_data_crc4(const uint8_t *data, u8 number_of_bytes)233{234 u8 bitmask = 0x80;235 u8 bitshift = 7;236 u8 array_index = 0;237 int number_of_bits = number_of_bytes * 8;238 u16 remainder = 0;239 240 while (number_of_bits != 0) {241 number_of_bits--;242 remainder <<= 1;243 remainder |= (data[array_index] & bitmask) >> bitshift;244 bitmask >>= 1;245 bitshift--;246 if (bitmask == 0) {247 bitmask = 0x80;248 bitshift = 7;249 array_index++;250 }251 if ((remainder & 0x100) == 0x100)252 remainder ^= 0xd5;253 }254 255 number_of_bits = 8;256 while (number_of_bits != 0) {257 number_of_bits--;258 remainder <<= 1;259 if ((remainder & 0x100) != 0)260 remainder ^= 0xd5;261 }262 263 return remainder & 0xff;264}265static inline u8 drm_dp_calc_sb_hdr_size(struct drm_dp_sideband_msg_hdr *hdr)266{267 u8 size = 3;268 269 size += (hdr->lct / 2);270 return size;271}272 273static void drm_dp_encode_sideband_msg_hdr(struct drm_dp_sideband_msg_hdr *hdr,274 u8 *buf, int *len)275{276 int idx = 0;277 int i;278 u8 crc4;279 280 buf[idx++] = ((hdr->lct & 0xf) << 4) | (hdr->lcr & 0xf);281 for (i = 0; i < (hdr->lct / 2); i++)282 buf[idx++] = hdr->rad[i];283 buf[idx++] = (hdr->broadcast << 7) | (hdr->path_msg << 6) |284 (hdr->msg_len & 0x3f);285 buf[idx++] = (hdr->somt << 7) | (hdr->eomt << 6) | (hdr->seqno << 4);286 287 crc4 = drm_dp_msg_header_crc4(buf, (idx * 2) - 1);288 buf[idx - 1] |= (crc4 & 0xf);289 290 *len = idx;291}292 293static bool drm_dp_decode_sideband_msg_hdr(const struct drm_dp_mst_topology_mgr *mgr,294 struct drm_dp_sideband_msg_hdr *hdr,295 u8 *buf, int buflen, u8 *hdrlen)296{297 u8 crc4;298 u8 len;299 int i;300 u8 idx;301 302 if (buf[0] == 0)303 return false;304 len = 3;305 len += ((buf[0] & 0xf0) >> 4) / 2;306 if (len > buflen)307 return false;308 crc4 = drm_dp_msg_header_crc4(buf, (len * 2) - 1);309 310 if ((crc4 & 0xf) != (buf[len - 1] & 0xf)) {311 drm_dbg_kms(mgr->dev, "crc4 mismatch 0x%x 0x%x\n", crc4, buf[len - 1]);312 return false;313 }314 315 hdr->lct = (buf[0] & 0xf0) >> 4;316 hdr->lcr = (buf[0] & 0xf);317 idx = 1;318 for (i = 0; i < (hdr->lct / 2); i++)319 hdr->rad[i] = buf[idx++];320 hdr->broadcast = (buf[idx] >> 7) & 0x1;321 hdr->path_msg = (buf[idx] >> 6) & 0x1;322 hdr->msg_len = buf[idx] & 0x3f;323 idx++;324 hdr->somt = (buf[idx] >> 7) & 0x1;325 hdr->eomt = (buf[idx] >> 6) & 0x1;326 hdr->seqno = (buf[idx] >> 4) & 0x1;327 idx++;328 *hdrlen = idx;329 return true;330}331 332void333drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,334 struct drm_dp_sideband_msg_tx *raw)335{336 int idx = 0;337 int i;338 u8 *buf = raw->msg;339 340 buf[idx++] = req->req_type & 0x7f;341 342 switch (req->req_type) {343 case DP_ENUM_PATH_RESOURCES:344 case DP_POWER_DOWN_PHY:345 case DP_POWER_UP_PHY:346 buf[idx] = (req->u.port_num.port_number & 0xf) << 4;347 idx++;348 break;349 case DP_ALLOCATE_PAYLOAD:350 buf[idx] = (req->u.allocate_payload.port_number & 0xf) << 4 |351 (req->u.allocate_payload.number_sdp_streams & 0xf);352 idx++;353 buf[idx] = (req->u.allocate_payload.vcpi & 0x7f);354 idx++;355 buf[idx] = (req->u.allocate_payload.pbn >> 8);356 idx++;357 buf[idx] = (req->u.allocate_payload.pbn & 0xff);358 idx++;359 for (i = 0; i < req->u.allocate_payload.number_sdp_streams / 2; i++) {360 buf[idx] = ((req->u.allocate_payload.sdp_stream_sink[i * 2] & 0xf) << 4) |361 (req->u.allocate_payload.sdp_stream_sink[i * 2 + 1] & 0xf);362 idx++;363 }364 if (req->u.allocate_payload.number_sdp_streams & 1) {365 i = req->u.allocate_payload.number_sdp_streams - 1;366 buf[idx] = (req->u.allocate_payload.sdp_stream_sink[i] & 0xf) << 4;367 idx++;368 }369 break;370 case DP_QUERY_PAYLOAD:371 buf[idx] = (req->u.query_payload.port_number & 0xf) << 4;372 idx++;373 buf[idx] = (req->u.query_payload.vcpi & 0x7f);374 idx++;375 break;376 case DP_REMOTE_DPCD_READ:377 buf[idx] = (req->u.dpcd_read.port_number & 0xf) << 4;378 buf[idx] |= ((req->u.dpcd_read.dpcd_address & 0xf0000) >> 16) & 0xf;379 idx++;380 buf[idx] = (req->u.dpcd_read.dpcd_address & 0xff00) >> 8;381 idx++;382 buf[idx] = (req->u.dpcd_read.dpcd_address & 0xff);383 idx++;384 buf[idx] = (req->u.dpcd_read.num_bytes);385 idx++;386 break;387 388 case DP_REMOTE_DPCD_WRITE:389 buf[idx] = (req->u.dpcd_write.port_number & 0xf) << 4;390 buf[idx] |= ((req->u.dpcd_write.dpcd_address & 0xf0000) >> 16) & 0xf;391 idx++;392 buf[idx] = (req->u.dpcd_write.dpcd_address & 0xff00) >> 8;393 idx++;394 buf[idx] = (req->u.dpcd_write.dpcd_address & 0xff);395 idx++;396 buf[idx] = (req->u.dpcd_write.num_bytes);397 idx++;398 memcpy(&buf[idx], req->u.dpcd_write.bytes, req->u.dpcd_write.num_bytes);399 idx += req->u.dpcd_write.num_bytes;400 break;401 case DP_REMOTE_I2C_READ:402 buf[idx] = (req->u.i2c_read.port_number & 0xf) << 4;403 buf[idx] |= (req->u.i2c_read.num_transactions & 0x3);404 idx++;405 for (i = 0; i < (req->u.i2c_read.num_transactions & 0x3); i++) {406 buf[idx] = req->u.i2c_read.transactions[i].i2c_dev_id & 0x7f;407 idx++;408 buf[idx] = req->u.i2c_read.transactions[i].num_bytes;409 idx++;410 memcpy(&buf[idx], req->u.i2c_read.transactions[i].bytes, req->u.i2c_read.transactions[i].num_bytes);411 idx += req->u.i2c_read.transactions[i].num_bytes;412 413 buf[idx] = (req->u.i2c_read.transactions[i].no_stop_bit & 0x1) << 4;414 buf[idx] |= (req->u.i2c_read.transactions[i].i2c_transaction_delay & 0xf);415 idx++;416 }417 buf[idx] = (req->u.i2c_read.read_i2c_device_id) & 0x7f;418 idx++;419 buf[idx] = (req->u.i2c_read.num_bytes_read);420 idx++;421 break;422 423 case DP_REMOTE_I2C_WRITE:424 buf[idx] = (req->u.i2c_write.port_number & 0xf) << 4;425 idx++;426 buf[idx] = (req->u.i2c_write.write_i2c_device_id) & 0x7f;427 idx++;428 buf[idx] = (req->u.i2c_write.num_bytes);429 idx++;430 memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);431 idx += req->u.i2c_write.num_bytes;432 break;433 case DP_QUERY_STREAM_ENC_STATUS: {434 const struct drm_dp_query_stream_enc_status *msg;435 436 msg = &req->u.enc_status;437 buf[idx] = msg->stream_id;438 idx++;439 memcpy(&buf[idx], msg->client_id, sizeof(msg->client_id));440 idx += sizeof(msg->client_id);441 buf[idx] = 0;442 buf[idx] |= FIELD_PREP(GENMASK(1, 0), msg->stream_event);443 buf[idx] |= msg->valid_stream_event ? BIT(2) : 0;444 buf[idx] |= FIELD_PREP(GENMASK(4, 3), msg->stream_behavior);445 buf[idx] |= msg->valid_stream_behavior ? BIT(5) : 0;446 idx++;447 }448 break;449 }450 raw->cur_len = idx;451}452EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_dp_encode_sideband_req);453 454/* Decode a sideband request we've encoded, mainly used for debugging */455int456drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw,457 struct drm_dp_sideband_msg_req_body *req)458{459 const u8 *buf = raw->msg;460 int i, idx = 0;461 462 req->req_type = buf[idx++] & 0x7f;463 switch (req->req_type) {464 case DP_ENUM_PATH_RESOURCES:465 case DP_POWER_DOWN_PHY:466 case DP_POWER_UP_PHY:467 req->u.port_num.port_number = (buf[idx] >> 4) & 0xf;468 break;469 case DP_ALLOCATE_PAYLOAD:470 {471 struct drm_dp_allocate_payload *a =472 &req->u.allocate_payload;473 474 a->number_sdp_streams = buf[idx] & 0xf;475 a->port_number = (buf[idx] >> 4) & 0xf;476 477 WARN_ON(buf[++idx] & 0x80);478 a->vcpi = buf[idx] & 0x7f;479 480 a->pbn = buf[++idx] << 8;481 a->pbn |= buf[++idx];482 483 idx++;484 for (i = 0; i < a->number_sdp_streams; i++) {485 a->sdp_stream_sink[i] =486 (buf[idx + (i / 2)] >> ((i % 2) ? 0 : 4)) & 0xf;487 }488 }489 break;490 case DP_QUERY_PAYLOAD:491 req->u.query_payload.port_number = (buf[idx] >> 4) & 0xf;492 WARN_ON(buf[++idx] & 0x80);493 req->u.query_payload.vcpi = buf[idx] & 0x7f;494 break;495 case DP_REMOTE_DPCD_READ:496 {497 struct drm_dp_remote_dpcd_read *r = &req->u.dpcd_read;498 499 r->port_number = (buf[idx] >> 4) & 0xf;500 501 r->dpcd_address = (buf[idx] << 16) & 0xf0000;502 r->dpcd_address |= (buf[++idx] << 8) & 0xff00;503 r->dpcd_address |= buf[++idx] & 0xff;504 505 r->num_bytes = buf[++idx];506 }507 break;508 case DP_REMOTE_DPCD_WRITE:509 {510 struct drm_dp_remote_dpcd_write *w =511 &req->u.dpcd_write;512 513 w->port_number = (buf[idx] >> 4) & 0xf;514 515 w->dpcd_address = (buf[idx] << 16) & 0xf0000;516 w->dpcd_address |= (buf[++idx] << 8) & 0xff00;517 w->dpcd_address |= buf[++idx] & 0xff;518 519 w->num_bytes = buf[++idx];520 521 w->bytes = kmemdup(&buf[++idx], w->num_bytes,522 GFP_KERNEL);523 if (!w->bytes)524 return -ENOMEM;525 }526 break;527 case DP_REMOTE_I2C_READ:528 {529 struct drm_dp_remote_i2c_read *r = &req->u.i2c_read;530 struct drm_dp_remote_i2c_read_tx *tx;531 bool failed = false;532 533 r->num_transactions = buf[idx] & 0x3;534 r->port_number = (buf[idx] >> 4) & 0xf;535 for (i = 0; i < r->num_transactions; i++) {536 tx = &r->transactions[i];537 538 tx->i2c_dev_id = buf[++idx] & 0x7f;539 tx->num_bytes = buf[++idx];540 tx->bytes = kmemdup(&buf[++idx],541 tx->num_bytes,542 GFP_KERNEL);543 if (!tx->bytes) {544 failed = true;545 break;546 }547 idx += tx->num_bytes;548 tx->no_stop_bit = (buf[idx] >> 5) & 0x1;549 tx->i2c_transaction_delay = buf[idx] & 0xf;550 }551 552 if (failed) {553 for (i = 0; i < r->num_transactions; i++) {554 tx = &r->transactions[i];555 kfree(tx->bytes);556 }557 return -ENOMEM;558 }559 560 r->read_i2c_device_id = buf[++idx] & 0x7f;561 r->num_bytes_read = buf[++idx];562 }563 break;564 case DP_REMOTE_I2C_WRITE:565 {566 struct drm_dp_remote_i2c_write *w = &req->u.i2c_write;567 568 w->port_number = (buf[idx] >> 4) & 0xf;569 w->write_i2c_device_id = buf[++idx] & 0x7f;570 w->num_bytes = buf[++idx];571 w->bytes = kmemdup(&buf[++idx], w->num_bytes,572 GFP_KERNEL);573 if (!w->bytes)574 return -ENOMEM;575 }576 break;577 case DP_QUERY_STREAM_ENC_STATUS:578 req->u.enc_status.stream_id = buf[idx++];579 for (i = 0; i < sizeof(req->u.enc_status.client_id); i++)580 req->u.enc_status.client_id[i] = buf[idx++];581 582 req->u.enc_status.stream_event = FIELD_GET(GENMASK(1, 0),583 buf[idx]);584 req->u.enc_status.valid_stream_event = FIELD_GET(BIT(2),585 buf[idx]);586 req->u.enc_status.stream_behavior = FIELD_GET(GENMASK(4, 3),587 buf[idx]);588 req->u.enc_status.valid_stream_behavior = FIELD_GET(BIT(5),589 buf[idx]);590 break;591 }592 593 return 0;594}595EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_dp_decode_sideband_req);596 597void598drm_dp_dump_sideband_msg_req_body(const struct drm_dp_sideband_msg_req_body *req,599 int indent, struct drm_printer *printer)600{601 int i;602 603#define P(f, ...) drm_printf_indent(printer, indent, f, ##__VA_ARGS__)604 if (req->req_type == DP_LINK_ADDRESS) {605 /* No contents to print */606 P("type=%s\n", drm_dp_mst_req_type_str(req->req_type));607 return;608 }609 610 P("type=%s contents:\n", drm_dp_mst_req_type_str(req->req_type));611 indent++;612 613 switch (req->req_type) {614 case DP_ENUM_PATH_RESOURCES:615 case DP_POWER_DOWN_PHY:616 case DP_POWER_UP_PHY:617 P("port=%d\n", req->u.port_num.port_number);618 break;619 case DP_ALLOCATE_PAYLOAD:620 P("port=%d vcpi=%d pbn=%d sdp_streams=%d %*ph\n",621 req->u.allocate_payload.port_number,622 req->u.allocate_payload.vcpi, req->u.allocate_payload.pbn,623 req->u.allocate_payload.number_sdp_streams,624 req->u.allocate_payload.number_sdp_streams,625 req->u.allocate_payload.sdp_stream_sink);626 break;627 case DP_QUERY_PAYLOAD:628 P("port=%d vcpi=%d\n",629 req->u.query_payload.port_number,630 req->u.query_payload.vcpi);631 break;632 case DP_REMOTE_DPCD_READ:633 P("port=%d dpcd_addr=%05x len=%d\n",634 req->u.dpcd_read.port_number, req->u.dpcd_read.dpcd_address,635 req->u.dpcd_read.num_bytes);636 break;637 case DP_REMOTE_DPCD_WRITE:638 P("port=%d addr=%05x len=%d: %*ph\n",639 req->u.dpcd_write.port_number,640 req->u.dpcd_write.dpcd_address,641 req->u.dpcd_write.num_bytes, req->u.dpcd_write.num_bytes,642 req->u.dpcd_write.bytes);643 break;644 case DP_REMOTE_I2C_READ:645 P("port=%d num_tx=%d id=%d size=%d:\n",646 req->u.i2c_read.port_number,647 req->u.i2c_read.num_transactions,648 req->u.i2c_read.read_i2c_device_id,649 req->u.i2c_read.num_bytes_read);650 651 indent++;652 for (i = 0; i < req->u.i2c_read.num_transactions; i++) {653 const struct drm_dp_remote_i2c_read_tx *rtx =654 &req->u.i2c_read.transactions[i];655 656 P("%d: id=%03d size=%03d no_stop_bit=%d tx_delay=%03d: %*ph\n",657 i, rtx->i2c_dev_id, rtx->num_bytes,658 rtx->no_stop_bit, rtx->i2c_transaction_delay,659 rtx->num_bytes, rtx->bytes);660 }661 break;662 case DP_REMOTE_I2C_WRITE:663 P("port=%d id=%d size=%d: %*ph\n",664 req->u.i2c_write.port_number,665 req->u.i2c_write.write_i2c_device_id,666 req->u.i2c_write.num_bytes, req->u.i2c_write.num_bytes,667 req->u.i2c_write.bytes);668 break;669 case DP_QUERY_STREAM_ENC_STATUS:670 P("stream_id=%u client_id=%*ph stream_event=%x "671 "valid_event=%d stream_behavior=%x valid_behavior=%d",672 req->u.enc_status.stream_id,673 (int)ARRAY_SIZE(req->u.enc_status.client_id),674 req->u.enc_status.client_id, req->u.enc_status.stream_event,675 req->u.enc_status.valid_stream_event,676 req->u.enc_status.stream_behavior,677 req->u.enc_status.valid_stream_behavior);678 break;679 default:680 P("???\n");681 break;682 }683#undef P684}685EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_dp_dump_sideband_msg_req_body);686 687static inline void688drm_dp_mst_dump_sideband_msg_tx(struct drm_printer *p,689 const struct drm_dp_sideband_msg_tx *txmsg)690{691 struct drm_dp_sideband_msg_req_body req;692 char buf[64];693 int ret;694 int i;695 696 drm_dp_mst_rad_to_str(txmsg->dst->rad, txmsg->dst->lct, buf,697 sizeof(buf));698 drm_printf(p, "txmsg cur_offset=%x cur_len=%x seqno=%x state=%s path_msg=%d dst=%s\n",699 txmsg->cur_offset, txmsg->cur_len, txmsg->seqno,700 drm_dp_mst_sideband_tx_state_str(txmsg->state),701 txmsg->path_msg, buf);702 703 ret = drm_dp_decode_sideband_req(txmsg, &req);704 if (ret) {705 drm_printf(p, "<failed to decode sideband req: %d>\n", ret);706 return;707 }708 drm_dp_dump_sideband_msg_req_body(&req, 1, p);709 710 switch (req.req_type) {711 case DP_REMOTE_DPCD_WRITE:712 kfree(req.u.dpcd_write.bytes);713 break;714 case DP_REMOTE_I2C_READ:715 for (i = 0; i < req.u.i2c_read.num_transactions; i++)716 kfree(req.u.i2c_read.transactions[i].bytes);717 break;718 case DP_REMOTE_I2C_WRITE:719 kfree(req.u.i2c_write.bytes);720 break;721 }722}723 724static void drm_dp_crc_sideband_chunk_req(u8 *msg, u8 len)725{726 u8 crc4;727 728 crc4 = drm_dp_msg_data_crc4(msg, len);729 msg[len] = crc4;730}731 732static void drm_dp_encode_sideband_reply(struct drm_dp_sideband_msg_reply_body *rep,733 struct drm_dp_sideband_msg_tx *raw)734{735 int idx = 0;736 u8 *buf = raw->msg;737 738 buf[idx++] = (rep->reply_type & 0x1) << 7 | (rep->req_type & 0x7f);739 740 raw->cur_len = idx;741}742 743static int drm_dp_sideband_msg_set_header(struct drm_dp_sideband_msg_rx *msg,744 struct drm_dp_sideband_msg_hdr *hdr,745 u8 hdrlen)746{747 /*748 * ignore out-of-order messages or messages that are part of a749 * failed transaction750 */751 if (!hdr->somt && !msg->have_somt)752 return false;753 754 /* get length contained in this portion */755 msg->curchunk_idx = 0;756 msg->curchunk_len = hdr->msg_len;757 msg->curchunk_hdrlen = hdrlen;758 759 /* we have already gotten an somt - don't bother parsing */760 if (hdr->somt && msg->have_somt)761 return false;762 763 if (hdr->somt) {764 memcpy(&msg->initial_hdr, hdr,765 sizeof(struct drm_dp_sideband_msg_hdr));766 msg->have_somt = true;767 }768 if (hdr->eomt)769 msg->have_eomt = true;770 771 return true;772}773 774/* this adds a chunk of msg to the builder to get the final msg */775static bool drm_dp_sideband_append_payload(struct drm_dp_sideband_msg_rx *msg,776 u8 *replybuf, u8 replybuflen)777{778 u8 crc4;779 780 memcpy(&msg->chunk[msg->curchunk_idx], replybuf, replybuflen);781 msg->curchunk_idx += replybuflen;782 783 if (msg->curchunk_idx >= msg->curchunk_len) {784 /* do CRC */785 crc4 = drm_dp_msg_data_crc4(msg->chunk, msg->curchunk_len - 1);786 if (crc4 != msg->chunk[msg->curchunk_len - 1])787 print_hex_dump(KERN_DEBUG, "wrong crc",788 DUMP_PREFIX_NONE, 16, 1,789 msg->chunk, msg->curchunk_len, false);790 /* copy chunk into bigger msg */791 memcpy(&msg->msg[msg->curlen], msg->chunk, msg->curchunk_len - 1);792 msg->curlen += msg->curchunk_len - 1;793 }794 return true;795}796 797static bool drm_dp_sideband_parse_link_address(const struct drm_dp_mst_topology_mgr *mgr,798 struct drm_dp_sideband_msg_rx *raw,799 struct drm_dp_sideband_msg_reply_body *repmsg)800{801 int idx = 1;802 int i;803 804 import_guid(&repmsg->u.link_addr.guid, &raw->msg[idx]);805 idx += 16;806 repmsg->u.link_addr.nports = raw->msg[idx] & 0xf;807 idx++;808 if (idx > raw->curlen)809 goto fail_len;810 for (i = 0; i < repmsg->u.link_addr.nports; i++) {811 if (raw->msg[idx] & 0x80)812 repmsg->u.link_addr.ports[i].input_port = 1;813 814 repmsg->u.link_addr.ports[i].peer_device_type = (raw->msg[idx] >> 4) & 0x7;815 repmsg->u.link_addr.ports[i].port_number = (raw->msg[idx] & 0xf);816 817 idx++;818 if (idx > raw->curlen)819 goto fail_len;820 repmsg->u.link_addr.ports[i].mcs = (raw->msg[idx] >> 7) & 0x1;821 repmsg->u.link_addr.ports[i].ddps = (raw->msg[idx] >> 6) & 0x1;822 if (repmsg->u.link_addr.ports[i].input_port == 0)823 repmsg->u.link_addr.ports[i].legacy_device_plug_status = (raw->msg[idx] >> 5) & 0x1;824 idx++;825 if (idx > raw->curlen)826 goto fail_len;827 if (repmsg->u.link_addr.ports[i].input_port == 0) {828 repmsg->u.link_addr.ports[i].dpcd_revision = (raw->msg[idx]);829 idx++;830 if (idx > raw->curlen)831 goto fail_len;832 import_guid(&repmsg->u.link_addr.ports[i].peer_guid, &raw->msg[idx]);833 idx += 16;834 if (idx > raw->curlen)835 goto fail_len;836 repmsg->u.link_addr.ports[i].num_sdp_streams = (raw->msg[idx] >> 4) & 0xf;837 repmsg->u.link_addr.ports[i].num_sdp_stream_sinks = (raw->msg[idx] & 0xf);838 idx++;839 840 }841 if (idx > raw->curlen)842 goto fail_len;843 }844 845 return true;846fail_len:847 DRM_DEBUG_KMS("link address reply parse length fail %d %d\n", idx, raw->curlen);848 return false;849}850 851static bool drm_dp_sideband_parse_remote_dpcd_read(struct drm_dp_sideband_msg_rx *raw,852 struct drm_dp_sideband_msg_reply_body *repmsg)853{854 int idx = 1;855 856 repmsg->u.remote_dpcd_read_ack.port_number = raw->msg[idx] & 0xf;857 idx++;858 if (idx > raw->curlen)859 goto fail_len;860 repmsg->u.remote_dpcd_read_ack.num_bytes = raw->msg[idx];861 idx++;862 if (idx > raw->curlen)863 goto fail_len;864 865 memcpy(repmsg->u.remote_dpcd_read_ack.bytes, &raw->msg[idx], repmsg->u.remote_dpcd_read_ack.num_bytes);866 return true;867fail_len:868 DRM_DEBUG_KMS("link address reply parse length fail %d %d\n", idx, raw->curlen);869 return false;870}871 872static bool drm_dp_sideband_parse_remote_dpcd_write(struct drm_dp_sideband_msg_rx *raw,873 struct drm_dp_sideband_msg_reply_body *repmsg)874{875 int idx = 1;876 877 repmsg->u.remote_dpcd_write_ack.port_number = raw->msg[idx] & 0xf;878 idx++;879 if (idx > raw->curlen)880 goto fail_len;881 return true;882fail_len:883 DRM_DEBUG_KMS("parse length fail %d %d\n", idx, raw->curlen);884 return false;885}886 887static bool drm_dp_sideband_parse_remote_i2c_read_ack(struct drm_dp_sideband_msg_rx *raw,888 struct drm_dp_sideband_msg_reply_body *repmsg)889{890 int idx = 1;891 892 repmsg->u.remote_i2c_read_ack.port_number = (raw->msg[idx] & 0xf);893 idx++;894 if (idx > raw->curlen)895 goto fail_len;896 repmsg->u.remote_i2c_read_ack.num_bytes = raw->msg[idx];897 idx++;898 /* TODO check */899 memcpy(repmsg->u.remote_i2c_read_ack.bytes, &raw->msg[idx], repmsg->u.remote_i2c_read_ack.num_bytes);900 return true;901fail_len:902 DRM_DEBUG_KMS("remote i2c reply parse length fail %d %d\n", idx, raw->curlen);903 return false;904}905 906static bool drm_dp_sideband_parse_enum_path_resources_ack(struct drm_dp_sideband_msg_rx *raw,907 struct drm_dp_sideband_msg_reply_body *repmsg)908{909 int idx = 1;910 911 repmsg->u.path_resources.port_number = (raw->msg[idx] >> 4) & 0xf;912 repmsg->u.path_resources.fec_capable = raw->msg[idx] & 0x1;913 idx++;914 if (idx > raw->curlen)915 goto fail_len;916 repmsg->u.path_resources.full_payload_bw_number = (raw->msg[idx] << 8) | (raw->msg[idx+1]);917 idx += 2;918 if (idx > raw->curlen)919 goto fail_len;920 repmsg->u.path_resources.avail_payload_bw_number = (raw->msg[idx] << 8) | (raw->msg[idx+1]);921 idx += 2;922 if (idx > raw->curlen)923 goto fail_len;924 return true;925fail_len:926 DRM_DEBUG_KMS("enum resource parse length fail %d %d\n", idx, raw->curlen);927 return false;928}929 930static bool drm_dp_sideband_parse_allocate_payload_ack(struct drm_dp_sideband_msg_rx *raw,931 struct drm_dp_sideband_msg_reply_body *repmsg)932{933 int idx = 1;934 935 repmsg->u.allocate_payload.port_number = (raw->msg[idx] >> 4) & 0xf;936 idx++;937 if (idx > raw->curlen)938 goto fail_len;939 repmsg->u.allocate_payload.vcpi = raw->msg[idx];940 idx++;941 if (idx > raw->curlen)942 goto fail_len;943 repmsg->u.allocate_payload.allocated_pbn = (raw->msg[idx] << 8) | (raw->msg[idx+1]);944 idx += 2;945 if (idx > raw->curlen)946 goto fail_len;947 return true;948fail_len:949 DRM_DEBUG_KMS("allocate payload parse length fail %d %d\n", idx, raw->curlen);950 return false;951}952 953static bool drm_dp_sideband_parse_query_payload_ack(struct drm_dp_sideband_msg_rx *raw,954 struct drm_dp_sideband_msg_reply_body *repmsg)955{956 int idx = 1;957 958 repmsg->u.query_payload.port_number = (raw->msg[idx] >> 4) & 0xf;959 idx++;960 if (idx > raw->curlen)961 goto fail_len;962 repmsg->u.query_payload.allocated_pbn = (raw->msg[idx] << 8) | (raw->msg[idx + 1]);963 idx += 2;964 if (idx > raw->curlen)965 goto fail_len;966 return true;967fail_len:968 DRM_DEBUG_KMS("query payload parse length fail %d %d\n", idx, raw->curlen);969 return false;970}971 972static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_msg_rx *raw,973 struct drm_dp_sideband_msg_reply_body *repmsg)974{975 int idx = 1;976 977 repmsg->u.port_number.port_number = (raw->msg[idx] >> 4) & 0xf;978 idx++;979 if (idx > raw->curlen) {980 DRM_DEBUG_KMS("power up/down phy parse length fail %d %d\n",981 idx, raw->curlen);982 return false;983 }984 return true;985}986 987static bool988drm_dp_sideband_parse_query_stream_enc_status(989 struct drm_dp_sideband_msg_rx *raw,990 struct drm_dp_sideband_msg_reply_body *repmsg)991{992 struct drm_dp_query_stream_enc_status_ack_reply *reply;993 994 reply = &repmsg->u.enc_status;995 996 reply->stream_id = raw->msg[3];997 998 reply->reply_signed = raw->msg[2] & BIT(0);999 1000 /*1001 * NOTE: It's my impression from reading the spec that the below parsing1002 * is correct. However I noticed while testing with an HDCP 1.4 display1003 * through an HDCP 2.2 hub that only bit 3 was set. In that case, I1004 * would expect both bits to be set. So keep the parsing following the1005 * spec, but beware reality might not match the spec (at least for some1006 * configurations).1007 */1008 reply->hdcp_1x_device_present = raw->msg[2] & BIT(4);1009 reply->hdcp_2x_device_present = raw->msg[2] & BIT(3);1010 1011 reply->query_capable_device_present = raw->msg[2] & BIT(5);1012 reply->legacy_device_present = raw->msg[2] & BIT(6);1013 reply->unauthorizable_device_present = raw->msg[2] & BIT(7);1014 1015 reply->auth_completed = !!(raw->msg[1] & BIT(3));1016 reply->encryption_enabled = !!(raw->msg[1] & BIT(4));1017 reply->repeater_present = !!(raw->msg[1] & BIT(5));1018 reply->state = (raw->msg[1] & GENMASK(7, 6)) >> 6;1019 1020 return true;1021}1022 1023static bool drm_dp_sideband_parse_reply(const struct drm_dp_mst_topology_mgr *mgr,1024 struct drm_dp_sideband_msg_rx *raw,1025 struct drm_dp_sideband_msg_reply_body *msg)1026{1027 memset(msg, 0, sizeof(*msg));1028 msg->reply_type = (raw->msg[0] & 0x80) >> 7;1029 msg->req_type = (raw->msg[0] & 0x7f);1030 1031 if (msg->reply_type == DP_SIDEBAND_REPLY_NAK) {1032 import_guid(&msg->u.nak.guid, &raw->msg[1]);1033 msg->u.nak.reason = raw->msg[17];1034 msg->u.nak.nak_data = raw->msg[18];1035 return false;1036 }1037 1038 switch (msg->req_type) {1039 case DP_LINK_ADDRESS:1040 return drm_dp_sideband_parse_link_address(mgr, raw, msg);1041 case DP_QUERY_PAYLOAD:1042 return drm_dp_sideband_parse_query_payload_ack(raw, msg);1043 case DP_REMOTE_DPCD_READ:1044 return drm_dp_sideband_parse_remote_dpcd_read(raw, msg);1045 case DP_REMOTE_DPCD_WRITE:1046 return drm_dp_sideband_parse_remote_dpcd_write(raw, msg);1047 case DP_REMOTE_I2C_READ:1048 return drm_dp_sideband_parse_remote_i2c_read_ack(raw, msg);1049 case DP_REMOTE_I2C_WRITE:1050 return true; /* since there's nothing to parse */1051 case DP_ENUM_PATH_RESOURCES:1052 return drm_dp_sideband_parse_enum_path_resources_ack(raw, msg);1053 case DP_ALLOCATE_PAYLOAD:1054 return drm_dp_sideband_parse_allocate_payload_ack(raw, msg);1055 case DP_POWER_DOWN_PHY:1056 case DP_POWER_UP_PHY:1057 return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);1058 case DP_CLEAR_PAYLOAD_ID_TABLE:1059 return true; /* since there's nothing to parse */1060 case DP_QUERY_STREAM_ENC_STATUS:1061 return drm_dp_sideband_parse_query_stream_enc_status(raw, msg);1062 default:1063 drm_err(mgr->dev, "Got unknown reply 0x%02x (%s)\n",1064 msg->req_type, drm_dp_mst_req_type_str(msg->req_type));1065 return false;1066 }1067}1068 1069static bool1070drm_dp_sideband_parse_connection_status_notify(const struct drm_dp_mst_topology_mgr *mgr,1071 struct drm_dp_sideband_msg_rx *raw,1072 struct drm_dp_sideband_msg_req_body *msg)1073{1074 int idx = 1;1075 1076 msg->u.conn_stat.port_number = (raw->msg[idx] & 0xf0) >> 4;1077 idx++;1078 if (idx > raw->curlen)1079 goto fail_len;1080 1081 import_guid(&msg->u.conn_stat.guid, &raw->msg[idx]);1082 idx += 16;1083 if (idx > raw->curlen)1084 goto fail_len;1085 1086 msg->u.conn_stat.legacy_device_plug_status = (raw->msg[idx] >> 6) & 0x1;1087 msg->u.conn_stat.displayport_device_plug_status = (raw->msg[idx] >> 5) & 0x1;1088 msg->u.conn_stat.message_capability_status = (raw->msg[idx] >> 4) & 0x1;1089 msg->u.conn_stat.input_port = (raw->msg[idx] >> 3) & 0x1;1090 msg->u.conn_stat.peer_device_type = (raw->msg[idx] & 0x7);1091 idx++;1092 return true;1093fail_len:1094 drm_dbg_kms(mgr->dev, "connection status reply parse length fail %d %d\n",1095 idx, raw->curlen);1096 return false;1097}1098 1099static bool drm_dp_sideband_parse_resource_status_notify(const struct drm_dp_mst_topology_mgr *mgr,1100 struct drm_dp_sideband_msg_rx *raw,1101 struct drm_dp_sideband_msg_req_body *msg)1102{1103 int idx = 1;1104 1105 msg->u.resource_stat.port_number = (raw->msg[idx] & 0xf0) >> 4;1106 idx++;1107 if (idx > raw->curlen)1108 goto fail_len;1109 1110 import_guid(&msg->u.resource_stat.guid, &raw->msg[idx]);1111 idx += 16;1112 if (idx > raw->curlen)1113 goto fail_len;1114 1115 msg->u.resource_stat.available_pbn = (raw->msg[idx] << 8) | (raw->msg[idx + 1]);1116 idx++;1117 return true;1118fail_len:1119 drm_dbg_kms(mgr->dev, "resource status reply parse length fail %d %d\n", idx, raw->curlen);1120 return false;1121}1122 1123static bool drm_dp_sideband_parse_req(const struct drm_dp_mst_topology_mgr *mgr,1124 struct drm_dp_sideband_msg_rx *raw,1125 struct drm_dp_sideband_msg_req_body *msg)1126{1127 memset(msg, 0, sizeof(*msg));1128 msg->req_type = (raw->msg[0] & 0x7f);1129 1130 switch (msg->req_type) {1131 case DP_CONNECTION_STATUS_NOTIFY:1132 return drm_dp_sideband_parse_connection_status_notify(mgr, raw, msg);1133 case DP_RESOURCE_STATUS_NOTIFY:1134 return drm_dp_sideband_parse_resource_status_notify(mgr, raw, msg);1135 default:1136 drm_err(mgr->dev, "Got unknown request 0x%02x (%s)\n",1137 msg->req_type, drm_dp_mst_req_type_str(msg->req_type));1138 return false;1139 }1140}1141 1142static void build_dpcd_write(struct drm_dp_sideband_msg_tx *msg,1143 u8 port_num, u32 offset, u8 num_bytes, u8 *bytes)1144{1145 struct drm_dp_sideband_msg_req_body req;1146 1147 req.req_type = DP_REMOTE_DPCD_WRITE;1148 req.u.dpcd_write.port_number = port_num;1149 req.u.dpcd_write.dpcd_address = offset;1150 req.u.dpcd_write.num_bytes = num_bytes;1151 req.u.dpcd_write.bytes = bytes;1152 drm_dp_encode_sideband_req(&req, msg);1153}1154 1155static void build_link_address(struct drm_dp_sideband_msg_tx *msg)1156{1157 struct drm_dp_sideband_msg_req_body req;1158 1159 req.req_type = DP_LINK_ADDRESS;1160 drm_dp_encode_sideband_req(&req, msg);1161}1162 1163static void build_clear_payload_id_table(struct drm_dp_sideband_msg_tx *msg)1164{1165 struct drm_dp_sideband_msg_req_body req;1166 1167 req.req_type = DP_CLEAR_PAYLOAD_ID_TABLE;1168 drm_dp_encode_sideband_req(&req, msg);1169 msg->path_msg = true;1170}1171 1172static int build_enum_path_resources(struct drm_dp_sideband_msg_tx *msg,1173 int port_num)1174{1175 struct drm_dp_sideband_msg_req_body req;1176 1177 req.req_type = DP_ENUM_PATH_RESOURCES;1178 req.u.port_num.port_number = port_num;1179 drm_dp_encode_sideband_req(&req, msg);1180 msg->path_msg = true;1181 return 0;1182}1183 1184static void build_allocate_payload(struct drm_dp_sideband_msg_tx *msg,1185 int port_num,1186 u8 vcpi, uint16_t pbn,1187 u8 number_sdp_streams,1188 u8 *sdp_stream_sink)1189{1190 struct drm_dp_sideband_msg_req_body req;1191 1192 memset(&req, 0, sizeof(req));1193 req.req_type = DP_ALLOCATE_PAYLOAD;1194 req.u.allocate_payload.port_number = port_num;1195 req.u.allocate_payload.vcpi = vcpi;1196 req.u.allocate_payload.pbn = pbn;1197 req.u.allocate_payload.number_sdp_streams = number_sdp_streams;1198 memcpy(req.u.allocate_payload.sdp_stream_sink, sdp_stream_sink,1199 number_sdp_streams);1200 drm_dp_encode_sideband_req(&req, msg);1201 msg->path_msg = true;1202}1203 1204static void build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,1205 int port_num, bool power_up)1206{1207 struct drm_dp_sideband_msg_req_body req;1208 1209 if (power_up)1210 req.req_type = DP_POWER_UP_PHY;1211 else1212 req.req_type = DP_POWER_DOWN_PHY;1213 1214 req.u.port_num.port_number = port_num;1215 drm_dp_encode_sideband_req(&req, msg);1216 msg->path_msg = true;1217}1218 1219static int1220build_query_stream_enc_status(struct drm_dp_sideband_msg_tx *msg, u8 stream_id,1221 u8 *q_id)1222{1223 struct drm_dp_sideband_msg_req_body req;1224 1225 req.req_type = DP_QUERY_STREAM_ENC_STATUS;1226 req.u.enc_status.stream_id = stream_id;1227 memcpy(req.u.enc_status.client_id, q_id,1228 sizeof(req.u.enc_status.client_id));1229 req.u.enc_status.stream_event = 0;1230 req.u.enc_status.valid_stream_event = false;1231 req.u.enc_status.stream_behavior = 0;1232 req.u.enc_status.valid_stream_behavior = false;1233 1234 drm_dp_encode_sideband_req(&req, msg);1235 return 0;1236}1237 1238static bool check_txmsg_state(struct drm_dp_mst_topology_mgr *mgr,1239 struct drm_dp_sideband_msg_tx *txmsg)1240{1241 unsigned int state;1242 1243 /*1244 * All updates to txmsg->state are protected by mgr->qlock, and the two1245 * cases we check here are terminal states. For those the barriers1246 * provided by the wake_up/wait_event pair are enough.1247 */1248 state = READ_ONCE(txmsg->state);1249 return (state == DRM_DP_SIDEBAND_TX_RX ||1250 state == DRM_DP_SIDEBAND_TX_TIMEOUT);1251}1252 1253static int drm_dp_mst_wait_tx_reply(struct drm_dp_mst_branch *mstb,1254 struct drm_dp_sideband_msg_tx *txmsg)1255{1256 struct drm_dp_mst_topology_mgr *mgr = mstb->mgr;1257 unsigned long wait_timeout = msecs_to_jiffies(4000);1258 unsigned long wait_expires = jiffies + wait_timeout;1259 int ret;1260 1261 for (;;) {1262 /*1263 * If the driver provides a way for this, change to1264 * poll-waiting for the MST reply interrupt if we didn't receive1265 * it for 50 msec. This would cater for cases where the HPD1266 * pulse signal got lost somewhere, even though the sink raised1267 * the corresponding MST interrupt correctly. One example is the1268 * Club 3D CAC-1557 TypeC -> DP adapter which for some reason1269 * filters out short pulses with a duration less than ~540 usec.1270 *1271 * The poll period is 50 msec to avoid missing an interrupt1272 * after the sink has cleared it (after a 110msec timeout1273 * since it raised the interrupt).1274 */1275 ret = wait_event_timeout(mgr->tx_waitq,1276 check_txmsg_state(mgr, txmsg),1277 mgr->cbs->poll_hpd_irq ?1278 msecs_to_jiffies(50) :1279 wait_timeout);1280 1281 if (ret || !mgr->cbs->poll_hpd_irq ||1282 time_after(jiffies, wait_expires))1283 break;1284 1285 mgr->cbs->poll_hpd_irq(mgr);1286 }1287 1288 mutex_lock(&mgr->qlock);1289 if (ret > 0) {1290 if (txmsg->state == DRM_DP_SIDEBAND_TX_TIMEOUT) {1291 ret = -EIO;1292 goto out;1293 }1294 } else {1295 drm_dbg_kms(mgr->dev, "timedout msg send %p %d %d\n",1296 txmsg, txmsg->state, txmsg->seqno);1297 1298 /* dump some state */1299 ret = -EIO;1300 1301 /* remove from q */1302 if (txmsg->state == DRM_DP_SIDEBAND_TX_QUEUED ||1303 txmsg->state == DRM_DP_SIDEBAND_TX_START_SEND ||1304 txmsg->state == DRM_DP_SIDEBAND_TX_SENT)1305 list_del(&txmsg->next);1306 }1307out:1308 if (unlikely(ret == -EIO) && drm_debug_enabled(DRM_UT_DP)) {1309 struct drm_printer p = drm_dbg_printer(mgr->dev, DRM_UT_DP,1310 DBG_PREFIX);1311 1312 drm_dp_mst_dump_sideband_msg_tx(&p, txmsg);1313 }1314 mutex_unlock(&mgr->qlock);1315 1316 drm_dp_mst_kick_tx(mgr);1317 return ret;1318}1319 1320static struct drm_dp_mst_branch *drm_dp_add_mst_branch_device(u8 lct, u8 *rad)1321{1322 struct drm_dp_mst_branch *mstb;1323 1324 mstb = kzalloc(sizeof(*mstb), GFP_KERNEL);1325 if (!mstb)1326 return NULL;1327 1328 mstb->lct = lct;1329 if (lct > 1)1330 memcpy(mstb->rad, rad, lct / 2);1331 INIT_LIST_HEAD(&mstb->ports);1332 kref_init(&mstb->topology_kref);1333 kref_init(&mstb->malloc_kref);1334 return mstb;1335}1336 1337static void drm_dp_free_mst_branch_device(struct kref *kref)1338{1339 struct drm_dp_mst_branch *mstb =1340 container_of(kref, struct drm_dp_mst_branch, malloc_kref);1341 1342 if (mstb->port_parent)1343 drm_dp_mst_put_port_malloc(mstb->port_parent);1344 1345 kfree(mstb);1346}1347 1348/**1349 * DOC: Branch device and port refcounting1350 *1351 * Topology refcount overview1352 * ~~~~~~~~~~~~~~~~~~~~~~~~~~1353 *1354 * The refcounting schemes for &struct drm_dp_mst_branch and &struct1355 * drm_dp_mst_port are somewhat unusual. Both ports and branch devices have1356 * two different kinds of refcounts: topology refcounts, and malloc refcounts.1357 *1358 * Topology refcounts are not exposed to drivers, and are handled internally1359 * by the DP MST helpers. The helpers use them in order to prevent the1360 * in-memory topology state from being changed in the middle of critical1361 * operations like changing the internal state of payload allocations. This1362 * means each branch and port will be considered to be connected to the rest1363 * of the topology until its topology refcount reaches zero. Additionally,1364 * for ports this means that their associated &struct drm_connector will stay1365 * registered with userspace until the port's refcount reaches 0.1366 *1367 * Malloc refcount overview1368 * ~~~~~~~~~~~~~~~~~~~~~~~~1369 *1370 * Malloc references are used to keep a &struct drm_dp_mst_port or &struct1371 * drm_dp_mst_branch allocated even after all of its topology references have1372 * been dropped, so that the driver or MST helpers can safely access each1373 * branch's last known state before it was disconnected from the topology.1374 * When the malloc refcount of a port or branch reaches 0, the memory1375 * allocation containing the &struct drm_dp_mst_branch or &struct1376 * drm_dp_mst_port respectively will be freed.1377 *1378 * For &struct drm_dp_mst_branch, malloc refcounts are not currently exposed1379 * to drivers. As of writing this documentation, there are no drivers that1380 * have a usecase for accessing &struct drm_dp_mst_branch outside of the MST1381 * helpers. Exposing this API to drivers in a race-free manner would take more1382 * tweaking of the refcounting scheme, however patches are welcome provided1383 * there is a legitimate driver usecase for this.1384 *1385 * Refcount relationships in a topology1386 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1387 *1388 * Let's take a look at why the relationship between topology and malloc1389 * refcounts is designed the way it is.1390 *1391 * .. kernel-figure:: dp-mst/topology-figure-1.dot1392 *1393 * An example of topology and malloc refs in a DP MST topology with two1394 * active payloads. Topology refcount increments are indicated by solid1395 * lines, and malloc refcount increments are indicated by dashed lines.1396 * Each starts from the branch which incremented the refcount, and ends at1397 * the branch to which the refcount belongs to, i.e. the arrow points the1398 * same way as the C pointers used to reference a structure.1399 *1400 * As you can see in the above figure, every branch increments the topology1401 * refcount of its children, and increments the malloc refcount of its1402 * parent. Additionally, every payload increments the malloc refcount of its1403 * assigned port by 1.1404 *1405 * So, what would happen if MSTB #3 from the above figure was unplugged from1406 * the system, but the driver hadn't yet removed payload #2 from port #3? The1407 * topology would start to look like the figure below.1408 *1409 * .. kernel-figure:: dp-mst/topology-figure-2.dot1410 *1411 * Ports and branch devices which have been released from memory are1412 * colored grey, and references which have been removed are colored red.1413 *1414 * Whenever a port or branch device's topology refcount reaches zero, it will1415 * decrement the topology refcounts of all its children, the malloc refcount1416 * of its parent, and finally its own malloc refcount. For MSTB #4 and port1417 * #4, this means they both have been disconnected from the topology and freed1418 * from memory. But, because payload #2 is still holding a reference to port1419 * #3, port #3 is removed from the topology but its &struct drm_dp_mst_port1420 * is still accessible from memory. This also means port #3 has not yet1421 * decremented the malloc refcount of MSTB #3, so its &struct1422 * drm_dp_mst_branch will also stay allocated in memory until port #3's1423 * malloc refcount reaches 0.1424 *1425 * This relationship is necessary because in order to release payload #2, we1426 * need to be able to figure out the last relative of port #3 that's still1427 * connected to the topology. In this case, we would travel up the topology as1428 * shown below.1429 *1430 * .. kernel-figure:: dp-mst/topology-figure-3.dot1431 *1432 * And finally, remove payload #2 by communicating with port #2 through1433 * sideband transactions.1434 */1435 1436/**1437 * drm_dp_mst_get_mstb_malloc() - Increment the malloc refcount of a branch1438 * device1439 * @mstb: The &struct drm_dp_mst_branch to increment the malloc refcount of1440 *1441 * Increments &drm_dp_mst_branch.malloc_kref. When1442 * &drm_dp_mst_branch.malloc_kref reaches 0, the memory allocation for @mstb1443 * will be released and @mstb may no longer be used.1444 *1445 * See also: drm_dp_mst_put_mstb_malloc()1446 */1447static void1448drm_dp_mst_get_mstb_malloc(struct drm_dp_mst_branch *mstb)1449{1450 kref_get(&mstb->malloc_kref);1451 drm_dbg(mstb->mgr->dev, "mstb %p (%d)\n", mstb, kref_read(&mstb->malloc_kref));1452}1453 1454/**1455 * drm_dp_mst_put_mstb_malloc() - Decrement the malloc refcount of a branch1456 * device1457 * @mstb: The &struct drm_dp_mst_branch to decrement the malloc refcount of1458 *1459 * Decrements &drm_dp_mst_branch.malloc_kref. When1460 * &drm_dp_mst_branch.malloc_kref reaches 0, the memory allocation for @mstb1461 * will be released and @mstb may no longer be used.1462 *1463 * See also: drm_dp_mst_get_mstb_malloc()1464 */1465static void1466drm_dp_mst_put_mstb_malloc(struct drm_dp_mst_branch *mstb)1467{1468 drm_dbg(mstb->mgr->dev, "mstb %p (%d)\n", mstb, kref_read(&mstb->malloc_kref) - 1);1469 kref_put(&mstb->malloc_kref, drm_dp_free_mst_branch_device);1470}1471 1472static void drm_dp_free_mst_port(struct kref *kref)1473{1474 struct drm_dp_mst_port *port =1475 container_of(kref, struct drm_dp_mst_port, malloc_kref);1476 1477 drm_dp_mst_put_mstb_malloc(port->parent);1478 kfree(port);1479}1480 1481/**1482 * drm_dp_mst_get_port_malloc() - Increment the malloc refcount of an MST port1483 * @port: The &struct drm_dp_mst_port to increment the malloc refcount of1484 *1485 * Increments &drm_dp_mst_port.malloc_kref. When &drm_dp_mst_port.malloc_kref1486 * reaches 0, the memory allocation for @port will be released and @port may1487 * no longer be used.1488 *1489 * Because @port could potentially be freed at any time by the DP MST helpers1490 * if &drm_dp_mst_port.malloc_kref reaches 0, including during a call to this1491 * function, drivers that which to make use of &struct drm_dp_mst_port should1492 * ensure that they grab at least one main malloc reference to their MST ports1493 * in &drm_dp_mst_topology_cbs.add_connector. This callback is called before1494 * there is any chance for &drm_dp_mst_port.malloc_kref to reach 0.1495 *1496 * See also: drm_dp_mst_put_port_malloc()1497 */1498void1499drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port)1500{1501 kref_get(&port->malloc_kref);1502 drm_dbg(port->mgr->dev, "port %p (%d)\n", port, kref_read(&port->malloc_kref));1503}1504EXPORT_SYMBOL(drm_dp_mst_get_port_malloc);1505 1506/**1507 * drm_dp_mst_put_port_malloc() - Decrement the malloc refcount of an MST port1508 * @port: The &struct drm_dp_mst_port to decrement the malloc refcount of1509 *1510 * Decrements &drm_dp_mst_port.malloc_kref. When &drm_dp_mst_port.malloc_kref1511 * reaches 0, the memory allocation for @port will be released and @port may1512 * no longer be used.1513 *1514 * See also: drm_dp_mst_get_port_malloc()1515 */1516void1517drm_dp_mst_put_port_malloc(struct drm_dp_mst_port *port)1518{1519 drm_dbg(port->mgr->dev, "port %p (%d)\n", port, kref_read(&port->malloc_kref) - 1);1520 kref_put(&port->malloc_kref, drm_dp_free_mst_port);1521}1522EXPORT_SYMBOL(drm_dp_mst_put_port_malloc);1523 1524#if IS_ENABLED(CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS)1525 1526#define STACK_DEPTH 81527 1528static noinline void1529__topology_ref_save(struct drm_dp_mst_topology_mgr *mgr,1530 struct drm_dp_mst_topology_ref_history *history,1531 enum drm_dp_mst_topology_ref_type type)1532{1533 struct drm_dp_mst_topology_ref_entry *entry = NULL;1534 depot_stack_handle_t backtrace;1535 ulong stack_entries[STACK_DEPTH];1536 uint n;1537 int i;1538 1539 n = stack_trace_save(stack_entries, ARRAY_SIZE(stack_entries), 1);1540 backtrace = stack_depot_save(stack_entries, n, GFP_KERNEL);1541 if (!backtrace)1542 return;1543 1544 /* Try to find an existing entry for this backtrace */1545 for (i = 0; i < history->len; i++) {1546 if (history->entries[i].backtrace == backtrace) {1547 entry = &history->entries[i];1548 break;1549 }1550 }1551 1552 /* Otherwise add one */1553 if (!entry) {1554 struct drm_dp_mst_topology_ref_entry *new;1555 int new_len = history->len + 1;1556 1557 new = krealloc(history->entries, sizeof(*new) * new_len,1558 GFP_KERNEL);1559 if (!new)1560 return;1561 1562 entry = &new[history->len];1563 history->len = new_len;1564 history->entries = new;1565 1566 entry->backtrace = backtrace;1567 entry->type = type;1568 entry->count = 0;1569 }1570 entry->count++;1571 entry->ts_nsec = ktime_get_ns();1572}1573 1574static int1575topology_ref_history_cmp(const void *a, const void *b)1576{1577 const struct drm_dp_mst_topology_ref_entry *entry_a = a, *entry_b = b;1578 1579 if (entry_a->ts_nsec > entry_b->ts_nsec)1580 return 1;1581 else if (entry_a->ts_nsec < entry_b->ts_nsec)1582 return -1;1583 else1584 return 0;1585}1586 1587static inline const char *1588topology_ref_type_to_str(enum drm_dp_mst_topology_ref_type type)1589{1590 if (type == DRM_DP_MST_TOPOLOGY_REF_GET)1591 return "get";1592 else1593 return "put";1594}1595 1596static void1597__dump_topology_ref_history(struct drm_device *drm,1598 struct drm_dp_mst_topology_ref_history *history,1599 void *ptr, const char *type_str)1600{1601 struct drm_printer p = drm_dbg_printer(drm, DRM_UT_DP, DBG_PREFIX);1602 char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);1603 int i;1604 1605 if (!buf)1606 return;1607 1608 if (!history->len)1609 goto out;1610 1611 /* First, sort the list so that it goes from oldest to newest1612 * reference entry1613 */1614 sort(history->entries, history->len, sizeof(*history->entries),1615 topology_ref_history_cmp, NULL);1616 1617 drm_printf(&p, "%s (%p) topology count reached 0, dumping history:\n",1618 type_str, ptr);1619 1620 for (i = 0; i < history->len; i++) {1621 const struct drm_dp_mst_topology_ref_entry *entry =1622 &history->entries[i];1623 u64 ts_nsec = entry->ts_nsec;1624 u32 rem_nsec = do_div(ts_nsec, 1000000000);1625 1626 stack_depot_snprint(entry->backtrace, buf, PAGE_SIZE, 4);1627 1628 drm_printf(&p, " %d %ss (last at %5llu.%06u):\n%s",1629 entry->count,1630 topology_ref_type_to_str(entry->type),1631 ts_nsec, rem_nsec / 1000, buf);1632 }1633 1634 /* Now free the history, since this is the only time we expose it */1635 kfree(history->entries);1636out:1637 kfree(buf);1638}1639 1640static __always_inline void1641drm_dp_mst_dump_mstb_topology_history(struct drm_dp_mst_branch *mstb)1642{1643 __dump_topology_ref_history(mstb->mgr->dev, &mstb->topology_ref_history,1644 mstb, "MSTB");1645}1646 1647static __always_inline void1648drm_dp_mst_dump_port_topology_history(struct drm_dp_mst_port *port)1649{1650 __dump_topology_ref_history(port->mgr->dev, &port->topology_ref_history,1651 port, "Port");1652}1653 1654static __always_inline void1655save_mstb_topology_ref(struct drm_dp_mst_branch *mstb,1656 enum drm_dp_mst_topology_ref_type type)1657{1658 __topology_ref_save(mstb->mgr, &mstb->topology_ref_history, type);1659}1660 1661static __always_inline void1662save_port_topology_ref(struct drm_dp_mst_port *port,1663 enum drm_dp_mst_topology_ref_type type)1664{1665 __topology_ref_save(port->mgr, &port->topology_ref_history, type);1666}1667 1668static inline void1669topology_ref_history_lock(struct drm_dp_mst_topology_mgr *mgr)1670{1671 mutex_lock(&mgr->topology_ref_history_lock);1672}1673 1674static inline void1675topology_ref_history_unlock(struct drm_dp_mst_topology_mgr *mgr)1676{1677 mutex_unlock(&mgr->topology_ref_history_lock);1678}1679#else1680static inline void1681topology_ref_history_lock(struct drm_dp_mst_topology_mgr *mgr) {}1682static inline void1683topology_ref_history_unlock(struct drm_dp_mst_topology_mgr *mgr) {}1684static inline void1685drm_dp_mst_dump_mstb_topology_history(struct drm_dp_mst_branch *mstb) {}1686static inline void1687drm_dp_mst_dump_port_topology_history(struct drm_dp_mst_port *port) {}1688#define save_mstb_topology_ref(mstb, type)1689#define save_port_topology_ref(port, type)1690#endif1691 1692struct drm_dp_mst_atomic_payload *1693drm_atomic_get_mst_payload_state(struct drm_dp_mst_topology_state *state,1694 struct drm_dp_mst_port *port)1695{1696 struct drm_dp_mst_atomic_payload *payload;1697 1698 list_for_each_entry(payload, &state->payloads, next)1699 if (payload->port == port)1700 return payload;1701 1702 return NULL;1703}1704EXPORT_SYMBOL(drm_atomic_get_mst_payload_state);1705 1706static void drm_dp_destroy_mst_branch_device(struct kref *kref)1707{1708 struct drm_dp_mst_branch *mstb =1709 container_of(kref, struct drm_dp_mst_branch, topology_kref);1710 struct drm_dp_mst_topology_mgr *mgr = mstb->mgr;1711 1712 drm_dp_mst_dump_mstb_topology_history(mstb);1713 1714 INIT_LIST_HEAD(&mstb->destroy_next);1715 1716 /*1717 * This can get called under mgr->mutex, so we need to perform the1718 * actual destruction of the mstb in another worker1719 */1720 mutex_lock(&mgr->delayed_destroy_lock);1721 list_add(&mstb->destroy_next, &mgr->destroy_branch_device_list);1722 mutex_unlock(&mgr->delayed_destroy_lock);1723 queue_work(mgr->delayed_destroy_wq, &mgr->delayed_destroy_work);1724}1725 1726/**1727 * drm_dp_mst_topology_try_get_mstb() - Increment the topology refcount of a1728 * branch device unless it's zero1729 * @mstb: &struct drm_dp_mst_branch to increment the topology refcount of1730 *1731 * Attempts to grab a topology reference to @mstb, if it hasn't yet been1732 * removed from the topology (e.g. &drm_dp_mst_branch.topology_kref has1733 * reached 0). Holding a topology reference implies that a malloc reference1734 * will be held to @mstb as long as the user holds the topology reference.1735 *1736 * Care should be taken to ensure that the user has at least one malloc1737 * reference to @mstb. If you already have a topology reference to @mstb, you1738 * should use drm_dp_mst_topology_get_mstb() instead.1739 *1740 * See also:1741 * drm_dp_mst_topology_get_mstb()1742 * drm_dp_mst_topology_put_mstb()1743 *1744 * Returns:1745 * * 1: A topology reference was grabbed successfully1746 * * 0: @port is no longer in the topology, no reference was grabbed1747 */1748static int __must_check1749drm_dp_mst_topology_try_get_mstb(struct drm_dp_mst_branch *mstb)1750{1751 int ret;1752 1753 topology_ref_history_lock(mstb->mgr);1754 ret = kref_get_unless_zero(&mstb->topology_kref);1755 if (ret) {1756 drm_dbg(mstb->mgr->dev, "mstb %p (%d)\n", mstb, kref_read(&mstb->topology_kref));1757 save_mstb_topology_ref(mstb, DRM_DP_MST_TOPOLOGY_REF_GET);1758 }1759 1760 topology_ref_history_unlock(mstb->mgr);1761 1762 return ret;1763}1764 1765/**1766 * drm_dp_mst_topology_get_mstb() - Increment the topology refcount of a1767 * branch device1768 * @mstb: The &struct drm_dp_mst_branch to increment the topology refcount of1769 *1770 * Increments &drm_dp_mst_branch.topology_refcount without checking whether or1771 * not it's already reached 0. This is only valid to use in scenarios where1772 * you are already guaranteed to have at least one active topology reference1773 * to @mstb. Otherwise, drm_dp_mst_topology_try_get_mstb() must be used.1774 *1775 * See also:1776 * drm_dp_mst_topology_try_get_mstb()1777 * drm_dp_mst_topology_put_mstb()1778 */1779static void drm_dp_mst_topology_get_mstb(struct drm_dp_mst_branch *mstb)1780{1781 topology_ref_history_lock(mstb->mgr);1782 1783 save_mstb_topology_ref(mstb, DRM_DP_MST_TOPOLOGY_REF_GET);1784 WARN_ON(kref_read(&mstb->topology_kref) == 0);1785 kref_get(&mstb->topology_kref);1786 drm_dbg(mstb->mgr->dev, "mstb %p (%d)\n", mstb, kref_read(&mstb->topology_kref));1787 1788 topology_ref_history_unlock(mstb->mgr);1789}1790 1791/**1792 * drm_dp_mst_topology_put_mstb() - release a topology reference to a branch1793 * device1794 * @mstb: The &struct drm_dp_mst_branch to release the topology reference from1795 *1796 * Releases a topology reference from @mstb by decrementing1797 * &drm_dp_mst_branch.topology_kref.1798 *1799 * See also:1800 * drm_dp_mst_topology_try_get_mstb()1801 * drm_dp_mst_topology_get_mstb()1802 */1803static void1804drm_dp_mst_topology_put_mstb(struct drm_dp_mst_branch *mstb)1805{1806 topology_ref_history_lock(mstb->mgr);1807 1808 drm_dbg(mstb->mgr->dev, "mstb %p (%d)\n", mstb, kref_read(&mstb->topology_kref) - 1);1809 save_mstb_topology_ref(mstb, DRM_DP_MST_TOPOLOGY_REF_PUT);1810 1811 topology_ref_history_unlock(mstb->mgr);1812 kref_put(&mstb->topology_kref, drm_dp_destroy_mst_branch_device);1813}1814 1815static void drm_dp_destroy_port(struct kref *kref)1816{1817 struct drm_dp_mst_port *port =1818 container_of(kref, struct drm_dp_mst_port, topology_kref);1819 struct drm_dp_mst_topology_mgr *mgr = port->mgr;1820 1821 drm_dp_mst_dump_port_topology_history(port);1822 1823 /* There's nothing that needs locking to destroy an input port yet */1824 if (port->input) {1825 drm_dp_mst_put_port_malloc(port);1826 return;1827 }1828 1829 drm_edid_free(port->cached_edid);1830 1831 /*1832 * we can't destroy the connector here, as we might be holding the1833 * mode_config.mutex from an EDID retrieval1834 */1835 mutex_lock(&mgr->delayed_destroy_lock);1836 list_add(&port->next, &mgr->destroy_port_list);1837 mutex_unlock(&mgr->delayed_destroy_lock);1838 queue_work(mgr->delayed_destroy_wq, &mgr->delayed_destroy_work);1839}1840 1841/**1842 * drm_dp_mst_topology_try_get_port() - Increment the topology refcount of a1843 * port unless it's zero1844 * @port: &struct drm_dp_mst_port to increment the topology refcount of1845 *1846 * Attempts to grab a topology reference to @port, if it hasn't yet been1847 * removed from the topology (e.g. &drm_dp_mst_port.topology_kref has reached1848 * 0). Holding a topology reference implies that a malloc reference will be1849 * held to @port as long as the user holds the topology reference.1850 *1851 * Care should be taken to ensure that the user has at least one malloc1852 * reference to @port. If you already have a topology reference to @port, you1853 * should use drm_dp_mst_topology_get_port() instead.1854 *1855 * See also:1856 * drm_dp_mst_topology_get_port()1857 * drm_dp_mst_topology_put_port()1858 *1859 * Returns:1860 * * 1: A topology reference was grabbed successfully1861 * * 0: @port is no longer in the topology, no reference was grabbed1862 */1863static int __must_check1864drm_dp_mst_topology_try_get_port(struct drm_dp_mst_port *port)1865{1866 int ret;1867 1868 topology_ref_history_lock(port->mgr);1869 ret = kref_get_unless_zero(&port->topology_kref);1870 if (ret) {1871 drm_dbg(port->mgr->dev, "port %p (%d)\n", port, kref_read(&port->topology_kref));1872 save_port_topology_ref(port, DRM_DP_MST_TOPOLOGY_REF_GET);1873 }1874 1875 topology_ref_history_unlock(port->mgr);1876 return ret;1877}1878 1879/**1880 * drm_dp_mst_topology_get_port() - Increment the topology refcount of a port1881 * @port: The &struct drm_dp_mst_port to increment the topology refcount of1882 *1883 * Increments &drm_dp_mst_port.topology_refcount without checking whether or1884 * not it's already reached 0. This is only valid to use in scenarios where1885 * you are already guaranteed to have at least one active topology reference1886 * to @port. Otherwise, drm_dp_mst_topology_try_get_port() must be used.1887 *1888 * See also:1889 * drm_dp_mst_topology_try_get_port()1890 * drm_dp_mst_topology_put_port()1891 */1892static void drm_dp_mst_topology_get_port(struct drm_dp_mst_port *port)1893{1894 topology_ref_history_lock(port->mgr);1895 1896 WARN_ON(kref_read(&port->topology_kref) == 0);1897 kref_get(&port->topology_kref);1898 drm_dbg(port->mgr->dev, "port %p (%d)\n", port, kref_read(&port->topology_kref));1899 save_port_topology_ref(port, DRM_DP_MST_TOPOLOGY_REF_GET);1900 1901 topology_ref_history_unlock(port->mgr);1902}1903 1904/**1905 * drm_dp_mst_topology_put_port() - release a topology reference to a port1906 * @port: The &struct drm_dp_mst_port to release the topology reference from1907 *1908 * Releases a topology reference from @port by decrementing1909 * &drm_dp_mst_port.topology_kref.1910 *1911 * See also:1912 * drm_dp_mst_topology_try_get_port()1913 * drm_dp_mst_topology_get_port()1914 */1915static void drm_dp_mst_topology_put_port(struct drm_dp_mst_port *port)1916{1917 topology_ref_history_lock(port->mgr);1918 1919 drm_dbg(port->mgr->dev, "port %p (%d)\n", port, kref_read(&port->topology_kref) - 1);1920 save_port_topology_ref(port, DRM_DP_MST_TOPOLOGY_REF_PUT);1921 1922 topology_ref_history_unlock(port->mgr);1923 kref_put(&port->topology_kref, drm_dp_destroy_port);1924}1925 1926static struct drm_dp_mst_branch *1927drm_dp_mst_topology_get_mstb_validated_locked(struct drm_dp_mst_branch *mstb,1928 struct drm_dp_mst_branch *to_find)1929{1930 struct drm_dp_mst_port *port;1931 struct drm_dp_mst_branch *rmstb;1932 1933 if (to_find == mstb)1934 return mstb;1935 1936 list_for_each_entry(port, &mstb->ports, next) {1937 if (port->mstb) {1938 rmstb = drm_dp_mst_topology_get_mstb_validated_locked(1939 port->mstb, to_find);1940 if (rmstb)1941 return rmstb;1942 }1943 }1944 return NULL;1945}1946 1947static struct drm_dp_mst_branch *1948drm_dp_mst_topology_get_mstb_validated(struct drm_dp_mst_topology_mgr *mgr,1949 struct drm_dp_mst_branch *mstb)1950{1951 struct drm_dp_mst_branch *rmstb = NULL;1952 1953 mutex_lock(&mgr->lock);1954 if (mgr->mst_primary) {1955 rmstb = drm_dp_mst_topology_get_mstb_validated_locked(1956 mgr->mst_primary, mstb);1957 1958 if (rmstb && !drm_dp_mst_topology_try_get_mstb(rmstb))1959 rmstb = NULL;1960 }1961 mutex_unlock(&mgr->lock);1962 return rmstb;1963}1964 1965static struct drm_dp_mst_port *1966drm_dp_mst_topology_get_port_validated_locked(struct drm_dp_mst_branch *mstb,1967 struct drm_dp_mst_port *to_find)1968{1969 struct drm_dp_mst_port *port, *mport;1970 1971 list_for_each_entry(port, &mstb->ports, next) {1972 if (port == to_find)1973 return port;1974 1975 if (port->mstb) {1976 mport = drm_dp_mst_topology_get_port_validated_locked(1977 port->mstb, to_find);1978 if (mport)1979 return mport;1980 }1981 }1982 return NULL;1983}1984 1985static struct drm_dp_mst_port *1986drm_dp_mst_topology_get_port_validated(struct drm_dp_mst_topology_mgr *mgr,1987 struct drm_dp_mst_port *port)1988{1989 struct drm_dp_mst_port *rport = NULL;1990 1991 mutex_lock(&mgr->lock);1992 if (mgr->mst_primary) {1993 rport = drm_dp_mst_topology_get_port_validated_locked(1994 mgr->mst_primary, port);1995 1996 if (rport && !drm_dp_mst_topology_try_get_port(rport))1997 rport = NULL;1998 }1999 mutex_unlock(&mgr->lock);2000 return rport;2001}2002 2003static struct drm_dp_mst_port *drm_dp_get_port(struct drm_dp_mst_branch *mstb, u8 port_num)2004{2005 struct drm_dp_mst_port *port;2006 int ret;2007 2008 list_for_each_entry(port, &mstb->ports, next) {2009 if (port->port_num == port_num) {2010 ret = drm_dp_mst_topology_try_get_port(port);2011 return ret ? port : NULL;2012 }2013 }2014 2015 return NULL;2016}2017 2018/*2019 * calculate a new RAD for this MST branch device2020 * if parent has an LCT of 2 then it has 1 nibble of RAD,2021 * if parent has an LCT of 3 then it has 2 nibbles of RAD,2022 */2023static u8 drm_dp_calculate_rad(struct drm_dp_mst_port *port,2024 u8 *rad)2025{2026 int parent_lct = port->parent->lct;2027 int shift = 4;2028 int idx = (parent_lct - 1) / 2;2029 2030 if (parent_lct > 1) {2031 memcpy(rad, port->parent->rad, idx + 1);2032 shift = (parent_lct % 2) ? 4 : 0;2033 } else2034 rad[0] = 0;2035 2036 rad[idx] |= port->port_num << shift;2037 return parent_lct + 1;2038}2039 2040static bool drm_dp_mst_is_end_device(u8 pdt, bool mcs)2041{2042 switch (pdt) {2043 case DP_PEER_DEVICE_DP_LEGACY_CONV:2044 case DP_PEER_DEVICE_SST_SINK:2045 return true;2046 case DP_PEER_DEVICE_MST_BRANCHING:2047 /* For sst branch device */2048 if (!mcs)2049 return true;2050 2051 return false;2052 }2053 return true;2054}2055 2056static int2057drm_dp_port_set_pdt(struct drm_dp_mst_port *port, u8 new_pdt,2058 bool new_mcs)2059{2060 struct drm_dp_mst_topology_mgr *mgr = port->mgr;2061 struct drm_dp_mst_branch *mstb;2062 u8 rad[8], lct;2063 int ret = 0;2064 2065 if (port->pdt == new_pdt && port->mcs == new_mcs)2066 return 0;2067 2068 /* Teardown the old pdt, if there is one */2069 if (port->pdt != DP_PEER_DEVICE_NONE) {2070 if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) {2071 /*2072 * If the new PDT would also have an i2c bus,2073 * don't bother with reregistering it2074 */2075 if (new_pdt != DP_PEER_DEVICE_NONE &&2076 drm_dp_mst_is_end_device(new_pdt, new_mcs)) {2077 port->pdt = new_pdt;2078 port->mcs = new_mcs;2079 return 0;2080 }2081 2082 /* remove i2c over sideband */2083 drm_dp_mst_unregister_i2c_bus(port);2084 } else {2085 mutex_lock(&mgr->lock);2086 drm_dp_mst_topology_put_mstb(port->mstb);2087 port->mstb = NULL;2088 mutex_unlock(&mgr->lock);2089 }2090 }2091 2092 port->pdt = new_pdt;2093 port->mcs = new_mcs;2094 2095 if (port->pdt != DP_PEER_DEVICE_NONE) {2096 if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) {2097 /* add i2c over sideband */2098 ret = drm_dp_mst_register_i2c_bus(port);2099 } else {2100 lct = drm_dp_calculate_rad(port, rad);2101 mstb = drm_dp_add_mst_branch_device(lct, rad);2102 if (!mstb) {2103 ret = -ENOMEM;2104 drm_err(mgr->dev, "Failed to create MSTB for port %p", port);2105 goto out;2106 }2107 2108 mutex_lock(&mgr->lock);2109 port->mstb = mstb;2110 mstb->mgr = port->mgr;2111 mstb->port_parent = port;2112 2113 /*2114 * Make sure this port's memory allocation stays2115 * around until its child MSTB releases it2116 */2117 drm_dp_mst_get_port_malloc(port);2118 mutex_unlock(&mgr->lock);2119 2120 /* And make sure we send a link address for this */2121 ret = 1;2122 }2123 }2124 2125out:2126 if (ret < 0)2127 port->pdt = DP_PEER_DEVICE_NONE;2128 return ret;2129}2130 2131/**2132 * drm_dp_mst_dpcd_read() - read a series of bytes from the DPCD via sideband2133 * @aux: Fake sideband AUX CH2134 * @offset: address of the (first) register to read2135 * @buffer: buffer to store the register values2136 * @size: number of bytes in @buffer2137 *2138 * Performs the same functionality for remote devices via2139 * sideband messaging as drm_dp_dpcd_read() does for local2140 * devices via actual AUX CH.2141 *2142 * Return: Number of bytes read, or negative error code on failure.2143 */2144ssize_t drm_dp_mst_dpcd_read(struct drm_dp_aux *aux,2145 unsigned int offset, void *buffer, size_t size)2146{2147 struct drm_dp_mst_port *port = container_of(aux, struct drm_dp_mst_port,2148 aux);2149 2150 return drm_dp_send_dpcd_read(port->mgr, port,2151 offset, size, buffer);2152}2153 2154/**2155 * drm_dp_mst_dpcd_write() - write a series of bytes to the DPCD via sideband2156 * @aux: Fake sideband AUX CH2157 * @offset: address of the (first) register to write2158 * @buffer: buffer containing the values to write2159 * @size: number of bytes in @buffer2160 *2161 * Performs the same functionality for remote devices via2162 * sideband messaging as drm_dp_dpcd_write() does for local2163 * devices via actual AUX CH.2164 *2165 * Return: number of bytes written on success, negative error code on failure.2166 */2167ssize_t drm_dp_mst_dpcd_write(struct drm_dp_aux *aux,2168 unsigned int offset, void *buffer, size_t size)2169{2170 struct drm_dp_mst_port *port = container_of(aux, struct drm_dp_mst_port,2171 aux);2172 2173 return drm_dp_send_dpcd_write(port->mgr, port,2174 offset, size, buffer);2175}2176 2177static int drm_dp_check_mstb_guid(struct drm_dp_mst_branch *mstb, guid_t *guid)2178{2179 int ret = 0;2180 2181 guid_copy(&mstb->guid, guid);2182 2183 if (!drm_dp_validate_guid(mstb->mgr, &mstb->guid)) {2184 u8 buf[UUID_SIZE];2185 2186 export_guid(buf, &mstb->guid);2187 2188 if (mstb->port_parent) {2189 ret = drm_dp_send_dpcd_write(mstb->mgr,2190 mstb->port_parent,2191 DP_GUID, sizeof(buf), buf);2192 } else {2193 ret = drm_dp_dpcd_write(mstb->mgr->aux,2194 DP_GUID, buf, sizeof(buf));2195 }2196 }2197 2198 if (ret < 16 && ret > 0)2199 return -EPROTO;2200 2201 return ret == 16 ? 0 : ret;2202}2203 2204static void build_mst_prop_path(const struct drm_dp_mst_branch *mstb,2205 int pnum,2206 char *proppath,2207 size_t proppath_size)2208{2209 int i;2210 char temp[8];2211 2212 snprintf(proppath, proppath_size, "mst:%d", mstb->mgr->conn_base_id);2213 for (i = 0; i < (mstb->lct - 1); i++) {2214 int shift = (i % 2) ? 0 : 4;2215 int port_num = (mstb->rad[i / 2] >> shift) & 0xf;2216 2217 snprintf(temp, sizeof(temp), "-%d", port_num);2218 strlcat(proppath, temp, proppath_size);2219 }2220 snprintf(temp, sizeof(temp), "-%d", pnum);2221 strlcat(proppath, temp, proppath_size);2222}2223 2224/**2225 * drm_dp_mst_connector_late_register() - Late MST connector registration2226 * @connector: The MST connector2227 * @port: The MST port for this connector2228 *2229 * Helper to register the remote aux device for this MST port. Drivers should2230 * call this from their mst connector's late_register hook to enable MST aux2231 * devices.2232 *2233 * Return: 0 on success, negative error code on failure.2234 */2235int drm_dp_mst_connector_late_register(struct drm_connector *connector,2236 struct drm_dp_mst_port *port)2237{2238 drm_dbg_kms(port->mgr->dev, "registering %s remote bus for %s\n",2239 port->aux.name, connector->kdev->kobj.name);2240 2241 port->aux.dev = connector->kdev;2242 return drm_dp_aux_register_devnode(&port->aux);2243}2244EXPORT_SYMBOL(drm_dp_mst_connector_late_register);2245 2246/**2247 * drm_dp_mst_connector_early_unregister() - Early MST connector unregistration2248 * @connector: The MST connector2249 * @port: The MST port for this connector2250 *2251 * Helper to unregister the remote aux device for this MST port, registered by2252 * drm_dp_mst_connector_late_register(). Drivers should call this from their mst2253 * connector's early_unregister hook.2254 */2255void drm_dp_mst_connector_early_unregister(struct drm_connector *connector,2256 struct drm_dp_mst_port *port)2257{2258 drm_dbg_kms(port->mgr->dev, "unregistering %s remote bus for %s\n",2259 port->aux.name, connector->kdev->kobj.name);2260 drm_dp_aux_unregister_devnode(&port->aux);2261}2262EXPORT_SYMBOL(drm_dp_mst_connector_early_unregister);2263 2264static void2265drm_dp_mst_port_add_connector(struct drm_dp_mst_branch *mstb,2266 struct drm_dp_mst_port *port)2267{2268 struct drm_dp_mst_topology_mgr *mgr = port->mgr;2269 char proppath[255];2270 int ret;2271 2272 build_mst_prop_path(mstb, port->port_num, proppath, sizeof(proppath));2273 port->connector = mgr->cbs->add_connector(mgr, port, proppath);2274 if (!port->connector) {2275 ret = -ENOMEM;2276 goto error;2277 }2278 2279 if (port->pdt != DP_PEER_DEVICE_NONE &&2280 drm_dp_mst_is_end_device(port->pdt, port->mcs) &&2281 drm_dp_mst_port_is_logical(port))2282 port->cached_edid = drm_edid_read_ddc(port->connector,2283 &port->aux.ddc);2284 2285 drm_connector_register(port->connector);2286 return;2287 2288error:2289 drm_err(mgr->dev, "Failed to create connector for port %p: %d\n", port, ret);2290}2291 2292/*2293 * Drop a topology reference, and unlink the port from the in-memory topology2294 * layout2295 */2296static void2297drm_dp_mst_topology_unlink_port(struct drm_dp_mst_topology_mgr *mgr,2298 struct drm_dp_mst_port *port)2299{2300 mutex_lock(&mgr->lock);2301 port->parent->num_ports--;2302 list_del(&port->next);2303 mutex_unlock(&mgr->lock);2304 drm_dp_mst_topology_put_port(port);2305}2306 2307static struct drm_dp_mst_port *2308drm_dp_mst_add_port(struct drm_device *dev,2309 struct drm_dp_mst_topology_mgr *mgr,2310 struct drm_dp_mst_branch *mstb, u8 port_number)2311{2312 struct drm_dp_mst_port *port = kzalloc(sizeof(*port), GFP_KERNEL);2313 2314 if (!port)2315 return NULL;2316 2317 kref_init(&port->topology_kref);2318 kref_init(&port->malloc_kref);2319 port->parent = mstb;2320 port->port_num = port_number;2321 port->mgr = mgr;2322 port->aux.name = "DPMST";2323 port->aux.dev = dev->dev;2324 port->aux.is_remote = true;2325 2326 /* initialize the MST downstream port's AUX crc work queue */2327 port->aux.drm_dev = dev;2328 drm_dp_remote_aux_init(&port->aux);2329 2330 /*2331 * Make sure the memory allocation for our parent branch stays2332 * around until our own memory allocation is released2333 */2334 drm_dp_mst_get_mstb_malloc(mstb);2335 2336 return port;2337}2338 2339static int2340drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,2341 struct drm_device *dev,2342 struct drm_dp_link_addr_reply_port *port_msg)2343{2344 struct drm_dp_mst_topology_mgr *mgr = mstb->mgr;2345 struct drm_dp_mst_port *port;2346 int ret;2347 u8 new_pdt = DP_PEER_DEVICE_NONE;2348 bool new_mcs = 0;2349 bool created = false, send_link_addr = false, changed = false;2350 2351 port = drm_dp_get_port(mstb, port_msg->port_number);2352 if (!port) {2353 port = drm_dp_mst_add_port(dev, mgr, mstb,2354 port_msg->port_number);2355 if (!port)2356 return -ENOMEM;2357 created = true;2358 changed = true;2359 } else if (!port->input && port_msg->input_port && port->connector) {2360 /* Since port->connector can't be changed here, we create a2361 * new port if input_port changes from 0 to 12362 */2363 drm_dp_mst_topology_unlink_port(mgr, port);2364 drm_dp_mst_topology_put_port(port);2365 port = drm_dp_mst_add_port(dev, mgr, mstb,2366 port_msg->port_number);2367 if (!port)2368 return -ENOMEM;2369 changed = true;2370 created = true;2371 } else if (port->input && !port_msg->input_port) {2372 changed = true;2373 } else if (port->connector) {2374 /* We're updating a port that's exposed to userspace, so do it2375 * under lock2376 */2377 drm_modeset_lock(&mgr->base.lock, NULL);2378 2379 changed = port->ddps != port_msg->ddps ||2380 (port->ddps &&2381 (port->ldps != port_msg->legacy_device_plug_status ||2382 port->dpcd_rev != port_msg->dpcd_revision ||2383 port->mcs != port_msg->mcs ||2384 port->pdt != port_msg->peer_device_type ||2385 port->num_sdp_stream_sinks !=2386 port_msg->num_sdp_stream_sinks));2387 }2388 2389 port->input = port_msg->input_port;2390 if (!port->input)2391 new_pdt = port_msg->peer_device_type;2392 new_mcs = port_msg->mcs;2393 port->ddps = port_msg->ddps;2394 port->ldps = port_msg->legacy_device_plug_status;2395 port->dpcd_rev = port_msg->dpcd_revision;2396 port->num_sdp_streams = port_msg->num_sdp_streams;2397 port->num_sdp_stream_sinks = port_msg->num_sdp_stream_sinks;2398 2399 /* manage mstb port lists with mgr lock - take a reference2400 for this list */2401 if (created) {2402 mutex_lock(&mgr->lock);2403 drm_dp_mst_topology_get_port(port);2404 list_add(&port->next, &mstb->ports);2405 mstb->num_ports++;2406 mutex_unlock(&mgr->lock);2407 }2408 2409 /*2410 * Reprobe PBN caps on both hotplug, and when re-probing the link2411 * for our parent mstb2412 */2413 if (port->ddps && !port->input) {2414 ret = drm_dp_send_enum_path_resources(mgr, mstb,2415 port);2416 if (ret == 1)2417 changed = true;2418 } else {2419 port->full_pbn = 0;2420 }2421 2422 ret = drm_dp_port_set_pdt(port, new_pdt, new_mcs);2423 if (ret == 1) {2424 send_link_addr = true;2425 } else if (ret < 0) {2426 drm_err(dev, "Failed to change PDT on port %p: %d\n", port, ret);2427 goto fail;2428 }2429 2430 /*2431 * If this port wasn't just created, then we're reprobing because2432 * we're coming out of suspend. In this case, always resend the link2433 * address if there's an MSTB on this port2434 */2435 if (!created && port->pdt == DP_PEER_DEVICE_MST_BRANCHING &&2436 port->mcs)2437 send_link_addr = true;2438 2439 if (port->connector)2440 drm_modeset_unlock(&mgr->base.lock);2441 else if (!port->input)2442 drm_dp_mst_port_add_connector(mstb, port);2443 2444 if (send_link_addr && port->mstb) {2445 ret = drm_dp_send_link_address(mgr, port->mstb);2446 if (ret == 1) /* MSTB below us changed */2447 changed = true;2448 else if (ret < 0)2449 goto fail_put;2450 }2451 2452 /* put reference to this port */2453 drm_dp_mst_topology_put_port(port);2454 return changed;2455 2456fail:2457 drm_dp_mst_topology_unlink_port(mgr, port);2458 if (port->connector)2459 drm_modeset_unlock(&mgr->base.lock);2460fail_put:2461 drm_dp_mst_topology_put_port(port);2462 return ret;2463}2464 2465static int2466drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,2467 struct drm_dp_connection_status_notify *conn_stat)2468{2469 struct drm_dp_mst_topology_mgr *mgr = mstb->mgr;2470 struct drm_dp_mst_port *port;2471 int old_ddps, ret;2472 u8 new_pdt;2473 bool new_mcs;2474 bool dowork = false, create_connector = false;2475 2476 port = drm_dp_get_port(mstb, conn_stat->port_number);2477 if (!port)2478 return 0;2479 2480 if (port->connector) {2481 if (!port->input && conn_stat->input_port) {2482 /*2483 * We can't remove a connector from an already exposed2484 * port, so just throw the port out and make sure we2485 * reprobe the link address of it's parent MSTB2486 */2487 drm_dp_mst_topology_unlink_port(mgr, port);2488 mstb->link_address_sent = false;2489 dowork = true;2490 goto out;2491 }2492 2493 /* Locking is only needed if the port's exposed to userspace */2494 drm_modeset_lock(&mgr->base.lock, NULL);2495 } else if (port->input && !conn_stat->input_port) {2496 create_connector = true;2497 /* Reprobe link address so we get num_sdp_streams */2498 mstb->link_address_sent = false;2499 dowork = true;2500 }2501 2502 old_ddps = port->ddps;2503 port->input = conn_stat->input_port;2504 port->ldps = conn_stat->legacy_device_plug_status;2505 port->ddps = conn_stat->displayport_device_plug_status;2506 2507 if (old_ddps != port->ddps) {2508 if (port->ddps && !port->input)2509 drm_dp_send_enum_path_resources(mgr, mstb, port);2510 else2511 port->full_pbn = 0;2512 }2513 2514 new_pdt = port->input ? DP_PEER_DEVICE_NONE : conn_stat->peer_device_type;2515 new_mcs = conn_stat->message_capability_status;2516 ret = drm_dp_port_set_pdt(port, new_pdt, new_mcs);2517 if (ret == 1) {2518 dowork = true;2519 } else if (ret < 0) {2520 drm_err(mgr->dev, "Failed to change PDT for port %p: %d\n", port, ret);2521 dowork = false;2522 }2523 2524 if (port->connector)2525 drm_modeset_unlock(&mgr->base.lock);2526 else if (create_connector)2527 drm_dp_mst_port_add_connector(mstb, port);2528 2529out:2530 drm_dp_mst_topology_put_port(port);2531 return dowork;2532}2533 2534static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_topology_mgr *mgr,2535 u8 lct, u8 *rad)2536{2537 struct drm_dp_mst_branch *mstb;2538 struct drm_dp_mst_port *port;2539 int i, ret;2540 /* find the port by iterating down */2541 2542 mutex_lock(&mgr->lock);2543 mstb = mgr->mst_primary;2544 2545 if (!mstb)2546 goto out;2547 2548 for (i = 0; i < lct - 1; i++) {2549 int shift = (i % 2) ? 0 : 4;2550 int port_num = (rad[i / 2] >> shift) & 0xf;2551 2552 list_for_each_entry(port, &mstb->ports, next) {2553 if (port->port_num == port_num) {2554 mstb = port->mstb;2555 if (!mstb) {2556 drm_err(mgr->dev,2557 "failed to lookup MSTB with lct %d, rad %02x\n",2558 lct, rad[0]);2559 goto out;2560 }2561 2562 break;2563 }2564 }2565 }2566 ret = drm_dp_mst_topology_try_get_mstb(mstb);2567 if (!ret)2568 mstb = NULL;2569out:2570 mutex_unlock(&mgr->lock);2571 return mstb;2572}2573 2574static struct drm_dp_mst_branch *2575get_mst_branch_device_by_guid_helper(struct drm_dp_mst_branch *mstb,2576 const guid_t *guid)2577{2578 struct drm_dp_mst_branch *found_mstb;2579 struct drm_dp_mst_port *port;2580 2581 if (!mstb)2582 return NULL;2583 2584 if (guid_equal(&mstb->guid, guid))2585 return mstb;2586 2587 list_for_each_entry(port, &mstb->ports, next) {2588 found_mstb = get_mst_branch_device_by_guid_helper(port->mstb, guid);2589 2590 if (found_mstb)2591 return found_mstb;2592 }2593 2594 return NULL;2595}2596 2597static struct drm_dp_mst_branch *2598drm_dp_get_mst_branch_device_by_guid(struct drm_dp_mst_topology_mgr *mgr,2599 const guid_t *guid)2600{2601 struct drm_dp_mst_branch *mstb;2602 int ret;2603 2604 /* find the port by iterating down */2605 mutex_lock(&mgr->lock);2606 2607 mstb = get_mst_branch_device_by_guid_helper(mgr->mst_primary, guid);2608 if (mstb) {2609 ret = drm_dp_mst_topology_try_get_mstb(mstb);2610 if (!ret)2611 mstb = NULL;2612 }2613 2614 mutex_unlock(&mgr->lock);2615 return mstb;2616}2617 2618static int drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *mgr,2619 struct drm_dp_mst_branch *mstb)2620{2621 struct drm_dp_mst_port *port;2622 int ret;2623 bool changed = false;2624 2625 if (!mstb->link_address_sent) {2626 ret = drm_dp_send_link_address(mgr, mstb);2627 if (ret == 1)2628 changed = true;2629 else if (ret < 0)2630 return ret;2631 }2632 2633 list_for_each_entry(port, &mstb->ports, next) {2634 if (port->input || !port->ddps || !port->mstb)2635 continue;2636 2637 ret = drm_dp_check_and_send_link_address(mgr, port->mstb);2638 if (ret == 1)2639 changed = true;2640 else if (ret < 0)2641 return ret;2642 }2643 2644 return changed;2645}2646 2647static void drm_dp_mst_link_probe_work(struct work_struct *work)2648{2649 struct drm_dp_mst_topology_mgr *mgr =2650 container_of(work, struct drm_dp_mst_topology_mgr, work);2651 struct drm_device *dev = mgr->dev;2652 struct drm_dp_mst_branch *mstb;2653 int ret;2654 bool clear_payload_id_table;2655 2656 mutex_lock(&mgr->probe_lock);2657 2658 mutex_lock(&mgr->lock);2659 clear_payload_id_table = !mgr->payload_id_table_cleared;2660 mgr->payload_id_table_cleared = true;2661 2662 mstb = mgr->mst_primary;2663 if (mstb) {2664 ret = drm_dp_mst_topology_try_get_mstb(mstb);2665 if (!ret)2666 mstb = NULL;2667 }2668 mutex_unlock(&mgr->lock);2669 if (!mstb) {2670 mutex_unlock(&mgr->probe_lock);2671 return;2672 }2673 2674 /*2675 * Certain branch devices seem to incorrectly report an available_pbn2676 * of 0 on downstream sinks, even after clearing the2677 * DP_PAYLOAD_ALLOCATE_* registers in2678 * drm_dp_mst_topology_mgr_set_mst(). Namely, the CableMatters USB-C2679 * 2x DP hub. Sending a CLEAR_PAYLOAD_ID_TABLE message seems to make2680 * things work again.2681 */2682 if (clear_payload_id_table) {2683 drm_dbg_kms(dev, "Clearing payload ID table\n");2684 drm_dp_send_clear_payload_id_table(mgr, mstb);2685 }2686 2687 ret = drm_dp_check_and_send_link_address(mgr, mstb);2688 drm_dp_mst_topology_put_mstb(mstb);2689 2690 mutex_unlock(&mgr->probe_lock);2691 if (ret > 0)2692 drm_kms_helper_hotplug_event(dev);2693}2694 2695static void drm_dp_mst_queue_probe_work(struct drm_dp_mst_topology_mgr *mgr)2696{2697 queue_work(system_long_wq, &mgr->work);2698}2699 2700static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr,2701 guid_t *guid)2702{2703 if (!guid_is_null(guid))2704 return true;2705 2706 guid_gen(guid);2707 2708 return false;2709}2710 2711static void build_dpcd_read(struct drm_dp_sideband_msg_tx *msg,2712 u8 port_num, u32 offset, u8 num_bytes)2713{2714 struct drm_dp_sideband_msg_req_body req;2715 2716 req.req_type = DP_REMOTE_DPCD_READ;2717 req.u.dpcd_read.port_number = port_num;2718 req.u.dpcd_read.dpcd_address = offset;2719 req.u.dpcd_read.num_bytes = num_bytes;2720 drm_dp_encode_sideband_req(&req, msg);2721}2722 2723static int drm_dp_send_sideband_msg(struct drm_dp_mst_topology_mgr *mgr,2724 bool up, u8 *msg, int len)2725{2726 int ret;2727 int regbase = up ? DP_SIDEBAND_MSG_UP_REP_BASE : DP_SIDEBAND_MSG_DOWN_REQ_BASE;2728 int tosend, total, offset;2729 int retries = 0;2730 2731retry:2732 total = len;2733 offset = 0;2734 do {2735 tosend = min3(mgr->max_dpcd_transaction_bytes, 16, total);2736 2737 ret = drm_dp_dpcd_write(mgr->aux, regbase + offset,2738 &msg[offset],2739 tosend);2740 if (ret != tosend) {2741 if (ret == -EIO && retries < 5) {2742 retries++;2743 goto retry;2744 }2745 drm_dbg_kms(mgr->dev, "failed to dpcd write %d %d\n", tosend, ret);2746 2747 return -EIO;2748 }2749 offset += tosend;2750 total -= tosend;2751 } while (total > 0);2752 return 0;2753}2754 2755static int set_hdr_from_dst_qlock(struct drm_dp_sideband_msg_hdr *hdr,2756 struct drm_dp_sideband_msg_tx *txmsg)2757{2758 struct drm_dp_mst_branch *mstb = txmsg->dst;2759 u8 req_type;2760 2761 req_type = txmsg->msg[0] & 0x7f;2762 if (req_type == DP_CONNECTION_STATUS_NOTIFY ||2763 req_type == DP_RESOURCE_STATUS_NOTIFY ||2764 req_type == DP_CLEAR_PAYLOAD_ID_TABLE)2765 hdr->broadcast = 1;2766 else2767 hdr->broadcast = 0;2768 hdr->path_msg = txmsg->path_msg;2769 if (hdr->broadcast) {2770 hdr->lct = 1;2771 hdr->lcr = 6;2772 } else {2773 hdr->lct = mstb->lct;2774 hdr->lcr = mstb->lct - 1;2775 }2776 2777 memcpy(hdr->rad, mstb->rad, hdr->lct / 2);2778 2779 return 0;2780}2781/*2782 * process a single block of the next message in the sideband queue2783 */2784static int process_single_tx_qlock(struct drm_dp_mst_topology_mgr *mgr,2785 struct drm_dp_sideband_msg_tx *txmsg,2786 bool up)2787{2788 u8 chunk[48];2789 struct drm_dp_sideband_msg_hdr hdr;2790 int len, space, idx, tosend;2791 int ret;2792 2793 if (txmsg->state == DRM_DP_SIDEBAND_TX_SENT)2794 return 0;2795 2796 memset(&hdr, 0, sizeof(struct drm_dp_sideband_msg_hdr));2797 2798 if (txmsg->state == DRM_DP_SIDEBAND_TX_QUEUED)2799 txmsg->state = DRM_DP_SIDEBAND_TX_START_SEND;2800 2801 /* make hdr from dst mst */2802 ret = set_hdr_from_dst_qlock(&hdr, txmsg);2803 if (ret < 0)2804 return ret;2805 2806 /* amount left to send in this message */2807 len = txmsg->cur_len - txmsg->cur_offset;2808 2809 /* 48 - sideband msg size - 1 byte for data CRC, x header bytes */2810 space = 48 - 1 - drm_dp_calc_sb_hdr_size(&hdr);2811 2812 tosend = min(len, space);2813 if (len == txmsg->cur_len)2814 hdr.somt = 1;2815 if (space >= len)2816 hdr.eomt = 1;2817 2818 2819 hdr.msg_len = tosend + 1;2820 drm_dp_encode_sideband_msg_hdr(&hdr, chunk, &idx);2821 memcpy(&chunk[idx], &txmsg->msg[txmsg->cur_offset], tosend);2822 /* add crc at end */2823 drm_dp_crc_sideband_chunk_req(&chunk[idx], tosend);2824 idx += tosend + 1;2825 2826 ret = drm_dp_send_sideband_msg(mgr, up, chunk, idx);2827 if (ret) {2828 if (drm_debug_enabled(DRM_UT_DP)) {2829 struct drm_printer p = drm_dbg_printer(mgr->dev,2830 DRM_UT_DP,2831 DBG_PREFIX);2832 2833 drm_printf(&p, "sideband msg failed to send\n");2834 drm_dp_mst_dump_sideband_msg_tx(&p, txmsg);2835 }2836 return ret;2837 }2838 2839 txmsg->cur_offset += tosend;2840 if (txmsg->cur_offset == txmsg->cur_len) {2841 txmsg->state = DRM_DP_SIDEBAND_TX_SENT;2842 return 1;2843 }2844 return 0;2845}2846 2847static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr)2848{2849 struct drm_dp_sideband_msg_tx *txmsg;2850 int ret;2851 2852 WARN_ON(!mutex_is_locked(&mgr->qlock));2853 2854 /* construct a chunk from the first msg in the tx_msg queue */2855 if (list_empty(&mgr->tx_msg_downq))2856 return;2857 2858 txmsg = list_first_entry(&mgr->tx_msg_downq,2859 struct drm_dp_sideband_msg_tx, next);2860 ret = process_single_tx_qlock(mgr, txmsg, false);2861 if (ret < 0) {2862 drm_dbg_kms(mgr->dev, "failed to send msg in q %d\n", ret);2863 list_del(&txmsg->next);2864 txmsg->state = DRM_DP_SIDEBAND_TX_TIMEOUT;2865 wake_up_all(&mgr->tx_waitq);2866 }2867}2868 2869static void drm_dp_queue_down_tx(struct drm_dp_mst_topology_mgr *mgr,2870 struct drm_dp_sideband_msg_tx *txmsg)2871{2872 mutex_lock(&mgr->qlock);2873 list_add_tail(&txmsg->next, &mgr->tx_msg_downq);2874 2875 if (drm_debug_enabled(DRM_UT_DP)) {2876 struct drm_printer p = drm_dbg_printer(mgr->dev, DRM_UT_DP,2877 DBG_PREFIX);2878 2879 drm_dp_mst_dump_sideband_msg_tx(&p, txmsg);2880 }2881 2882 if (list_is_singular(&mgr->tx_msg_downq))2883 process_single_down_tx_qlock(mgr);2884 mutex_unlock(&mgr->qlock);2885}2886 2887static void2888drm_dp_dump_link_address(const struct drm_dp_mst_topology_mgr *mgr,2889 struct drm_dp_link_address_ack_reply *reply)2890{2891 struct drm_dp_link_addr_reply_port *port_reply;2892 int i;2893 2894 for (i = 0; i < reply->nports; i++) {2895 port_reply = &reply->ports[i];2896 drm_dbg_kms(mgr->dev,2897 "port %d: input %d, pdt: %d, pn: %d, dpcd_rev: %02x, mcs: %d, ddps: %d, ldps %d, sdp %d/%d\n",2898 i,2899 port_reply->input_port,2900 port_reply->peer_device_type,2901 port_reply->port_number,2902 port_reply->dpcd_revision,2903 port_reply->mcs,2904 port_reply->ddps,2905 port_reply->legacy_device_plug_status,2906 port_reply->num_sdp_streams,2907 port_reply->num_sdp_stream_sinks);2908 }2909}2910 2911static int drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr,2912 struct drm_dp_mst_branch *mstb)2913{2914 struct drm_dp_sideband_msg_tx *txmsg;2915 struct drm_dp_link_address_ack_reply *reply;2916 struct drm_dp_mst_port *port, *tmp;2917 int i, ret, port_mask = 0;2918 bool changed = false;2919 2920 txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);2921 if (!txmsg)2922 return -ENOMEM;2923 2924 txmsg->dst = mstb;2925 build_link_address(txmsg);2926 2927 mstb->link_address_sent = true;2928 drm_dp_queue_down_tx(mgr, txmsg);2929 2930 /* FIXME: Actually do some real error handling here */2931 ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);2932 if (ret < 0) {2933 drm_err(mgr->dev, "Sending link address failed with %d\n", ret);2934 goto out;2935 }2936 if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {2937 drm_err(mgr->dev, "link address NAK received\n");2938 ret = -EIO;2939 goto out;2940 }2941 2942 reply = &txmsg->reply.u.link_addr;2943 drm_dbg_kms(mgr->dev, "link address reply: %d\n", reply->nports);2944 drm_dp_dump_link_address(mgr, reply);2945 2946 ret = drm_dp_check_mstb_guid(mstb, &reply->guid);2947 if (ret) {2948 char buf[64];2949 2950 drm_dp_mst_rad_to_str(mstb->rad, mstb->lct, buf, sizeof(buf));2951 drm_err(mgr->dev, "GUID check on %s failed: %d\n", buf, ret);2952 goto out;2953 }2954 2955 for (i = 0; i < reply->nports; i++) {2956 port_mask |= BIT(reply->ports[i].port_number);2957 ret = drm_dp_mst_handle_link_address_port(mstb, mgr->dev,2958 &reply->ports[i]);2959 if (ret == 1)2960 changed = true;2961 else if (ret < 0)2962 goto out;2963 }2964 2965 /* Prune any ports that are currently a part of mstb in our in-memory2966 * topology, but were not seen in this link address. Usually this2967 * means that they were removed while the topology was out of sync,2968 * e.g. during suspend/resume2969 */2970 mutex_lock(&mgr->lock);2971 list_for_each_entry_safe(port, tmp, &mstb->ports, next) {2972 if (port_mask & BIT(port->port_num))2973 continue;2974 2975 drm_dbg_kms(mgr->dev, "port %d was not in link address, removing\n",2976 port->port_num);2977 list_del(&port->next);2978 drm_dp_mst_topology_put_port(port);2979 changed = true;2980 }2981 mutex_unlock(&mgr->lock);2982 2983out:2984 if (ret < 0)2985 mstb->link_address_sent = false;2986 kfree(txmsg);2987 return ret < 0 ? ret : changed;2988}2989 2990static void2991drm_dp_send_clear_payload_id_table(struct drm_dp_mst_topology_mgr *mgr,2992 struct drm_dp_mst_branch *mstb)2993{2994 struct drm_dp_sideband_msg_tx *txmsg;2995 int ret;2996 2997 txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);2998 if (!txmsg)2999 return;3000 3001 txmsg->dst = mstb;3002 build_clear_payload_id_table(txmsg);3003 3004 drm_dp_queue_down_tx(mgr, txmsg);3005 3006 ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);3007 if (ret > 0 && txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK)3008 drm_dbg_kms(mgr->dev, "clear payload table id nak received\n");3009 3010 kfree(txmsg);3011}3012 3013static int3014drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr,3015 struct drm_dp_mst_branch *mstb,3016 struct drm_dp_mst_port *port)3017{3018 struct drm_dp_enum_path_resources_ack_reply *path_res;3019 struct drm_dp_sideband_msg_tx *txmsg;3020 int ret;3021 3022 txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);3023 if (!txmsg)3024 return -ENOMEM;3025 3026 txmsg->dst = mstb;3027 build_enum_path_resources(txmsg, port->port_num);3028 3029 drm_dp_queue_down_tx(mgr, txmsg);3030 3031 ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);3032 if (ret > 0) {3033 ret = 0;3034 path_res = &txmsg->reply.u.path_resources;3035 3036 if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {3037 drm_dbg_kms(mgr->dev, "enum path resources nak received\n");3038 } else {3039 if (port->port_num != path_res->port_number)3040 DRM_ERROR("got incorrect port in response\n");3041 3042 drm_dbg_kms(mgr->dev, "enum path resources %d: %d %d\n",3043 path_res->port_number,3044 path_res->full_payload_bw_number,3045 path_res->avail_payload_bw_number);3046 3047 /*3048 * If something changed, make sure we send a3049 * hotplug3050 */3051 if (port->full_pbn != path_res->full_payload_bw_number ||3052 port->fec_capable != path_res->fec_capable)3053 ret = 1;3054 3055 port->full_pbn = path_res->full_payload_bw_number;3056 port->fec_capable = path_res->fec_capable;3057 }3058 }3059 3060 kfree(txmsg);3061 return ret;3062}3063 3064static struct drm_dp_mst_port *drm_dp_get_last_connected_port_to_mstb(struct drm_dp_mst_branch *mstb)3065{3066 if (!mstb->port_parent)3067 return NULL;3068 3069 if (mstb->port_parent->mstb != mstb)3070 return mstb->port_parent;3071 3072 return drm_dp_get_last_connected_port_to_mstb(mstb->port_parent->parent);3073}3074 3075/*3076 * Searches upwards in the topology starting from mstb to try to find the3077 * closest available parent of mstb that's still connected to the rest of the3078 * topology. This can be used in order to perform operations like releasing3079 * payloads, where the branch device which owned the payload may no longer be3080 * around and thus would require that the payload on the last living relative3081 * be freed instead.3082 */3083static struct drm_dp_mst_branch *3084drm_dp_get_last_connected_port_and_mstb(struct drm_dp_mst_topology_mgr *mgr,3085 struct drm_dp_mst_branch *mstb,3086 int *port_num)3087{3088 struct drm_dp_mst_branch *rmstb = NULL;3089 struct drm_dp_mst_port *found_port;3090 3091 mutex_lock(&mgr->lock);3092 if (!mgr->mst_primary)3093 goto out;3094 3095 do {3096 found_port = drm_dp_get_last_connected_port_to_mstb(mstb);3097 if (!found_port)3098 break;3099 3100 if (drm_dp_mst_topology_try_get_mstb(found_port->parent)) {3101 rmstb = found_port->parent;3102 *port_num = found_port->port_num;3103 } else {3104 /* Search again, starting from this parent */3105 mstb = found_port->parent;3106 }3107 } while (!rmstb);3108out:3109 mutex_unlock(&mgr->lock);3110 return rmstb;3111}3112 3113static int drm_dp_payload_send_msg(struct drm_dp_mst_topology_mgr *mgr,3114 struct drm_dp_mst_port *port,3115 int id,3116 int pbn)3117{3118 struct drm_dp_sideband_msg_tx *txmsg;3119 struct drm_dp_mst_branch *mstb;3120 int ret, port_num;3121 u8 sinks[DRM_DP_MAX_SDP_STREAMS];3122 int i;3123 3124 port_num = port->port_num;3125 mstb = drm_dp_mst_topology_get_mstb_validated(mgr, port->parent);3126 if (!mstb) {3127 mstb = drm_dp_get_last_connected_port_and_mstb(mgr,3128 port->parent,3129 &port_num);3130 3131 if (!mstb)3132 return -EINVAL;3133 }3134 3135 txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);3136 if (!txmsg) {3137 ret = -ENOMEM;3138 goto fail_put;3139 }3140 3141 for (i = 0; i < port->num_sdp_streams; i++)3142 sinks[i] = i;3143 3144 txmsg->dst = mstb;3145 build_allocate_payload(txmsg, port_num,3146 id,3147 pbn, port->num_sdp_streams, sinks);3148 3149 drm_dp_queue_down_tx(mgr, txmsg);3150 3151 /*3152 * FIXME: there is a small chance that between getting the last3153 * connected mstb and sending the payload message, the last connected3154 * mstb could also be removed from the topology. In the future, this3155 * needs to be fixed by restarting the3156 * drm_dp_get_last_connected_port_and_mstb() search in the event of a3157 * timeout if the topology is still connected to the system.3158 */3159 ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);3160 if (ret > 0) {3161 if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK)3162 ret = -EINVAL;3163 else3164 ret = 0;3165 }3166 kfree(txmsg);3167fail_put:3168 drm_dp_mst_topology_put_mstb(mstb);3169 return ret;3170}3171 3172int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,3173 struct drm_dp_mst_port *port, bool power_up)3174{3175 struct drm_dp_sideband_msg_tx *txmsg;3176 int ret;3177 3178 port = drm_dp_mst_topology_get_port_validated(mgr, port);3179 if (!port)3180 return -EINVAL;3181 3182 txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);3183 if (!txmsg) {3184 drm_dp_mst_topology_put_port(port);3185 return -ENOMEM;3186 }3187 3188 txmsg->dst = port->parent;3189 build_power_updown_phy(txmsg, port->port_num, power_up);3190 drm_dp_queue_down_tx(mgr, txmsg);3191 3192 ret = drm_dp_mst_wait_tx_reply(port->parent, txmsg);3193 if (ret > 0) {3194 if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK)3195 ret = -EINVAL;3196 else3197 ret = 0;3198 }3199 kfree(txmsg);3200 drm_dp_mst_topology_put_port(port);3201 3202 return ret;3203}3204EXPORT_SYMBOL(drm_dp_send_power_updown_phy);3205 3206int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,3207 struct drm_dp_mst_port *port,3208 struct drm_dp_query_stream_enc_status_ack_reply *status)3209{3210 struct drm_dp_mst_topology_state *state;3211 struct drm_dp_mst_atomic_payload *payload;3212 struct drm_dp_sideband_msg_tx *txmsg;3213 u8 nonce[7];3214 int ret;3215 3216 txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);3217 if (!txmsg)3218 return -ENOMEM;3219 3220 port = drm_dp_mst_topology_get_port_validated(mgr, port);3221 if (!port) {3222 ret = -EINVAL;3223 goto out_get_port;3224 }3225 3226 get_random_bytes(nonce, sizeof(nonce));3227 3228 drm_modeset_lock(&mgr->base.lock, NULL);3229 state = to_drm_dp_mst_topology_state(mgr->base.state);3230 payload = drm_atomic_get_mst_payload_state(state, port);3231 3232 /*3233 * "Source device targets the QUERY_STREAM_ENCRYPTION_STATUS message3234 * transaction at the MST Branch device directly connected to the3235 * Source"3236 */3237 txmsg->dst = mgr->mst_primary;3238 3239 build_query_stream_enc_status(txmsg, payload->vcpi, nonce);3240 3241 drm_dp_queue_down_tx(mgr, txmsg);3242 3243 ret = drm_dp_mst_wait_tx_reply(mgr->mst_primary, txmsg);3244 if (ret < 0) {3245 goto out;3246 } else if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {3247 drm_dbg_kms(mgr->dev, "query encryption status nak received\n");3248 ret = -ENXIO;3249 goto out;3250 }3251 3252 ret = 0;3253 memcpy(status, &txmsg->reply.u.enc_status, sizeof(*status));3254 3255out:3256 drm_modeset_unlock(&mgr->base.lock);3257 drm_dp_mst_topology_put_port(port);3258out_get_port:3259 kfree(txmsg);3260 return ret;3261}3262EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status);3263 3264static int drm_dp_create_payload_at_dfp(struct drm_dp_mst_topology_mgr *mgr,3265 struct drm_dp_mst_atomic_payload *payload)3266{3267 return drm_dp_dpcd_write_payload(mgr, payload->vcpi, payload->vc_start_slot,3268 payload->time_slots);3269}3270 3271static int drm_dp_create_payload_to_remote(struct drm_dp_mst_topology_mgr *mgr,3272 struct drm_dp_mst_atomic_payload *payload)3273{3274 int ret;3275 struct drm_dp_mst_port *port = drm_dp_mst_topology_get_port_validated(mgr, payload->port);3276 3277 if (!port)3278 return -EIO;3279 3280 ret = drm_dp_payload_send_msg(mgr, port, payload->vcpi, payload->pbn);3281 drm_dp_mst_topology_put_port(port);3282 return ret;3283}3284 3285static void drm_dp_destroy_payload_at_remote_and_dfp(struct drm_dp_mst_topology_mgr *mgr,3286 struct drm_dp_mst_topology_state *mst_state,3287 struct drm_dp_mst_atomic_payload *payload)3288{3289 drm_dbg_kms(mgr->dev, "\n");3290 3291 /* it's okay for these to fail */3292 if (payload->payload_allocation_status == DRM_DP_MST_PAYLOAD_ALLOCATION_REMOTE) {3293 drm_dp_payload_send_msg(mgr, payload->port, payload->vcpi, 0);3294 payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_DFP;3295 }3296 3297 if (payload->payload_allocation_status == DRM_DP_MST_PAYLOAD_ALLOCATION_DFP)3298 drm_dp_dpcd_write_payload(mgr, payload->vcpi, payload->vc_start_slot, 0);3299}3300 3301/**3302 * drm_dp_add_payload_part1() - Execute payload update part 13303 * @mgr: Manager to use.3304 * @mst_state: The MST atomic state3305 * @payload: The payload to write3306 *3307 * Determines the starting time slot for the given payload, and programs the VCPI for this payload3308 * into the DPCD of DPRX. After calling this, the driver should generate ACT and payload packets.3309 *3310 * Returns: 0 on success, error code on failure.3311 */3312int drm_dp_add_payload_part1(struct drm_dp_mst_topology_mgr *mgr,3313 struct drm_dp_mst_topology_state *mst_state,3314 struct drm_dp_mst_atomic_payload *payload)3315{3316 struct drm_dp_mst_port *port;3317 int ret;3318 3319 /* Update mst mgr info */3320 if (mgr->payload_count == 0)3321 mgr->next_start_slot = mst_state->start_slot;3322 3323 payload->vc_start_slot = mgr->next_start_slot;3324 3325 mgr->payload_count++;3326 mgr->next_start_slot += payload->time_slots;3327 3328 payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_LOCAL;3329 3330 /* Allocate payload to immediate downstream facing port */3331 port = drm_dp_mst_topology_get_port_validated(mgr, payload->port);3332 if (!port) {3333 drm_dbg_kms(mgr->dev,3334 "VCPI %d for port %p not in topology, not creating a payload to remote\n",3335 payload->vcpi, payload->port);3336 return -EIO;3337 }3338 3339 ret = drm_dp_create_payload_at_dfp(mgr, payload);3340 if (ret < 0) {3341 drm_dbg_kms(mgr->dev, "Failed to create MST payload for port %p: %d\n",3342 payload->port, ret);3343 goto put_port;3344 }3345 3346 payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_DFP;3347 3348put_port:3349 drm_dp_mst_topology_put_port(port);3350 3351 return ret;3352}3353EXPORT_SYMBOL(drm_dp_add_payload_part1);3354 3355/**3356 * drm_dp_remove_payload_part1() - Remove an MST payload along the virtual channel3357 * @mgr: Manager to use.3358 * @mst_state: The MST atomic state3359 * @payload: The payload to remove3360 *3361 * Removes a payload along the virtual channel if it was successfully allocated.3362 * After calling this, the driver should set HW to generate ACT and then switch to new3363 * payload allocation state.3364 */3365void drm_dp_remove_payload_part1(struct drm_dp_mst_topology_mgr *mgr,3366 struct drm_dp_mst_topology_state *mst_state,3367 struct drm_dp_mst_atomic_payload *payload)3368{3369 /* Remove remote payload allocation */3370 bool send_remove = false;3371 3372 mutex_lock(&mgr->lock);3373 send_remove = drm_dp_mst_port_downstream_of_branch(payload->port, mgr->mst_primary);3374 mutex_unlock(&mgr->lock);3375 3376 if (send_remove)3377 drm_dp_destroy_payload_at_remote_and_dfp(mgr, mst_state, payload);3378 else3379 drm_dbg_kms(mgr->dev, "Payload for VCPI %d not in topology, not sending remove\n",3380 payload->vcpi);3381 3382 payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_LOCAL;3383}3384EXPORT_SYMBOL(drm_dp_remove_payload_part1);3385 3386/**3387 * drm_dp_remove_payload_part2() - Remove an MST payload locally3388 * @mgr: Manager to use.3389 * @mst_state: The MST atomic state3390 * @old_payload: The payload with its old state3391 * @new_payload: The payload with its latest state3392 *3393 * Updates the starting time slots of all other payloads which would have been shifted towards3394 * the start of the payload ID table as a result of removing a payload. Driver should call this3395 * function whenever it removes a payload in its HW. It's independent to the result of payload3396 * allocation/deallocation at branch devices along the virtual channel.3397 */3398void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,3399 struct drm_dp_mst_topology_state *mst_state,3400 const struct drm_dp_mst_atomic_payload *old_payload,3401 struct drm_dp_mst_atomic_payload *new_payload)3402{3403 struct drm_dp_mst_atomic_payload *pos;3404 3405 /* Remove local payload allocation */3406 list_for_each_entry(pos, &mst_state->payloads, next) {3407 if (pos != new_payload && pos->vc_start_slot > new_payload->vc_start_slot)3408 pos->vc_start_slot -= old_payload->time_slots;3409 }3410 new_payload->vc_start_slot = -1;3411 3412 mgr->payload_count--;3413 mgr->next_start_slot -= old_payload->time_slots;3414 3415 if (new_payload->delete)3416 drm_dp_mst_put_port_malloc(new_payload->port);3417 3418 new_payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;3419}3420EXPORT_SYMBOL(drm_dp_remove_payload_part2);3421/**3422 * drm_dp_add_payload_part2() - Execute payload update part 23423 * @mgr: Manager to use.3424 * @payload: The payload to update3425 *3426 * If @payload was successfully assigned a starting time slot by drm_dp_add_payload_part1(), this3427 * function will send the sideband messages to finish allocating this payload.3428 *3429 * Returns: 0 on success, negative error code on failure.3430 */3431int drm_dp_add_payload_part2(struct drm_dp_mst_topology_mgr *mgr,3432 struct drm_dp_mst_atomic_payload *payload)3433{3434 int ret = 0;3435 3436 /* Skip failed payloads */3437 if (payload->payload_allocation_status != DRM_DP_MST_PAYLOAD_ALLOCATION_DFP) {3438 drm_dbg_kms(mgr->dev, "Part 1 of payload creation for %s failed, skipping part 2\n",3439 payload->port->connector->name);3440 return -EIO;3441 }3442 3443 /* Allocate payload to remote end */3444 ret = drm_dp_create_payload_to_remote(mgr, payload);3445 if (ret < 0)3446 drm_err(mgr->dev, "Step 2 of creating MST payload for %p failed: %d\n",3447 payload->port, ret);3448 else3449 payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_REMOTE;3450 3451 return ret;3452}3453EXPORT_SYMBOL(drm_dp_add_payload_part2);3454 3455static int drm_dp_send_dpcd_read(struct drm_dp_mst_topology_mgr *mgr,3456 struct drm_dp_mst_port *port,3457 int offset, int size, u8 *bytes)3458{3459 int ret = 0;3460 struct drm_dp_sideband_msg_tx *txmsg;3461 struct drm_dp_mst_branch *mstb;3462 3463 mstb = drm_dp_mst_topology_get_mstb_validated(mgr, port->parent);3464 if (!mstb)3465 return -EINVAL;3466 3467 txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);3468 if (!txmsg) {3469 ret = -ENOMEM;3470 goto fail_put;3471 }3472 3473 build_dpcd_read(txmsg, port->port_num, offset, size);3474 txmsg->dst = port->parent;3475 3476 drm_dp_queue_down_tx(mgr, txmsg);3477 3478 ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);3479 if (ret < 0)3480 goto fail_free;3481 3482 if (txmsg->reply.reply_type == 1) {3483 drm_dbg_kms(mgr->dev, "mstb %p port %d: DPCD read on addr 0x%x for %d bytes NAKed\n",3484 mstb, port->port_num, offset, size);3485 ret = -EIO;3486 goto fail_free;3487 }3488 3489 if (txmsg->reply.u.remote_dpcd_read_ack.num_bytes != size) {3490 ret = -EPROTO;3491 goto fail_free;3492 }3493 3494 ret = min_t(size_t, txmsg->reply.u.remote_dpcd_read_ack.num_bytes,3495 size);3496 memcpy(bytes, txmsg->reply.u.remote_dpcd_read_ack.bytes, ret);3497 3498fail_free:3499 kfree(txmsg);3500fail_put:3501 drm_dp_mst_topology_put_mstb(mstb);3502 3503 return ret;3504}3505 3506static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr,3507 struct drm_dp_mst_port *port,3508 int offset, int size, u8 *bytes)3509{3510 int ret;3511 struct drm_dp_sideband_msg_tx *txmsg;3512 struct drm_dp_mst_branch *mstb;3513 3514 mstb = drm_dp_mst_topology_get_mstb_validated(mgr, port->parent);3515 if (!mstb)3516 return -EINVAL;3517 3518 txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);3519 if (!txmsg) {3520 ret = -ENOMEM;3521 goto fail_put;3522 }3523 3524 build_dpcd_write(txmsg, port->port_num, offset, size, bytes);3525 txmsg->dst = mstb;3526 3527 drm_dp_queue_down_tx(mgr, txmsg);3528 3529 ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);3530 if (ret > 0) {3531 if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK)3532 ret = -EIO;3533 else3534 ret = size;3535 }3536 3537 kfree(txmsg);3538fail_put:3539 drm_dp_mst_topology_put_mstb(mstb);3540 return ret;3541}3542 3543static int drm_dp_encode_up_ack_reply(struct drm_dp_sideband_msg_tx *msg, u8 req_type)3544{3545 struct drm_dp_sideband_msg_reply_body reply;3546 3547 reply.reply_type = DP_SIDEBAND_REPLY_ACK;3548 reply.req_type = req_type;3549 drm_dp_encode_sideband_reply(&reply, msg);3550 return 0;3551}3552 3553static int drm_dp_send_up_ack_reply(struct drm_dp_mst_topology_mgr *mgr,3554 struct drm_dp_mst_branch *mstb,3555 int req_type, bool broadcast)3556{3557 struct drm_dp_sideband_msg_tx *txmsg;3558 3559 txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);3560 if (!txmsg)3561 return -ENOMEM;3562 3563 txmsg->dst = mstb;3564 drm_dp_encode_up_ack_reply(txmsg, req_type);3565 3566 mutex_lock(&mgr->qlock);3567 /* construct a chunk from the first msg in the tx_msg queue */3568 process_single_tx_qlock(mgr, txmsg, true);3569 mutex_unlock(&mgr->qlock);3570 3571 kfree(txmsg);3572 return 0;3573}3574 3575/**3576 * drm_dp_get_vc_payload_bw - get the VC payload BW for an MST link3577 * @mgr: The &drm_dp_mst_topology_mgr to use3578 * @link_rate: link rate in 10kbits/s units3579 * @link_lane_count: lane count3580 *3581 * Calculate the total bandwidth of a MultiStream Transport link. The returned3582 * value is in units of PBNs/(timeslots/1 MTP). This value can be used to3583 * convert the number of PBNs required for a given stream to the number of3584 * timeslots this stream requires in each MTP.3585 *3586 * Returns the BW / timeslot value in 20.12 fixed point format.3587 */3588fixed20_12 drm_dp_get_vc_payload_bw(const struct drm_dp_mst_topology_mgr *mgr,3589 int link_rate, int link_lane_count)3590{3591 int ch_coding_efficiency =3592 drm_dp_bw_channel_coding_efficiency(drm_dp_is_uhbr_rate(link_rate));3593 fixed20_12 ret;3594 3595 if (link_rate == 0 || link_lane_count == 0)3596 drm_dbg_kms(mgr->dev, "invalid link rate/lane count: (%d / %d)\n",3597 link_rate, link_lane_count);3598 3599 /* See DP v2.0 2.6.4.2, 2.7.6.3 VCPayload_Bandwidth_for_OneTimeSlotPer_MTP_Allocation */3600 ret.full = DIV_ROUND_DOWN_ULL(mul_u32_u32(link_rate * link_lane_count,3601 ch_coding_efficiency),3602 (1000000ULL * 8 * 5400) >> 12);3603 3604 return ret;3605}3606EXPORT_SYMBOL(drm_dp_get_vc_payload_bw);3607 3608/**3609 * drm_dp_read_mst_cap() - Read the sink's MST mode capability3610 * @aux: The DP AUX channel to use3611 * @dpcd: A cached copy of the DPCD capabilities for this sink3612 *3613 * Returns: enum drm_dp_mst_mode to indicate MST mode capability3614 */3615enum drm_dp_mst_mode drm_dp_read_mst_cap(struct drm_dp_aux *aux,3616 const u8 dpcd[DP_RECEIVER_CAP_SIZE])3617{3618 u8 mstm_cap;3619 3620 if (dpcd[DP_DPCD_REV] < DP_DPCD_REV_12)3621 return DRM_DP_SST;3622 3623 if (drm_dp_dpcd_readb(aux, DP_MSTM_CAP, &mstm_cap) != 1)3624 return DRM_DP_SST;3625 3626 if (mstm_cap & DP_MST_CAP)3627 return DRM_DP_MST;3628 3629 if (mstm_cap & DP_SINGLE_STREAM_SIDEBAND_MSG)3630 return DRM_DP_SST_SIDEBAND_MSG;3631 3632 return DRM_DP_SST;3633}3634EXPORT_SYMBOL(drm_dp_read_mst_cap);3635 3636/**3637 * drm_dp_mst_topology_mgr_set_mst() - Set the MST state for a topology manager3638 * @mgr: manager to set state for3639 * @mst_state: true to enable MST on this connector - false to disable.3640 *3641 * This is called by the driver when it detects an MST capable device plugged3642 * into a DP MST capable port, or when a DP MST capable device is unplugged.3643 */3644int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool mst_state)3645{3646 int ret = 0;3647 struct drm_dp_mst_branch *mstb = NULL;3648 3649 mutex_lock(&mgr->lock);3650 if (mst_state == mgr->mst_state)3651 goto out_unlock;3652 3653 mgr->mst_state = mst_state;3654 /* set the device into MST mode */3655 if (mst_state) {3656 WARN_ON(mgr->mst_primary);3657 3658 /* get dpcd info */3659 ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd);3660 if (ret < 0) {3661 drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret %d\n",3662 mgr->aux->name, ret);3663 goto out_unlock;3664 }3665 3666 /* add initial branch device at LCT 1 */3667 mstb = drm_dp_add_mst_branch_device(1, NULL);3668 if (mstb == NULL) {3669 ret = -ENOMEM;3670 goto out_unlock;3671 }3672 mstb->mgr = mgr;3673 3674 /* give this the main reference */3675 mgr->mst_primary = mstb;3676 drm_dp_mst_topology_get_mstb(mgr->mst_primary);3677 3678 ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,3679 DP_MST_EN |3680 DP_UP_REQ_EN |3681 DP_UPSTREAM_IS_SRC);3682 if (ret < 0)3683 goto out_unlock;3684 3685 /* Write reset payload */3686 drm_dp_dpcd_write_payload(mgr, 0, 0, 0x3f);3687 3688 drm_dp_mst_queue_probe_work(mgr);3689 3690 ret = 0;3691 } else {3692 /* disable MST on the device */3693 mstb = mgr->mst_primary;3694 mgr->mst_primary = NULL;3695 /* this can fail if the device is gone */3696 drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL, 0);3697 ret = 0;3698 mgr->payload_id_table_cleared = false;3699 3700 memset(&mgr->down_rep_recv, 0, sizeof(mgr->down_rep_recv));3701 memset(&mgr->up_req_recv, 0, sizeof(mgr->up_req_recv));3702 }3703 3704out_unlock:3705 mutex_unlock(&mgr->lock);3706 if (mstb)3707 drm_dp_mst_topology_put_mstb(mstb);3708 return ret;3709 3710}3711EXPORT_SYMBOL(drm_dp_mst_topology_mgr_set_mst);3712 3713static void3714drm_dp_mst_topology_mgr_invalidate_mstb(struct drm_dp_mst_branch *mstb)3715{3716 struct drm_dp_mst_port *port;3717 3718 /* The link address will need to be re-sent on resume */3719 mstb->link_address_sent = false;3720 3721 list_for_each_entry(port, &mstb->ports, next)3722 if (port->mstb)3723 drm_dp_mst_topology_mgr_invalidate_mstb(port->mstb);3724}3725 3726/**3727 * drm_dp_mst_topology_queue_probe - Queue a topology probe3728 * @mgr: manager to probe3729 *3730 * Queue a work to probe the MST topology. Driver's should call this only to3731 * sync the topology's HW->SW state after the MST link's parameters have3732 * changed in a way the state could've become out-of-sync. This is the case3733 * for instance when the link rate between the source and first downstream3734 * branch device has switched between UHBR and non-UHBR rates. Except of those3735 * cases - for instance when a sink gets plugged/unplugged to a port - the SW3736 * state will get updated automatically via MST UP message notifications.3737 */3738void drm_dp_mst_topology_queue_probe(struct drm_dp_mst_topology_mgr *mgr)3739{3740 mutex_lock(&mgr->lock);3741 3742 if (drm_WARN_ON(mgr->dev, !mgr->mst_state || !mgr->mst_primary))3743 goto out_unlock;3744 3745 drm_dp_mst_topology_mgr_invalidate_mstb(mgr->mst_primary);3746 drm_dp_mst_queue_probe_work(mgr);3747 3748out_unlock:3749 mutex_unlock(&mgr->lock);3750}3751EXPORT_SYMBOL(drm_dp_mst_topology_queue_probe);3752 3753/**3754 * drm_dp_mst_topology_mgr_suspend() - suspend the MST manager3755 * @mgr: manager to suspend3756 *3757 * This function tells the MST device that we can't handle UP messages3758 * anymore. This should stop it from sending any since we are suspended.3759 */3760void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr)3761{3762 mutex_lock(&mgr->lock);3763 drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,3764 DP_MST_EN | DP_UPSTREAM_IS_SRC);3765 mutex_unlock(&mgr->lock);3766 flush_work(&mgr->up_req_work);3767 flush_work(&mgr->work);3768 flush_work(&mgr->delayed_destroy_work);3769 3770 mutex_lock(&mgr->lock);3771 if (mgr->mst_state && mgr->mst_primary)3772 drm_dp_mst_topology_mgr_invalidate_mstb(mgr->mst_primary);3773 mutex_unlock(&mgr->lock);3774}3775EXPORT_SYMBOL(drm_dp_mst_topology_mgr_suspend);3776 3777/**3778 * drm_dp_mst_topology_mgr_resume() - resume the MST manager3779 * @mgr: manager to resume3780 * @sync: whether or not to perform topology reprobing synchronously3781 *3782 * This will fetch DPCD and see if the device is still there,3783 * if it is, it will rewrite the MSTM control bits, and return.3784 *3785 * If the device fails this returns -1, and the driver should do3786 * a full MST reprobe, in case we were undocked.3787 *3788 * During system resume (where it is assumed that the driver will be calling3789 * drm_atomic_helper_resume()) this function should be called beforehand with3790 * @sync set to true. In contexts like runtime resume where the driver is not3791 * expected to be calling drm_atomic_helper_resume(), this function should be3792 * called with @sync set to false in order to avoid deadlocking.3793 *3794 * Returns: -1 if the MST topology was removed while we were suspended, 03795 * otherwise.3796 */3797int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr,3798 bool sync)3799{3800 u8 buf[UUID_SIZE];3801 guid_t guid;3802 int ret;3803 3804 mutex_lock(&mgr->lock);3805 if (!mgr->mst_primary)3806 goto out_fail;3807 3808 if (drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd) < 0) {3809 drm_dbg_kms(mgr->dev, "dpcd read failed - undocked during suspend?\n");3810 goto out_fail;3811 }3812 3813 ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,3814 DP_MST_EN |3815 DP_UP_REQ_EN |3816 DP_UPSTREAM_IS_SRC);3817 if (ret < 0) {3818 drm_dbg_kms(mgr->dev, "mst write failed - undocked during suspend?\n");3819 goto out_fail;3820 }3821 3822 /* Some hubs forget their guids after they resume */3823 ret = drm_dp_dpcd_read(mgr->aux, DP_GUID, buf, sizeof(buf));3824 if (ret != sizeof(buf)) {3825 drm_dbg_kms(mgr->dev, "dpcd read failed - undocked during suspend?\n");3826 goto out_fail;3827 }3828 3829 import_guid(&guid, buf);3830 3831 ret = drm_dp_check_mstb_guid(mgr->mst_primary, &guid);3832 if (ret) {3833 drm_dbg_kms(mgr->dev, "check mstb failed - undocked during suspend?\n");3834 goto out_fail;3835 }3836 3837 /*3838 * For the final step of resuming the topology, we need to bring the3839 * state of our in-memory topology back into sync with reality. So,3840 * restart the probing process as if we're probing a new hub3841 */3842 drm_dp_mst_queue_probe_work(mgr);3843 mutex_unlock(&mgr->lock);3844 3845 if (sync) {3846 drm_dbg_kms(mgr->dev,3847 "Waiting for link probe work to finish re-syncing topology...\n");3848 flush_work(&mgr->work);3849 }3850 3851 return 0;3852 3853out_fail:3854 mutex_unlock(&mgr->lock);3855 return -1;3856}3857EXPORT_SYMBOL(drm_dp_mst_topology_mgr_resume);3858 3859static bool3860drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up,3861 struct drm_dp_mst_branch **mstb)3862{3863 int len;3864 u8 replyblock[32];3865 int replylen, curreply;3866 int ret;3867 u8 hdrlen;3868 struct drm_dp_sideband_msg_hdr hdr;3869 struct drm_dp_sideband_msg_rx *msg =3870 up ? &mgr->up_req_recv : &mgr->down_rep_recv;3871 int basereg = up ? DP_SIDEBAND_MSG_UP_REQ_BASE :3872 DP_SIDEBAND_MSG_DOWN_REP_BASE;3873 3874 if (!up)3875 *mstb = NULL;3876 3877 len = min(mgr->max_dpcd_transaction_bytes, 16);3878 ret = drm_dp_dpcd_read(mgr->aux, basereg, replyblock, len);3879 if (ret != len) {3880 drm_dbg_kms(mgr->dev, "failed to read DPCD down rep %d %d\n", len, ret);3881 return false;3882 }3883 3884 ret = drm_dp_decode_sideband_msg_hdr(mgr, &hdr, replyblock, len, &hdrlen);3885 if (ret == false) {3886 print_hex_dump(KERN_DEBUG, "failed hdr", DUMP_PREFIX_NONE, 16,3887 1, replyblock, len, false);3888 drm_dbg_kms(mgr->dev, "ERROR: failed header\n");3889 return false;3890 }3891 3892 if (!up) {3893 /* Caller is responsible for giving back this reference */3894 *mstb = drm_dp_get_mst_branch_device(mgr, hdr.lct, hdr.rad);3895 if (!*mstb) {3896 drm_dbg_kms(mgr->dev, "Got MST reply from unknown device %d\n", hdr.lct);3897 return false;3898 }3899 }3900 3901 if (!drm_dp_sideband_msg_set_header(msg, &hdr, hdrlen)) {3902 drm_dbg_kms(mgr->dev, "sideband msg set header failed %d\n", replyblock[0]);3903 return false;3904 }3905 3906 replylen = min(msg->curchunk_len, (u8)(len - hdrlen));3907 ret = drm_dp_sideband_append_payload(msg, replyblock + hdrlen, replylen);3908 if (!ret) {3909 drm_dbg_kms(mgr->dev, "sideband msg build failed %d\n", replyblock[0]);3910 return false;3911 }3912 3913 replylen = msg->curchunk_len + msg->curchunk_hdrlen - len;3914 curreply = len;3915 while (replylen > 0) {3916 len = min3(replylen, mgr->max_dpcd_transaction_bytes, 16);3917 ret = drm_dp_dpcd_read(mgr->aux, basereg + curreply,3918 replyblock, len);3919 if (ret != len) {3920 drm_dbg_kms(mgr->dev, "failed to read a chunk (len %d, ret %d)\n",3921 len, ret);3922 return false;3923 }3924 3925 ret = drm_dp_sideband_append_payload(msg, replyblock, len);3926 if (!ret) {3927 drm_dbg_kms(mgr->dev, "failed to build sideband msg\n");3928 return false;3929 }3930 3931 curreply += len;3932 replylen -= len;3933 }3934 return true;3935}3936 3937static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)3938{3939 struct drm_dp_sideband_msg_tx *txmsg;3940 struct drm_dp_mst_branch *mstb = NULL;3941 struct drm_dp_sideband_msg_rx *msg = &mgr->down_rep_recv;3942 3943 if (!drm_dp_get_one_sb_msg(mgr, false, &mstb))3944 goto out_clear_reply;3945 3946 /* Multi-packet message transmission, don't clear the reply */3947 if (!msg->have_eomt)3948 goto out;3949 3950 /* find the message */3951 mutex_lock(&mgr->qlock);3952 txmsg = list_first_entry_or_null(&mgr->tx_msg_downq,3953 struct drm_dp_sideband_msg_tx, next);3954 mutex_unlock(&mgr->qlock);3955 3956 /* Were we actually expecting a response, and from this mstb? */3957 if (!txmsg || txmsg->dst != mstb) {3958 struct drm_dp_sideband_msg_hdr *hdr;3959 3960 hdr = &msg->initial_hdr;3961 drm_dbg_kms(mgr->dev, "Got MST reply with no msg %p %d %d %02x %02x\n",3962 mstb, hdr->seqno, hdr->lct, hdr->rad[0], msg->msg[0]);3963 goto out_clear_reply;3964 }3965 3966 drm_dp_sideband_parse_reply(mgr, msg, &txmsg->reply);3967 3968 if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {3969 drm_dbg_kms(mgr->dev,3970 "Got NAK reply: req 0x%02x (%s), reason 0x%02x (%s), nak data 0x%02x\n",3971 txmsg->reply.req_type,3972 drm_dp_mst_req_type_str(txmsg->reply.req_type),3973 txmsg->reply.u.nak.reason,3974 drm_dp_mst_nak_reason_str(txmsg->reply.u.nak.reason),3975 txmsg->reply.u.nak.nak_data);3976 }3977 3978 memset(msg, 0, sizeof(struct drm_dp_sideband_msg_rx));3979 drm_dp_mst_topology_put_mstb(mstb);3980 3981 mutex_lock(&mgr->qlock);3982 txmsg->state = DRM_DP_SIDEBAND_TX_RX;3983 list_del(&txmsg->next);3984 mutex_unlock(&mgr->qlock);3985 3986 wake_up_all(&mgr->tx_waitq);3987 3988 return 0;3989 3990out_clear_reply:3991 memset(msg, 0, sizeof(struct drm_dp_sideband_msg_rx));3992out:3993 if (mstb)3994 drm_dp_mst_topology_put_mstb(mstb);3995 3996 return 0;3997}3998 3999static inline bool4000drm_dp_mst_process_up_req(struct drm_dp_mst_topology_mgr *mgr,4001 struct drm_dp_pending_up_req *up_req)4002{4003 struct drm_dp_mst_branch *mstb = NULL;4004 struct drm_dp_sideband_msg_req_body *msg = &up_req->msg;4005 struct drm_dp_sideband_msg_hdr *hdr = &up_req->hdr;4006 bool hotplug = false, dowork = false;4007 4008 if (hdr->broadcast) {4009 const guid_t *guid = NULL;4010 4011 if (msg->req_type == DP_CONNECTION_STATUS_NOTIFY)4012 guid = &msg->u.conn_stat.guid;4013 else if (msg->req_type == DP_RESOURCE_STATUS_NOTIFY)4014 guid = &msg->u.resource_stat.guid;4015 4016 if (guid)4017 mstb = drm_dp_get_mst_branch_device_by_guid(mgr, guid);4018 } else {4019 mstb = drm_dp_get_mst_branch_device(mgr, hdr->lct, hdr->rad);4020 }4021 4022 if (!mstb) {4023 drm_dbg_kms(mgr->dev, "Got MST reply from unknown device %d\n", hdr->lct);4024 return false;4025 }4026 4027 /* TODO: Add missing handler for DP_RESOURCE_STATUS_NOTIFY events */4028 if (msg->req_type == DP_CONNECTION_STATUS_NOTIFY) {4029 dowork = drm_dp_mst_handle_conn_stat(mstb, &msg->u.conn_stat);4030 hotplug = true;4031 }4032 4033 drm_dp_mst_topology_put_mstb(mstb);4034 4035 if (dowork)4036 queue_work(system_long_wq, &mgr->work);4037 return hotplug;4038}4039 4040static void drm_dp_mst_up_req_work(struct work_struct *work)4041{4042 struct drm_dp_mst_topology_mgr *mgr =4043 container_of(work, struct drm_dp_mst_topology_mgr,4044 up_req_work);4045 struct drm_dp_pending_up_req *up_req;4046 bool send_hotplug = false;4047 4048 mutex_lock(&mgr->probe_lock);4049 while (true) {4050 mutex_lock(&mgr->up_req_lock);4051 up_req = list_first_entry_or_null(&mgr->up_req_list,4052 struct drm_dp_pending_up_req,4053 next);4054 if (up_req)4055 list_del(&up_req->next);4056 mutex_unlock(&mgr->up_req_lock);4057 4058 if (!up_req)4059 break;4060 4061 send_hotplug |= drm_dp_mst_process_up_req(mgr, up_req);4062 kfree(up_req);4063 }4064 mutex_unlock(&mgr->probe_lock);4065 4066 if (send_hotplug)4067 drm_kms_helper_hotplug_event(mgr->dev);4068}4069 4070static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)4071{4072 struct drm_dp_pending_up_req *up_req;4073 4074 if (!drm_dp_get_one_sb_msg(mgr, true, NULL))4075 goto out;4076 4077 if (!mgr->up_req_recv.have_eomt)4078 return 0;4079 4080 up_req = kzalloc(sizeof(*up_req), GFP_KERNEL);4081 if (!up_req)4082 return -ENOMEM;4083 4084 INIT_LIST_HEAD(&up_req->next);4085 4086 drm_dp_sideband_parse_req(mgr, &mgr->up_req_recv, &up_req->msg);4087 4088 if (up_req->msg.req_type != DP_CONNECTION_STATUS_NOTIFY &&4089 up_req->msg.req_type != DP_RESOURCE_STATUS_NOTIFY) {4090 drm_dbg_kms(mgr->dev, "Received unknown up req type, ignoring: %x\n",4091 up_req->msg.req_type);4092 kfree(up_req);4093 goto out;4094 }4095 4096 drm_dp_send_up_ack_reply(mgr, mgr->mst_primary, up_req->msg.req_type,4097 false);4098 4099 if (up_req->msg.req_type == DP_CONNECTION_STATUS_NOTIFY) {4100 const struct drm_dp_connection_status_notify *conn_stat =4101 &up_req->msg.u.conn_stat;4102 bool handle_csn;4103 4104 drm_dbg_kms(mgr->dev, "Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n",4105 conn_stat->port_number,4106 conn_stat->legacy_device_plug_status,4107 conn_stat->displayport_device_plug_status,4108 conn_stat->message_capability_status,4109 conn_stat->input_port,4110 conn_stat->peer_device_type);4111 4112 mutex_lock(&mgr->probe_lock);4113 handle_csn = mgr->mst_primary->link_address_sent;4114 mutex_unlock(&mgr->probe_lock);4115 4116 if (!handle_csn) {4117 drm_dbg_kms(mgr->dev, "Got CSN before finish topology probing. Skip it.");4118 kfree(up_req);4119 goto out;4120 }4121 } else if (up_req->msg.req_type == DP_RESOURCE_STATUS_NOTIFY) {4122 const struct drm_dp_resource_status_notify *res_stat =4123 &up_req->msg.u.resource_stat;4124 4125 drm_dbg_kms(mgr->dev, "Got RSN: pn: %d avail_pbn %d\n",4126 res_stat->port_number,4127 res_stat->available_pbn);4128 }4129 4130 up_req->hdr = mgr->up_req_recv.initial_hdr;4131 mutex_lock(&mgr->up_req_lock);4132 list_add_tail(&up_req->next, &mgr->up_req_list);4133 mutex_unlock(&mgr->up_req_lock);4134 queue_work(system_long_wq, &mgr->up_req_work);4135 4136out:4137 memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));4138 return 0;4139}4140 4141/**4142 * drm_dp_mst_hpd_irq_handle_event() - MST hotplug IRQ handle MST event4143 * @mgr: manager to notify irq for.4144 * @esi: 4 bytes from SINK_COUNT_ESI4145 * @ack: 4 bytes used to ack events starting from SINK_COUNT_ESI4146 * @handled: whether the hpd interrupt was consumed or not4147 *4148 * This should be called from the driver when it detects a HPD IRQ,4149 * along with the value of the DEVICE_SERVICE_IRQ_VECTOR_ESI0. The4150 * topology manager will process the sideband messages received4151 * as indicated in the DEVICE_SERVICE_IRQ_VECTOR_ESI0 and set the4152 * corresponding flags that Driver has to ack the DP receiver later.4153 *4154 * Note that driver shall also call4155 * drm_dp_mst_hpd_irq_send_new_request() if the 'handled' is set4156 * after calling this function, to try to kick off a new request in4157 * the queue if the previous message transaction is completed.4158 *4159 * See also:4160 * drm_dp_mst_hpd_irq_send_new_request()4161 */4162int drm_dp_mst_hpd_irq_handle_event(struct drm_dp_mst_topology_mgr *mgr, const u8 *esi,4163 u8 *ack, bool *handled)4164{4165 int ret = 0;4166 int sc;4167 *handled = false;4168 sc = DP_GET_SINK_COUNT(esi[0]);4169 4170 if (sc != mgr->sink_count) {4171 mgr->sink_count = sc;4172 *handled = true;4173 }4174 4175 if (esi[1] & DP_DOWN_REP_MSG_RDY) {4176 ret = drm_dp_mst_handle_down_rep(mgr);4177 *handled = true;4178 ack[1] |= DP_DOWN_REP_MSG_RDY;4179 }4180 4181 if (esi[1] & DP_UP_REQ_MSG_RDY) {4182 ret |= drm_dp_mst_handle_up_req(mgr);4183 *handled = true;4184 ack[1] |= DP_UP_REQ_MSG_RDY;4185 }4186 4187 return ret;4188}4189EXPORT_SYMBOL(drm_dp_mst_hpd_irq_handle_event);4190 4191/**4192 * drm_dp_mst_hpd_irq_send_new_request() - MST hotplug IRQ kick off new request4193 * @mgr: manager to notify irq for.4194 *4195 * This should be called from the driver when mst irq event is handled4196 * and acked. Note that new down request should only be sent when4197 * previous message transaction is completed. Source is not supposed to generate4198 * interleaved message transactions.4199 */4200void drm_dp_mst_hpd_irq_send_new_request(struct drm_dp_mst_topology_mgr *mgr)4201{4202 struct drm_dp_sideband_msg_tx *txmsg;4203 bool kick = true;4204 4205 mutex_lock(&mgr->qlock);4206 txmsg = list_first_entry_or_null(&mgr->tx_msg_downq,4207 struct drm_dp_sideband_msg_tx, next);4208 /* If last transaction is not completed yet*/4209 if (!txmsg ||4210 txmsg->state == DRM_DP_SIDEBAND_TX_START_SEND ||4211 txmsg->state == DRM_DP_SIDEBAND_TX_SENT)4212 kick = false;4213 mutex_unlock(&mgr->qlock);4214 4215 if (kick)4216 drm_dp_mst_kick_tx(mgr);4217}4218EXPORT_SYMBOL(drm_dp_mst_hpd_irq_send_new_request);4219/**4220 * drm_dp_mst_detect_port() - get connection status for an MST port4221 * @connector: DRM connector for this port4222 * @ctx: The acquisition context to use for grabbing locks4223 * @mgr: manager for this port4224 * @port: pointer to a port4225 *4226 * This returns the current connection state for a port.4227 */4228int4229drm_dp_mst_detect_port(struct drm_connector *connector,4230 struct drm_modeset_acquire_ctx *ctx,4231 struct drm_dp_mst_topology_mgr *mgr,4232 struct drm_dp_mst_port *port)4233{4234 int ret;4235 4236 /* we need to search for the port in the mgr in case it's gone */4237 port = drm_dp_mst_topology_get_port_validated(mgr, port);4238 if (!port)4239 return connector_status_disconnected;4240 4241 ret = drm_modeset_lock(&mgr->base.lock, ctx);4242 if (ret)4243 goto out;4244 4245 ret = connector_status_disconnected;4246 4247 if (!port->ddps)4248 goto out;4249 4250 switch (port->pdt) {4251 case DP_PEER_DEVICE_NONE:4252 break;4253 case DP_PEER_DEVICE_MST_BRANCHING:4254 if (!port->mcs)4255 ret = connector_status_connected;4256 break;4257 4258 case DP_PEER_DEVICE_SST_SINK:4259 ret = connector_status_connected;4260 /* for logical ports - cache the EDID */4261 if (drm_dp_mst_port_is_logical(port) && !port->cached_edid)4262 port->cached_edid = drm_edid_read_ddc(connector, &port->aux.ddc);4263 break;4264 case DP_PEER_DEVICE_DP_LEGACY_CONV:4265 if (port->ldps)4266 ret = connector_status_connected;4267 break;4268 }4269out:4270 drm_dp_mst_topology_put_port(port);4271 return ret;4272}4273EXPORT_SYMBOL(drm_dp_mst_detect_port);4274 4275/**4276 * drm_dp_mst_edid_read() - get EDID for an MST port4277 * @connector: toplevel connector to get EDID for4278 * @mgr: manager for this port4279 * @port: unverified pointer to a port.4280 *4281 * This returns an EDID for the port connected to a connector,4282 * It validates the pointer still exists so the caller doesn't require a4283 * reference.4284 */4285const struct drm_edid *drm_dp_mst_edid_read(struct drm_connector *connector,4286 struct drm_dp_mst_topology_mgr *mgr,4287 struct drm_dp_mst_port *port)4288{4289 const struct drm_edid *drm_edid;4290 4291 /* we need to search for the port in the mgr in case it's gone */4292 port = drm_dp_mst_topology_get_port_validated(mgr, port);4293 if (!port)4294 return NULL;4295 4296 if (port->cached_edid)4297 drm_edid = drm_edid_dup(port->cached_edid);4298 else4299 drm_edid = drm_edid_read_ddc(connector, &port->aux.ddc);4300 4301 drm_dp_mst_topology_put_port(port);4302 4303 return drm_edid;4304}4305EXPORT_SYMBOL(drm_dp_mst_edid_read);4306 4307/**4308 * drm_dp_mst_get_edid() - get EDID for an MST port4309 * @connector: toplevel connector to get EDID for4310 * @mgr: manager for this port4311 * @port: unverified pointer to a port.4312 *4313 * This function is deprecated; please use drm_dp_mst_edid_read() instead.4314 *4315 * This returns an EDID for the port connected to a connector,4316 * It validates the pointer still exists so the caller doesn't require a4317 * reference.4318 */4319struct edid *drm_dp_mst_get_edid(struct drm_connector *connector,4320 struct drm_dp_mst_topology_mgr *mgr,4321 struct drm_dp_mst_port *port)4322{4323 const struct drm_edid *drm_edid;4324 struct edid *edid;4325 4326 drm_edid = drm_dp_mst_edid_read(connector, mgr, port);4327 4328 edid = drm_edid_duplicate(drm_edid_raw(drm_edid));4329 4330 drm_edid_free(drm_edid);4331 4332 return edid;4333}4334EXPORT_SYMBOL(drm_dp_mst_get_edid);4335 4336/**4337 * drm_dp_atomic_find_time_slots() - Find and add time slots to the state4338 * @state: global atomic state4339 * @mgr: MST topology manager for the port4340 * @port: port to find time slots for4341 * @pbn: bandwidth required for the mode in PBN4342 *4343 * Allocates time slots to @port, replacing any previous time slot allocations it may4344 * have had. Any atomic drivers which support MST must call this function in4345 * their &drm_encoder_helper_funcs.atomic_check() callback unconditionally to4346 * change the current time slot allocation for the new state, and ensure the MST4347 * atomic state is added whenever the state of payloads in the topology changes.4348 *4349 * Allocations set by this function are not checked against the bandwidth4350 * restraints of @mgr until the driver calls drm_dp_mst_atomic_check().4351 *4352 * Additionally, it is OK to call this function multiple times on the same4353 * @port as needed. It is not OK however, to call this function and4354 * drm_dp_atomic_release_time_slots() in the same atomic check phase.4355 *4356 * See also:4357 * drm_dp_atomic_release_time_slots()4358 * drm_dp_mst_atomic_check()4359 *4360 * Returns:4361 * Total slots in the atomic state assigned for this port, or a negative error4362 * code if the port no longer exists4363 */4364int drm_dp_atomic_find_time_slots(struct drm_atomic_state *state,4365 struct drm_dp_mst_topology_mgr *mgr,4366 struct drm_dp_mst_port *port, int pbn)4367{4368 struct drm_dp_mst_topology_state *topology_state;4369 struct drm_dp_mst_atomic_payload *payload = NULL;4370 struct drm_connector_state *conn_state;4371 int prev_slots = 0, prev_bw = 0, req_slots;4372 4373 topology_state = drm_atomic_get_mst_topology_state(state, mgr);4374 if (IS_ERR(topology_state))4375 return PTR_ERR(topology_state);4376 4377 conn_state = drm_atomic_get_new_connector_state(state, port->connector);4378 topology_state->pending_crtc_mask |= drm_crtc_mask(conn_state->crtc);4379 4380 /* Find the current allocation for this port, if any */4381 payload = drm_atomic_get_mst_payload_state(topology_state, port);4382 if (payload) {4383 prev_slots = payload->time_slots;4384 prev_bw = payload->pbn;4385 4386 /*4387 * This should never happen, unless the driver tries4388 * releasing and allocating the same timeslot allocation,4389 * which is an error4390 */4391 if (drm_WARN_ON(mgr->dev, payload->delete)) {4392 drm_err(mgr->dev,4393 "cannot allocate and release time slots on [MST PORT:%p] in the same state\n",4394 port);4395 return -EINVAL;4396 }4397 }4398 4399 req_slots = DIV_ROUND_UP(dfixed_const(pbn), topology_state->pbn_div.full);4400 4401 drm_dbg_atomic(mgr->dev, "[CONNECTOR:%d:%s] [MST PORT:%p] TU %d -> %d\n",4402 port->connector->base.id, port->connector->name,4403 port, prev_slots, req_slots);4404 drm_dbg_atomic(mgr->dev, "[CONNECTOR:%d:%s] [MST PORT:%p] PBN %d -> %d\n",4405 port->connector->base.id, port->connector->name,4406 port, prev_bw, pbn);4407 4408 /* Add the new allocation to the state, note the VCPI isn't assigned until the end */4409 if (!payload) {4410 payload = kzalloc(sizeof(*payload), GFP_KERNEL);4411 if (!payload)4412 return -ENOMEM;4413 4414 drm_dp_mst_get_port_malloc(port);4415 payload->port = port;4416 payload->vc_start_slot = -1;4417 payload->payload_allocation_status = DRM_DP_MST_PAYLOAD_ALLOCATION_NONE;4418 list_add(&payload->next, &topology_state->payloads);4419 }4420 payload->time_slots = req_slots;4421 payload->pbn = pbn;4422 4423 return req_slots;4424}4425EXPORT_SYMBOL(drm_dp_atomic_find_time_slots);4426 4427/**4428 * drm_dp_atomic_release_time_slots() - Release allocated time slots4429 * @state: global atomic state4430 * @mgr: MST topology manager for the port4431 * @port: The port to release the time slots from4432 *4433 * Releases any time slots that have been allocated to a port in the atomic4434 * state. Any atomic drivers which support MST must call this function4435 * unconditionally in their &drm_connector_helper_funcs.atomic_check() callback.4436 * This helper will check whether time slots would be released by the new state and4437 * respond accordingly, along with ensuring the MST state is always added to the4438 * atomic state whenever a new state would modify the state of payloads on the4439 * topology.4440 *4441 * It is OK to call this even if @port has been removed from the system.4442 * Additionally, it is OK to call this function multiple times on the same4443 * @port as needed. It is not OK however, to call this function and4444 * drm_dp_atomic_find_time_slots() on the same @port in a single atomic check4445 * phase.4446 *4447 * See also:4448 * drm_dp_atomic_find_time_slots()4449 * drm_dp_mst_atomic_check()4450 *4451 * Returns:4452 * 0 on success, negative error code otherwise4453 */4454int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state,4455 struct drm_dp_mst_topology_mgr *mgr,4456 struct drm_dp_mst_port *port)4457{4458 struct drm_dp_mst_topology_state *topology_state;4459 struct drm_dp_mst_atomic_payload *payload;4460 struct drm_connector_state *old_conn_state, *new_conn_state;4461 bool update_payload = true;4462 4463 old_conn_state = drm_atomic_get_old_connector_state(state, port->connector);4464 if (!old_conn_state->crtc)4465 return 0;4466 4467 /* If the CRTC isn't disabled by this state, don't release it's payload */4468 new_conn_state = drm_atomic_get_new_connector_state(state, port->connector);4469 if (new_conn_state->crtc) {4470 struct drm_crtc_state *crtc_state =4471 drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);4472 4473 /* No modeset means no payload changes, so it's safe to not pull in the MST state */4474 if (!crtc_state || !drm_atomic_crtc_needs_modeset(crtc_state))4475 return 0;4476 4477 if (!crtc_state->mode_changed && !crtc_state->connectors_changed)4478 update_payload = false;4479 }4480 4481 topology_state = drm_atomic_get_mst_topology_state(state, mgr);4482 if (IS_ERR(topology_state))4483 return PTR_ERR(topology_state);4484 4485 topology_state->pending_crtc_mask |= drm_crtc_mask(old_conn_state->crtc);4486 if (!update_payload)4487 return 0;4488 4489 payload = drm_atomic_get_mst_payload_state(topology_state, port);4490 if (WARN_ON(!payload)) {4491 drm_err(mgr->dev, "No payload for [MST PORT:%p] found in mst state %p\n",4492 port, &topology_state->base);4493 return -EINVAL;4494 }4495 4496 if (new_conn_state->crtc)4497 return 0;4498 4499 drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, payload->time_slots);4500 if (!payload->delete) {4501 payload->pbn = 0;4502 payload->delete = true;4503 topology_state->payload_mask &= ~BIT(payload->vcpi - 1);4504 }4505 4506 return 0;4507}4508EXPORT_SYMBOL(drm_dp_atomic_release_time_slots);4509 4510/**4511 * drm_dp_mst_atomic_setup_commit() - setup_commit hook for MST helpers4512 * @state: global atomic state4513 *4514 * This function saves all of the &drm_crtc_commit structs in an atomic state that touch any CRTCs4515 * currently assigned to an MST topology. Drivers must call this hook from their4516 * &drm_mode_config_helper_funcs.atomic_commit_setup hook.4517 *4518 * Returns:4519 * 0 if all CRTC commits were retrieved successfully, negative error code otherwise4520 */4521int drm_dp_mst_atomic_setup_commit(struct drm_atomic_state *state)4522{4523 struct drm_dp_mst_topology_mgr *mgr;4524 struct drm_dp_mst_topology_state *mst_state;4525 struct drm_crtc *crtc;4526 struct drm_crtc_state *crtc_state;4527 int i, j, commit_idx, num_commit_deps;4528 4529 for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {4530 if (!mst_state->pending_crtc_mask)4531 continue;4532 4533 num_commit_deps = hweight32(mst_state->pending_crtc_mask);4534 mst_state->commit_deps = kmalloc_array(num_commit_deps,4535 sizeof(*mst_state->commit_deps), GFP_KERNEL);4536 if (!mst_state->commit_deps)4537 return -ENOMEM;4538 mst_state->num_commit_deps = num_commit_deps;4539 4540 commit_idx = 0;4541 for_each_new_crtc_in_state(state, crtc, crtc_state, j) {4542 if (mst_state->pending_crtc_mask & drm_crtc_mask(crtc)) {4543 mst_state->commit_deps[commit_idx++] =4544 drm_crtc_commit_get(crtc_state->commit);4545 }4546 }4547 }4548 4549 return 0;4550}4551EXPORT_SYMBOL(drm_dp_mst_atomic_setup_commit);4552 4553/**4554 * drm_dp_mst_atomic_wait_for_dependencies() - Wait for all pending commits on MST topologies,4555 * prepare new MST state for commit4556 * @state: global atomic state4557 *4558 * Goes through any MST topologies in this atomic state, and waits for any pending commits which4559 * touched CRTCs that were/are on an MST topology to be programmed to hardware and flipped to before4560 * returning. This is to prevent multiple non-blocking commits affecting an MST topology from racing4561 * with eachother by forcing them to be executed sequentially in situations where the only resources4562 * the modeset objects in these commits share are an MST topology.4563 *4564 * This function also prepares the new MST state for commit by performing some state preparation4565 * which can't be done until this point, such as reading back the final VC start slots (which are4566 * determined at commit-time) from the previous state.4567 *4568 * All MST drivers must call this function after calling drm_atomic_helper_wait_for_dependencies(),4569 * or whatever their equivalent of that is.4570 */4571void drm_dp_mst_atomic_wait_for_dependencies(struct drm_atomic_state *state)4572{4573 struct drm_dp_mst_topology_state *old_mst_state, *new_mst_state;4574 struct drm_dp_mst_topology_mgr *mgr;4575 struct drm_dp_mst_atomic_payload *old_payload, *new_payload;4576 int i, j, ret;4577 4578 for_each_oldnew_mst_mgr_in_state(state, mgr, old_mst_state, new_mst_state, i) {4579 for (j = 0; j < old_mst_state->num_commit_deps; j++) {4580 ret = drm_crtc_commit_wait(old_mst_state->commit_deps[j]);4581 if (ret < 0)4582 drm_err(state->dev, "Failed to wait for %s: %d\n",4583 old_mst_state->commit_deps[j]->crtc->name, ret);4584 }4585 4586 /* Now that previous state is committed, it's safe to copy over the start slot4587 * and allocation status assignments4588 */4589 list_for_each_entry(old_payload, &old_mst_state->payloads, next) {4590 if (old_payload->delete)4591 continue;4592 4593 new_payload = drm_atomic_get_mst_payload_state(new_mst_state,4594 old_payload->port);4595 new_payload->vc_start_slot = old_payload->vc_start_slot;4596 new_payload->payload_allocation_status =4597 old_payload->payload_allocation_status;4598 }4599 }4600}4601EXPORT_SYMBOL(drm_dp_mst_atomic_wait_for_dependencies);4602 4603/**4604 * drm_dp_mst_root_conn_atomic_check() - Serialize CRTC commits on MST-capable connectors operating4605 * in SST mode4606 * @new_conn_state: The new connector state of the &drm_connector4607 * @mgr: The MST topology manager for the &drm_connector4608 *4609 * Since MST uses fake &drm_encoder structs, the generic atomic modesetting code isn't able to4610 * serialize non-blocking commits happening on the real DP connector of an MST topology switching4611 * into/away from MST mode - as the CRTC on the real DP connector and the CRTCs on the connector's4612 * MST topology will never share the same &drm_encoder.4613 *4614 * This function takes care of this serialization issue, by checking a root MST connector's atomic4615 * state to determine if it is about to have a modeset - and then pulling in the MST topology state4616 * if so, along with adding any relevant CRTCs to &drm_dp_mst_topology_state.pending_crtc_mask.4617 *4618 * Drivers implementing MST must call this function from the4619 * &drm_connector_helper_funcs.atomic_check hook of any physical DP &drm_connector capable of4620 * driving MST sinks.4621 *4622 * Returns:4623 * 0 on success, negative error code otherwise4624 */4625int drm_dp_mst_root_conn_atomic_check(struct drm_connector_state *new_conn_state,4626 struct drm_dp_mst_topology_mgr *mgr)4627{4628 struct drm_atomic_state *state = new_conn_state->state;4629 struct drm_connector_state *old_conn_state =4630 drm_atomic_get_old_connector_state(state, new_conn_state->connector);4631 struct drm_crtc_state *crtc_state;4632 struct drm_dp_mst_topology_state *mst_state = NULL;4633 4634 if (new_conn_state->crtc) {4635 crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);4636 if (crtc_state && drm_atomic_crtc_needs_modeset(crtc_state)) {4637 mst_state = drm_atomic_get_mst_topology_state(state, mgr);4638 if (IS_ERR(mst_state))4639 return PTR_ERR(mst_state);4640 4641 mst_state->pending_crtc_mask |= drm_crtc_mask(new_conn_state->crtc);4642 }4643 }4644 4645 if (old_conn_state->crtc) {4646 crtc_state = drm_atomic_get_new_crtc_state(state, old_conn_state->crtc);4647 if (crtc_state && drm_atomic_crtc_needs_modeset(crtc_state)) {4648 if (!mst_state) {4649 mst_state = drm_atomic_get_mst_topology_state(state, mgr);4650 if (IS_ERR(mst_state))4651 return PTR_ERR(mst_state);4652 }4653 4654 mst_state->pending_crtc_mask |= drm_crtc_mask(old_conn_state->crtc);4655 }4656 }4657 4658 return 0;4659}4660EXPORT_SYMBOL(drm_dp_mst_root_conn_atomic_check);4661 4662/**4663 * drm_dp_mst_update_slots() - updates the slot info depending on the DP ecoding format4664 * @mst_state: mst_state to update4665 * @link_encoding_cap: the ecoding format on the link4666 */4667void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, uint8_t link_encoding_cap)4668{4669 if (link_encoding_cap == DP_CAP_ANSI_128B132B) {4670 mst_state->total_avail_slots = 64;4671 mst_state->start_slot = 0;4672 } else {4673 mst_state->total_avail_slots = 63;4674 mst_state->start_slot = 1;4675 }4676 4677 DRM_DEBUG_KMS("%s encoding format on mst_state 0x%p\n",4678 (link_encoding_cap == DP_CAP_ANSI_128B132B) ? "128b/132b":"8b/10b",4679 mst_state);4680}4681EXPORT_SYMBOL(drm_dp_mst_update_slots);4682 4683static int drm_dp_dpcd_write_payload(struct drm_dp_mst_topology_mgr *mgr,4684 int id, u8 start_slot, u8 num_slots)4685{4686 u8 payload_alloc[3], status;4687 int ret;4688 int retries = 0;4689 4690 drm_dp_dpcd_writeb(mgr->aux, DP_PAYLOAD_TABLE_UPDATE_STATUS,4691 DP_PAYLOAD_TABLE_UPDATED);4692 4693 payload_alloc[0] = id;4694 payload_alloc[1] = start_slot;4695 payload_alloc[2] = num_slots;4696 4697 ret = drm_dp_dpcd_write(mgr->aux, DP_PAYLOAD_ALLOCATE_SET, payload_alloc, 3);4698 if (ret != 3) {4699 drm_dbg_kms(mgr->dev, "failed to write payload allocation %d\n", ret);4700 goto fail;4701 }4702 4703retry:4704 ret = drm_dp_dpcd_readb(mgr->aux, DP_PAYLOAD_TABLE_UPDATE_STATUS, &status);4705 if (ret < 0) {4706 drm_dbg_kms(mgr->dev, "failed to read payload table status %d\n", ret);4707 goto fail;4708 }4709 4710 if (!(status & DP_PAYLOAD_TABLE_UPDATED)) {4711 retries++;4712 if (retries < 20) {4713 usleep_range(10000, 20000);4714 goto retry;4715 }4716 drm_dbg_kms(mgr->dev, "status not set after read payload table status %d\n",4717 status);4718 ret = -EINVAL;4719 goto fail;4720 }4721 ret = 0;4722fail:4723 return ret;4724}4725 4726static int do_get_act_status(struct drm_dp_aux *aux)4727{4728 int ret;4729 u8 status;4730 4731 ret = drm_dp_dpcd_readb(aux, DP_PAYLOAD_TABLE_UPDATE_STATUS, &status);4732 if (ret < 0)4733 return ret;4734 4735 return status;4736}4737 4738/**4739 * drm_dp_check_act_status() - Polls for ACT handled status.4740 * @mgr: manager to use4741 *4742 * Tries waiting for the MST hub to finish updating it's payload table by4743 * polling for the ACT handled bit for up to 3 seconds (yes-some hubs really4744 * take that long).4745 *4746 * Returns:4747 * 0 if the ACT was handled in time, negative error code on failure.4748 */4749int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr)4750{4751 /*4752 * There doesn't seem to be any recommended retry count or timeout in4753 * the MST specification. Since some hubs have been observed to take4754 * over 1 second to update their payload allocations under certain4755 * conditions, we use a rather large timeout value.4756 */4757 const int timeout_ms = 3000;4758 int ret, status;4759 4760 ret = readx_poll_timeout(do_get_act_status, mgr->aux, status,4761 status & DP_PAYLOAD_ACT_HANDLED || status < 0,4762 200, timeout_ms * USEC_PER_MSEC);4763 if (ret < 0 && status >= 0) {4764 drm_err(mgr->dev, "Failed to get ACT after %dms, last status: %02x\n",4765 timeout_ms, status);4766 return -EINVAL;4767 } else if (status < 0) {4768 /*4769 * Failure here isn't unexpected - the hub may have4770 * just been unplugged4771 */4772 drm_dbg_kms(mgr->dev, "Failed to read payload table status: %d\n", status);4773 return status;4774 }4775 4776 return 0;4777}4778EXPORT_SYMBOL(drm_dp_check_act_status);4779 4780/**4781 * drm_dp_calc_pbn_mode() - Calculate the PBN for a mode.4782 * @clock: dot clock4783 * @bpp: bpp as .4 binary fixed point4784 *4785 * This uses the formula in the spec to calculate the PBN value for a mode.4786 */4787int drm_dp_calc_pbn_mode(int clock, int bpp)4788{4789 /*4790 * The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on4791 * common multiplier to render an integer PBN for all link rate/lane4792 * counts combinations4793 * calculate4794 * peak_kbps = clock * bpp / 164795 * peak_kbps *= SSC overhead / 10000004796 * peak_kbps /= 8 convert to Kbytes4797 * peak_kBps *= (64/54) / 1000 convert to PBN4798 */4799 /*4800 * TODO: Use the actual link and mode parameters to calculate4801 * the overhead. For now it's assumed that these are4802 * 4 link lanes, 4096 hactive pixels, which don't add any4803 * significant data padding overhead and that there is no DSC4804 * or FEC overhead.4805 */4806 int overhead = drm_dp_bw_overhead(4, 4096, 0, bpp,4807 DRM_DP_BW_OVERHEAD_MST |4808 DRM_DP_BW_OVERHEAD_SSC_REF_CLK);4809 4810 return DIV64_U64_ROUND_UP(mul_u32_u32(clock * bpp, 64 * overhead >> 4),4811 1000000ULL * 8 * 54 * 1000);4812}4813EXPORT_SYMBOL(drm_dp_calc_pbn_mode);4814 4815/* we want to kick the TX after we've ack the up/down IRQs. */4816static void drm_dp_mst_kick_tx(struct drm_dp_mst_topology_mgr *mgr)4817{4818 queue_work(system_long_wq, &mgr->tx_work);4819}4820 4821/*4822 * Helper function for parsing DP device types into convenient strings4823 * for use with dp_mst_topology4824 */4825static const char *pdt_to_string(u8 pdt)4826{4827 switch (pdt) {4828 case DP_PEER_DEVICE_NONE:4829 return "NONE";4830 case DP_PEER_DEVICE_SOURCE_OR_SST:4831 return "SOURCE OR SST";4832 case DP_PEER_DEVICE_MST_BRANCHING:4833 return "MST BRANCHING";4834 case DP_PEER_DEVICE_SST_SINK:4835 return "SST SINK";4836 case DP_PEER_DEVICE_DP_LEGACY_CONV:4837 return "DP LEGACY CONV";4838 default:4839 return "ERR";4840 }4841}4842 4843static void drm_dp_mst_dump_mstb(struct seq_file *m,4844 struct drm_dp_mst_branch *mstb)4845{4846 struct drm_dp_mst_port *port;4847 int tabs = mstb->lct;4848 char prefix[10];4849 int i;4850 4851 for (i = 0; i < tabs; i++)4852 prefix[i] = '\t';4853 prefix[i] = '\0';4854 4855 seq_printf(m, "%smstb - [%p]: num_ports: %d\n", prefix, mstb, mstb->num_ports);4856 list_for_each_entry(port, &mstb->ports, next) {4857 seq_printf(m, "%sport %d - [%p] (%s - %s): ddps: %d, ldps: %d, sdp: %d/%d, fec: %s, conn: %p\n",4858 prefix,4859 port->port_num,4860 port,4861 port->input ? "input" : "output",4862 pdt_to_string(port->pdt),4863 port->ddps,4864 port->ldps,4865 port->num_sdp_streams,4866 port->num_sdp_stream_sinks,4867 port->fec_capable ? "true" : "false",4868 port->connector);4869 if (port->mstb)4870 drm_dp_mst_dump_mstb(m, port->mstb);4871 }4872}4873 4874#define DP_PAYLOAD_TABLE_SIZE 644875 4876static bool dump_dp_payload_table(struct drm_dp_mst_topology_mgr *mgr,4877 char *buf)4878{4879 int i;4880 4881 for (i = 0; i < DP_PAYLOAD_TABLE_SIZE; i += 16) {4882 if (drm_dp_dpcd_read(mgr->aux,4883 DP_PAYLOAD_TABLE_UPDATE_STATUS + i,4884 &buf[i], 16) != 16)4885 return false;4886 }4887 return true;4888}4889 4890static void fetch_monitor_name(struct drm_dp_mst_topology_mgr *mgr,4891 struct drm_dp_mst_port *port, char *name,4892 int namelen)4893{4894 struct edid *mst_edid;4895 4896 mst_edid = drm_dp_mst_get_edid(port->connector, mgr, port);4897 drm_edid_get_monitor_name(mst_edid, name, namelen);4898 kfree(mst_edid);4899}4900 4901/**4902 * drm_dp_mst_dump_topology(): dump topology to seq file.4903 * @m: seq_file to dump output to4904 * @mgr: manager to dump current topology for.4905 *4906 * helper to dump MST topology to a seq file for debugfs.4907 */4908void drm_dp_mst_dump_topology(struct seq_file *m,4909 struct drm_dp_mst_topology_mgr *mgr)4910{4911 struct drm_dp_mst_topology_state *state;4912 struct drm_dp_mst_atomic_payload *payload;4913 int i, ret;4914 4915 static const char *const status[] = {4916 "None",4917 "Local",4918 "DFP",4919 "Remote",4920 };4921 4922 mutex_lock(&mgr->lock);4923 if (mgr->mst_primary)4924 drm_dp_mst_dump_mstb(m, mgr->mst_primary);4925 4926 /* dump VCPIs */4927 mutex_unlock(&mgr->lock);4928 4929 ret = drm_modeset_lock_single_interruptible(&mgr->base.lock);4930 if (ret < 0)4931 return;4932 4933 state = to_drm_dp_mst_topology_state(mgr->base.state);4934 seq_printf(m, "\n*** Atomic state info ***\n");4935 seq_printf(m, "payload_mask: %x, max_payloads: %d, start_slot: %u, pbn_div: %d\n",4936 state->payload_mask, mgr->max_payloads, state->start_slot,4937 dfixed_trunc(state->pbn_div));4938 4939 seq_printf(m, "\n| idx | port | vcpi | slots | pbn | dsc | status | sink name |\n");4940 for (i = 0; i < mgr->max_payloads; i++) {4941 list_for_each_entry(payload, &state->payloads, next) {4942 char name[14];4943 4944 if (payload->vcpi != i || payload->delete)4945 continue;4946 4947 fetch_monitor_name(mgr, payload->port, name, sizeof(name));4948 seq_printf(m, " %5d %6d %6d %02d - %02d %5d %5s %8s %19s\n",4949 i,4950 payload->port->port_num,4951 payload->vcpi,4952 payload->vc_start_slot,4953 payload->vc_start_slot + payload->time_slots - 1,4954 payload->pbn,4955 payload->dsc_enabled ? "Y" : "N",4956 status[payload->payload_allocation_status],4957 (*name != 0) ? name : "Unknown");4958 }4959 }4960 4961 seq_printf(m, "\n*** DPCD Info ***\n");4962 mutex_lock(&mgr->lock);4963 if (mgr->mst_primary) {4964 u8 buf[DP_PAYLOAD_TABLE_SIZE];4965 int ret;4966 4967 if (drm_dp_read_dpcd_caps(mgr->aux, buf) < 0) {4968 seq_printf(m, "dpcd read failed\n");4969 goto out;4970 }4971 seq_printf(m, "dpcd: %*ph\n", DP_RECEIVER_CAP_SIZE, buf);4972 4973 ret = drm_dp_dpcd_read(mgr->aux, DP_FAUX_CAP, buf, 2);4974 if (ret != 2) {4975 seq_printf(m, "faux/mst read failed\n");4976 goto out;4977 }4978 seq_printf(m, "faux/mst: %*ph\n", 2, buf);4979 4980 ret = drm_dp_dpcd_read(mgr->aux, DP_MSTM_CTRL, buf, 1);4981 if (ret != 1) {4982 seq_printf(m, "mst ctrl read failed\n");4983 goto out;4984 }4985 seq_printf(m, "mst ctrl: %*ph\n", 1, buf);4986 4987 /* dump the standard OUI branch header */4988 ret = drm_dp_dpcd_read(mgr->aux, DP_BRANCH_OUI, buf, DP_BRANCH_OUI_HEADER_SIZE);4989 if (ret != DP_BRANCH_OUI_HEADER_SIZE) {4990 seq_printf(m, "branch oui read failed\n");4991 goto out;4992 }4993 seq_printf(m, "branch oui: %*phN devid: ", 3, buf);4994 4995 for (i = 0x3; i < 0x8 && buf[i]; i++)4996 seq_putc(m, buf[i]);4997 seq_printf(m, " revision: hw: %x.%x sw: %x.%x\n",4998 buf[0x9] >> 4, buf[0x9] & 0xf, buf[0xa], buf[0xb]);4999 if (dump_dp_payload_table(mgr, buf))5000 seq_printf(m, "payload table: %*ph\n", DP_PAYLOAD_TABLE_SIZE, buf);5001 }5002 5003out:5004 mutex_unlock(&mgr->lock);5005 drm_modeset_unlock(&mgr->base.lock);5006}5007EXPORT_SYMBOL(drm_dp_mst_dump_topology);5008 5009static void drm_dp_tx_work(struct work_struct *work)5010{5011 struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, tx_work);5012 5013 mutex_lock(&mgr->qlock);5014 if (!list_empty(&mgr->tx_msg_downq))5015 process_single_down_tx_qlock(mgr);5016 mutex_unlock(&mgr->qlock);5017}5018 5019static inline void5020drm_dp_delayed_destroy_port(struct drm_dp_mst_port *port)5021{5022 drm_dp_port_set_pdt(port, DP_PEER_DEVICE_NONE, port->mcs);5023 5024 if (port->connector) {5025 drm_connector_unregister(port->connector);5026 drm_connector_put(port->connector);5027 }5028 5029 drm_dp_mst_put_port_malloc(port);5030}5031 5032static inline void5033drm_dp_delayed_destroy_mstb(struct drm_dp_mst_branch *mstb)5034{5035 struct drm_dp_mst_topology_mgr *mgr = mstb->mgr;5036 struct drm_dp_mst_port *port, *port_tmp;5037 struct drm_dp_sideband_msg_tx *txmsg, *txmsg_tmp;5038 bool wake_tx = false;5039 5040 mutex_lock(&mgr->lock);5041 list_for_each_entry_safe(port, port_tmp, &mstb->ports, next) {5042 list_del(&port->next);5043 drm_dp_mst_topology_put_port(port);5044 }5045 mutex_unlock(&mgr->lock);5046 5047 /* drop any tx slot msg */5048 mutex_lock(&mstb->mgr->qlock);5049 list_for_each_entry_safe(txmsg, txmsg_tmp, &mgr->tx_msg_downq, next) {5050 if (txmsg->dst != mstb)5051 continue;5052 5053 txmsg->state = DRM_DP_SIDEBAND_TX_TIMEOUT;5054 list_del(&txmsg->next);5055 wake_tx = true;5056 }5057 mutex_unlock(&mstb->mgr->qlock);5058 5059 if (wake_tx)5060 wake_up_all(&mstb->mgr->tx_waitq);5061 5062 drm_dp_mst_put_mstb_malloc(mstb);5063}5064 5065static void drm_dp_delayed_destroy_work(struct work_struct *work)5066{5067 struct drm_dp_mst_topology_mgr *mgr =5068 container_of(work, struct drm_dp_mst_topology_mgr,5069 delayed_destroy_work);5070 bool send_hotplug = false, go_again;5071 5072 /*5073 * Not a regular list traverse as we have to drop the destroy5074 * connector lock before destroying the mstb/port, to avoid AB->BA5075 * ordering between this lock and the config mutex.5076 */5077 do {5078 go_again = false;5079 5080 for (;;) {5081 struct drm_dp_mst_branch *mstb;5082 5083 mutex_lock(&mgr->delayed_destroy_lock);5084 mstb = list_first_entry_or_null(&mgr->destroy_branch_device_list,5085 struct drm_dp_mst_branch,5086 destroy_next);5087 if (mstb)5088 list_del(&mstb->destroy_next);5089 mutex_unlock(&mgr->delayed_destroy_lock);5090 5091 if (!mstb)5092 break;5093 5094 drm_dp_delayed_destroy_mstb(mstb);5095 go_again = true;5096 }5097 5098 for (;;) {5099 struct drm_dp_mst_port *port;5100 5101 mutex_lock(&mgr->delayed_destroy_lock);5102 port = list_first_entry_or_null(&mgr->destroy_port_list,5103 struct drm_dp_mst_port,5104 next);5105 if (port)5106 list_del(&port->next);5107 mutex_unlock(&mgr->delayed_destroy_lock);5108 5109 if (!port)5110 break;5111 5112 drm_dp_delayed_destroy_port(port);5113 send_hotplug = true;5114 go_again = true;5115 }5116 } while (go_again);5117 5118 if (send_hotplug)5119 drm_kms_helper_hotplug_event(mgr->dev);5120}5121 5122static struct drm_private_state *5123drm_dp_mst_duplicate_state(struct drm_private_obj *obj)5124{5125 struct drm_dp_mst_topology_state *state, *old_state =5126 to_dp_mst_topology_state(obj->state);5127 struct drm_dp_mst_atomic_payload *pos, *payload;5128 5129 state = kmemdup(old_state, sizeof(*state), GFP_KERNEL);5130 if (!state)5131 return NULL;5132 5133 __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);5134 5135 INIT_LIST_HEAD(&state->payloads);5136 state->commit_deps = NULL;5137 state->num_commit_deps = 0;5138 state->pending_crtc_mask = 0;5139 5140 list_for_each_entry(pos, &old_state->payloads, next) {5141 /* Prune leftover freed timeslot allocations */5142 if (pos->delete)5143 continue;5144 5145 payload = kmemdup(pos, sizeof(*payload), GFP_KERNEL);5146 if (!payload)5147 goto fail;5148 5149 drm_dp_mst_get_port_malloc(payload->port);5150 list_add(&payload->next, &state->payloads);5151 }5152 5153 return &state->base;5154 5155fail:5156 list_for_each_entry_safe(pos, payload, &state->payloads, next) {5157 drm_dp_mst_put_port_malloc(pos->port);5158 kfree(pos);5159 }5160 kfree(state);5161 5162 return NULL;5163}5164 5165static void drm_dp_mst_destroy_state(struct drm_private_obj *obj,5166 struct drm_private_state *state)5167{5168 struct drm_dp_mst_topology_state *mst_state =5169 to_dp_mst_topology_state(state);5170 struct drm_dp_mst_atomic_payload *pos, *tmp;5171 int i;5172 5173 list_for_each_entry_safe(pos, tmp, &mst_state->payloads, next) {5174 /* We only keep references to ports with active payloads */5175 if (!pos->delete)5176 drm_dp_mst_put_port_malloc(pos->port);5177 kfree(pos);5178 }5179 5180 for (i = 0; i < mst_state->num_commit_deps; i++)5181 drm_crtc_commit_put(mst_state->commit_deps[i]);5182 5183 kfree(mst_state->commit_deps);5184 kfree(mst_state);5185}5186 5187static bool drm_dp_mst_port_downstream_of_branch(struct drm_dp_mst_port *port,5188 struct drm_dp_mst_branch *branch)5189{5190 while (port->parent) {5191 if (port->parent == branch)5192 return true;5193 5194 if (port->parent->port_parent)5195 port = port->parent->port_parent;5196 else5197 break;5198 }5199 return false;5200}5201 5202static bool5203drm_dp_mst_port_downstream_of_parent_locked(struct drm_dp_mst_topology_mgr *mgr,5204 struct drm_dp_mst_port *port,5205 struct drm_dp_mst_port *parent)5206{5207 if (!mgr->mst_primary)5208 return false;5209 5210 port = drm_dp_mst_topology_get_port_validated_locked(mgr->mst_primary,5211 port);5212 if (!port)5213 return false;5214 5215 if (!parent)5216 return true;5217 5218 parent = drm_dp_mst_topology_get_port_validated_locked(mgr->mst_primary,5219 parent);5220 if (!parent)5221 return false;5222 5223 if (!parent->mstb)5224 return false;5225 5226 return drm_dp_mst_port_downstream_of_branch(port, parent->mstb);5227}5228 5229/**5230 * drm_dp_mst_port_downstream_of_parent - check if a port is downstream of a parent port5231 * @mgr: MST topology manager5232 * @port: the port being looked up5233 * @parent: the parent port5234 *5235 * The function returns %true if @port is downstream of @parent. If @parent is5236 * %NULL - denoting the root port - the function returns %true if @port is in5237 * @mgr's topology.5238 */5239bool5240drm_dp_mst_port_downstream_of_parent(struct drm_dp_mst_topology_mgr *mgr,5241 struct drm_dp_mst_port *port,5242 struct drm_dp_mst_port *parent)5243{5244 bool ret;5245 5246 mutex_lock(&mgr->lock);5247 ret = drm_dp_mst_port_downstream_of_parent_locked(mgr, port, parent);5248 mutex_unlock(&mgr->lock);5249 5250 return ret;5251}5252EXPORT_SYMBOL(drm_dp_mst_port_downstream_of_parent);5253 5254static int5255drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port,5256 struct drm_dp_mst_topology_state *state,5257 struct drm_dp_mst_port **failing_port);5258 5259static int5260drm_dp_mst_atomic_check_mstb_bw_limit(struct drm_dp_mst_branch *mstb,5261 struct drm_dp_mst_topology_state *state,5262 struct drm_dp_mst_port **failing_port)5263{5264 struct drm_dp_mst_atomic_payload *payload;5265 struct drm_dp_mst_port *port;5266 int pbn_used = 0, ret;5267 bool found = false;5268 5269 /* Check that we have at least one port in our state that's downstream5270 * of this branch, otherwise we can skip this branch5271 */5272 list_for_each_entry(payload, &state->payloads, next) {5273 if (!payload->pbn ||5274 !drm_dp_mst_port_downstream_of_branch(payload->port, mstb))5275 continue;5276 5277 found = true;5278 break;5279 }5280 if (!found)5281 return 0;5282 5283 if (mstb->port_parent)5284 drm_dbg_atomic(mstb->mgr->dev,5285 "[MSTB:%p] [MST PORT:%p] Checking bandwidth limits on [MSTB:%p]\n",5286 mstb->port_parent->parent, mstb->port_parent, mstb);5287 else5288 drm_dbg_atomic(mstb->mgr->dev, "[MSTB:%p] Checking bandwidth limits\n", mstb);5289 5290 list_for_each_entry(port, &mstb->ports, next) {5291 ret = drm_dp_mst_atomic_check_port_bw_limit(port, state, failing_port);5292 if (ret < 0)5293 return ret;5294 5295 pbn_used += ret;5296 }5297 5298 return pbn_used;5299}5300 5301static int5302drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port,5303 struct drm_dp_mst_topology_state *state,5304 struct drm_dp_mst_port **failing_port)5305{5306 struct drm_dp_mst_atomic_payload *payload;5307 int pbn_used = 0;5308 5309 if (port->pdt == DP_PEER_DEVICE_NONE)5310 return 0;5311 5312 if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) {5313 payload = drm_atomic_get_mst_payload_state(state, port);5314 if (!payload)5315 return 0;5316 5317 /*5318 * This could happen if the sink deasserted its HPD line, but5319 * the branch device still reports it as attached (PDT != NONE).5320 */5321 if (!port->full_pbn) {5322 drm_dbg_atomic(port->mgr->dev,5323 "[MSTB:%p] [MST PORT:%p] no BW available for the port\n",5324 port->parent, port);5325 *failing_port = port;5326 return -EINVAL;5327 }5328 5329 pbn_used = payload->pbn;5330 } else {5331 pbn_used = drm_dp_mst_atomic_check_mstb_bw_limit(port->mstb,5332 state,5333 failing_port);5334 if (pbn_used <= 0)5335 return pbn_used;5336 }5337 5338 if (pbn_used > port->full_pbn) {5339 drm_dbg_atomic(port->mgr->dev,5340 "[MSTB:%p] [MST PORT:%p] required PBN of %d exceeds port limit of %d\n",5341 port->parent, port, pbn_used, port->full_pbn);5342 *failing_port = port;5343 return -ENOSPC;5344 }5345 5346 drm_dbg_atomic(port->mgr->dev, "[MSTB:%p] [MST PORT:%p] uses %d out of %d PBN\n",5347 port->parent, port, pbn_used, port->full_pbn);5348 5349 return pbn_used;5350}5351 5352static inline int5353drm_dp_mst_atomic_check_payload_alloc_limits(struct drm_dp_mst_topology_mgr *mgr,5354 struct drm_dp_mst_topology_state *mst_state)5355{5356 struct drm_dp_mst_atomic_payload *payload;5357 int avail_slots = mst_state->total_avail_slots, payload_count = 0;5358 5359 list_for_each_entry(payload, &mst_state->payloads, next) {5360 /* Releasing payloads is always OK-even if the port is gone */5361 if (payload->delete) {5362 drm_dbg_atomic(mgr->dev, "[MST PORT:%p] releases all time slots\n",5363 payload->port);5364 continue;5365 }5366 5367 drm_dbg_atomic(mgr->dev, "[MST PORT:%p] requires %d time slots\n",5368 payload->port, payload->time_slots);5369 5370 avail_slots -= payload->time_slots;5371 if (avail_slots < 0) {5372 drm_dbg_atomic(mgr->dev,5373 "[MST PORT:%p] not enough time slots in mst state %p (avail=%d)\n",5374 payload->port, mst_state, avail_slots + payload->time_slots);5375 return -ENOSPC;5376 }5377 5378 if (++payload_count > mgr->max_payloads) {5379 drm_dbg_atomic(mgr->dev,5380 "[MST MGR:%p] state %p has too many payloads (max=%d)\n",5381 mgr, mst_state, mgr->max_payloads);5382 return -EINVAL;5383 }5384 5385 /* Assign a VCPI */5386 if (!payload->vcpi) {5387 payload->vcpi = ffz(mst_state->payload_mask) + 1;5388 drm_dbg_atomic(mgr->dev, "[MST PORT:%p] assigned VCPI #%d\n",5389 payload->port, payload->vcpi);5390 mst_state->payload_mask |= BIT(payload->vcpi - 1);5391 }5392 }5393 5394 if (!payload_count)5395 mst_state->pbn_div.full = dfixed_const(0);5396 5397 drm_dbg_atomic(mgr->dev, "[MST MGR:%p] mst state %p TU pbn_div=%d avail=%d used=%d\n",5398 mgr, mst_state, dfixed_trunc(mst_state->pbn_div), avail_slots,5399 mst_state->total_avail_slots - avail_slots);5400 5401 return 0;5402}5403 5404/**5405 * drm_dp_mst_add_affected_dsc_crtcs5406 * @state: Pointer to the new struct drm_dp_mst_topology_state5407 * @mgr: MST topology manager5408 *5409 * Whenever there is a change in mst topology5410 * DSC configuration would have to be recalculated5411 * therefore we need to trigger modeset on all affected5412 * CRTCs in that topology5413 *5414 * See also:5415 * drm_dp_mst_atomic_enable_dsc()5416 */5417int drm_dp_mst_add_affected_dsc_crtcs(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr)5418{5419 struct drm_dp_mst_topology_state *mst_state;5420 struct drm_dp_mst_atomic_payload *pos;5421 struct drm_connector *connector;5422 struct drm_connector_state *conn_state;5423 struct drm_crtc *crtc;5424 struct drm_crtc_state *crtc_state;5425 5426 mst_state = drm_atomic_get_mst_topology_state(state, mgr);5427 5428 if (IS_ERR(mst_state))5429 return PTR_ERR(mst_state);5430 5431 list_for_each_entry(pos, &mst_state->payloads, next) {5432 5433 connector = pos->port->connector;5434 5435 if (!connector)5436 return -EINVAL;5437 5438 conn_state = drm_atomic_get_connector_state(state, connector);5439 5440 if (IS_ERR(conn_state))5441 return PTR_ERR(conn_state);5442 5443 crtc = conn_state->crtc;5444 5445 if (!crtc)5446 continue;5447 5448 if (!drm_dp_mst_dsc_aux_for_port(pos->port))5449 continue;5450 5451 crtc_state = drm_atomic_get_crtc_state(mst_state->base.state, crtc);5452 5453 if (IS_ERR(crtc_state))5454 return PTR_ERR(crtc_state);5455 5456 drm_dbg_atomic(mgr->dev, "[MST MGR:%p] Setting mode_changed flag on CRTC %p\n",5457 mgr, crtc);5458 5459 crtc_state->mode_changed = true;5460 }5461 return 0;5462}5463EXPORT_SYMBOL(drm_dp_mst_add_affected_dsc_crtcs);5464 5465/**5466 * drm_dp_mst_atomic_enable_dsc - Set DSC Enable Flag to On/Off5467 * @state: Pointer to the new drm_atomic_state5468 * @port: Pointer to the affected MST Port5469 * @pbn: Newly recalculated bw required for link with DSC enabled5470 * @enable: Boolean flag to enable or disable DSC on the port5471 *5472 * This function enables DSC on the given Port5473 * by recalculating its vcpi from pbn provided5474 * and sets dsc_enable flag to keep track of which5475 * ports have DSC enabled5476 *5477 */5478int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state,5479 struct drm_dp_mst_port *port,5480 int pbn, bool enable)5481{5482 struct drm_dp_mst_topology_state *mst_state;5483 struct drm_dp_mst_atomic_payload *payload;5484 int time_slots = 0;5485 5486 mst_state = drm_atomic_get_mst_topology_state(state, port->mgr);5487 if (IS_ERR(mst_state))5488 return PTR_ERR(mst_state);5489 5490 payload = drm_atomic_get_mst_payload_state(mst_state, port);5491 if (!payload) {5492 drm_dbg_atomic(state->dev,5493 "[MST PORT:%p] Couldn't find payload in mst state %p\n",5494 port, mst_state);5495 return -EINVAL;5496 }5497 5498 if (payload->dsc_enabled == enable) {5499 drm_dbg_atomic(state->dev,5500 "[MST PORT:%p] DSC flag is already set to %d, returning %d time slots\n",5501 port, enable, payload->time_slots);5502 time_slots = payload->time_slots;5503 }5504 5505 if (enable) {5506 time_slots = drm_dp_atomic_find_time_slots(state, port->mgr, port, pbn);5507 drm_dbg_atomic(state->dev,5508 "[MST PORT:%p] Enabling DSC flag, reallocating %d time slots on the port\n",5509 port, time_slots);5510 if (time_slots < 0)5511 return -EINVAL;5512 }5513 5514 payload->dsc_enabled = enable;5515 5516 return time_slots;5517}5518EXPORT_SYMBOL(drm_dp_mst_atomic_enable_dsc);5519 5520/**5521 * drm_dp_mst_atomic_check_mgr - Check the atomic state of an MST topology manager5522 * @state: The global atomic state5523 * @mgr: Manager to check5524 * @mst_state: The MST atomic state for @mgr5525 * @failing_port: Returns the port with a BW limitation5526 *5527 * Checks the given MST manager's topology state for an atomic update to ensure5528 * that it's valid. This includes checking whether there's enough bandwidth to5529 * support the new timeslot allocations in the atomic update.5530 *5531 * Any atomic drivers supporting DP MST must make sure to call this or5532 * the drm_dp_mst_atomic_check() function after checking the rest of their state5533 * in their &drm_mode_config_funcs.atomic_check() callback.5534 *5535 * See also:5536 * drm_dp_mst_atomic_check()5537 * drm_dp_atomic_find_time_slots()5538 * drm_dp_atomic_release_time_slots()5539 *5540 * Returns:5541 * - 0 if the new state is valid5542 * - %-ENOSPC, if the new state is invalid, because of BW limitation5543 * @failing_port is set to:5544 *5545 * - The non-root port where a BW limit check failed5546 * with all the ports downstream of @failing_port passing5547 * the BW limit check.5548 * The returned port pointer is valid until at least5549 * one payload downstream of it exists.5550 * - %NULL if the BW limit check failed at the root port5551 * with all the ports downstream of the root port passing5552 * the BW limit check.5553 *5554 * - %-EINVAL, if the new state is invalid, because the root port has5555 * too many payloads.5556 */5557int drm_dp_mst_atomic_check_mgr(struct drm_atomic_state *state,5558 struct drm_dp_mst_topology_mgr *mgr,5559 struct drm_dp_mst_topology_state *mst_state,5560 struct drm_dp_mst_port **failing_port)5561{5562 int ret;5563 5564 *failing_port = NULL;5565 5566 if (!mgr->mst_state)5567 return 0;5568 5569 mutex_lock(&mgr->lock);5570 ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr->mst_primary,5571 mst_state,5572 failing_port);5573 mutex_unlock(&mgr->lock);5574 5575 if (ret < 0)5576 return ret;5577 5578 return drm_dp_mst_atomic_check_payload_alloc_limits(mgr, mst_state);5579}5580EXPORT_SYMBOL(drm_dp_mst_atomic_check_mgr);5581 5582/**5583 * drm_dp_mst_atomic_check - Check that the new state of an MST topology in an5584 * atomic update is valid5585 * @state: Pointer to the new &struct drm_dp_mst_topology_state5586 *5587 * Checks the given topology state for an atomic update to ensure that it's5588 * valid, calling drm_dp_mst_atomic_check_mgr() for all MST manager in the5589 * atomic state. This includes checking whether there's enough bandwidth to5590 * support the new timeslot allocations in the atomic update.5591 *5592 * Any atomic drivers supporting DP MST must make sure to call this after5593 * checking the rest of their state in their5594 * &drm_mode_config_funcs.atomic_check() callback.5595 *5596 * See also:5597 * drm_dp_mst_atomic_check_mgr()5598 * drm_dp_atomic_find_time_slots()5599 * drm_dp_atomic_release_time_slots()5600 *5601 * Returns:5602 * 0 if the new state is valid, negative error code otherwise.5603 */5604int drm_dp_mst_atomic_check(struct drm_atomic_state *state)5605{5606 struct drm_dp_mst_topology_mgr *mgr;5607 struct drm_dp_mst_topology_state *mst_state;5608 int i, ret = 0;5609 5610 for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {5611 struct drm_dp_mst_port *tmp_port;5612 5613 ret = drm_dp_mst_atomic_check_mgr(state, mgr, mst_state, &tmp_port);5614 if (ret)5615 break;5616 }5617 5618 return ret;5619}5620EXPORT_SYMBOL(drm_dp_mst_atomic_check);5621 5622const struct drm_private_state_funcs drm_dp_mst_topology_state_funcs = {5623 .atomic_duplicate_state = drm_dp_mst_duplicate_state,5624 .atomic_destroy_state = drm_dp_mst_destroy_state,5625};5626EXPORT_SYMBOL(drm_dp_mst_topology_state_funcs);5627 5628/**5629 * drm_atomic_get_mst_topology_state: get MST topology state5630 * @state: global atomic state5631 * @mgr: MST topology manager, also the private object in this case5632 *5633 * This function wraps drm_atomic_get_priv_obj_state() passing in the MST atomic5634 * state vtable so that the private object state returned is that of a MST5635 * topology object.5636 *5637 * RETURNS:5638 * The MST topology state or error pointer.5639 */5640struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_atomic_state *state,5641 struct drm_dp_mst_topology_mgr *mgr)5642{5643 return to_dp_mst_topology_state(drm_atomic_get_private_obj_state(state, &mgr->base));5644}5645EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);5646 5647/**5648 * drm_atomic_get_old_mst_topology_state: get old MST topology state in atomic state, if any5649 * @state: global atomic state5650 * @mgr: MST topology manager, also the private object in this case5651 *5652 * This function wraps drm_atomic_get_old_private_obj_state() passing in the MST atomic5653 * state vtable so that the private object state returned is that of a MST5654 * topology object.5655 *5656 * Returns:5657 * The old MST topology state, or NULL if there's no topology state for this MST mgr5658 * in the global atomic state5659 */5660struct drm_dp_mst_topology_state *5661drm_atomic_get_old_mst_topology_state(struct drm_atomic_state *state,5662 struct drm_dp_mst_topology_mgr *mgr)5663{5664 struct drm_private_state *old_priv_state =5665 drm_atomic_get_old_private_obj_state(state, &mgr->base);5666 5667 return old_priv_state ? to_dp_mst_topology_state(old_priv_state) : NULL;5668}5669EXPORT_SYMBOL(drm_atomic_get_old_mst_topology_state);5670 5671/**5672 * drm_atomic_get_new_mst_topology_state: get new MST topology state in atomic state, if any5673 * @state: global atomic state5674 * @mgr: MST topology manager, also the private object in this case5675 *5676 * This function wraps drm_atomic_get_new_private_obj_state() passing in the MST atomic5677 * state vtable so that the private object state returned is that of a MST5678 * topology object.5679 *5680 * Returns:5681 * The new MST topology state, or NULL if there's no topology state for this MST mgr5682 * in the global atomic state5683 */5684struct drm_dp_mst_topology_state *5685drm_atomic_get_new_mst_topology_state(struct drm_atomic_state *state,5686 struct drm_dp_mst_topology_mgr *mgr)5687{5688 struct drm_private_state *new_priv_state =5689 drm_atomic_get_new_private_obj_state(state, &mgr->base);5690 5691 return new_priv_state ? to_dp_mst_topology_state(new_priv_state) : NULL;5692}5693EXPORT_SYMBOL(drm_atomic_get_new_mst_topology_state);5694 5695/**5696 * drm_dp_mst_topology_mgr_init - initialise a topology manager5697 * @mgr: manager struct to initialise5698 * @dev: device providing this structure - for i2c addition.5699 * @aux: DP helper aux channel to talk to this device5700 * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit5701 * @max_payloads: maximum number of payloads this GPU can source5702 * @conn_base_id: the connector object ID the MST device is connected to.5703 *5704 * Return 0 for success, or negative error code on failure5705 */5706int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,5707 struct drm_device *dev, struct drm_dp_aux *aux,5708 int max_dpcd_transaction_bytes, int max_payloads,5709 int conn_base_id)5710{5711 struct drm_dp_mst_topology_state *mst_state;5712 5713 mutex_init(&mgr->lock);5714 mutex_init(&mgr->qlock);5715 mutex_init(&mgr->delayed_destroy_lock);5716 mutex_init(&mgr->up_req_lock);5717 mutex_init(&mgr->probe_lock);5718#if IS_ENABLED(CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS)5719 mutex_init(&mgr->topology_ref_history_lock);5720 stack_depot_init();5721#endif5722 INIT_LIST_HEAD(&mgr->tx_msg_downq);5723 INIT_LIST_HEAD(&mgr->destroy_port_list);5724 INIT_LIST_HEAD(&mgr->destroy_branch_device_list);5725 INIT_LIST_HEAD(&mgr->up_req_list);5726 5727 /*5728 * delayed_destroy_work will be queued on a dedicated WQ, so that any5729 * requeuing will be also flushed when deiniting the topology manager.5730 */5731 mgr->delayed_destroy_wq = alloc_ordered_workqueue("drm_dp_mst_wq", 0);5732 if (mgr->delayed_destroy_wq == NULL)5733 return -ENOMEM;5734 5735 INIT_WORK(&mgr->work, drm_dp_mst_link_probe_work);5736 INIT_WORK(&mgr->tx_work, drm_dp_tx_work);5737 INIT_WORK(&mgr->delayed_destroy_work, drm_dp_delayed_destroy_work);5738 INIT_WORK(&mgr->up_req_work, drm_dp_mst_up_req_work);5739 init_waitqueue_head(&mgr->tx_waitq);5740 mgr->dev = dev;5741 mgr->aux = aux;5742 mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;5743 mgr->max_payloads = max_payloads;5744 mgr->conn_base_id = conn_base_id;5745 5746 mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);5747 if (mst_state == NULL)5748 return -ENOMEM;5749 5750 mst_state->total_avail_slots = 63;5751 mst_state->start_slot = 1;5752 5753 mst_state->mgr = mgr;5754 INIT_LIST_HEAD(&mst_state->payloads);5755 5756 drm_atomic_private_obj_init(dev, &mgr->base,5757 &mst_state->base,5758 &drm_dp_mst_topology_state_funcs);5759 5760 return 0;5761}5762EXPORT_SYMBOL(drm_dp_mst_topology_mgr_init);5763 5764/**5765 * drm_dp_mst_topology_mgr_destroy() - destroy topology manager.5766 * @mgr: manager to destroy5767 */5768void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr)5769{5770 drm_dp_mst_topology_mgr_set_mst(mgr, false);5771 flush_work(&mgr->work);5772 /* The following will also drain any requeued work on the WQ. */5773 if (mgr->delayed_destroy_wq) {5774 destroy_workqueue(mgr->delayed_destroy_wq);5775 mgr->delayed_destroy_wq = NULL;5776 }5777 mgr->dev = NULL;5778 mgr->aux = NULL;5779 drm_atomic_private_obj_fini(&mgr->base);5780 mgr->funcs = NULL;5781 5782 mutex_destroy(&mgr->delayed_destroy_lock);5783 mutex_destroy(&mgr->qlock);5784 mutex_destroy(&mgr->lock);5785 mutex_destroy(&mgr->up_req_lock);5786 mutex_destroy(&mgr->probe_lock);5787#if IS_ENABLED(CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS)5788 mutex_destroy(&mgr->topology_ref_history_lock);5789#endif5790}5791EXPORT_SYMBOL(drm_dp_mst_topology_mgr_destroy);5792 5793static bool remote_i2c_read_ok(const struct i2c_msg msgs[], int num)5794{5795 int i;5796 5797 if (num - 1 > DP_REMOTE_I2C_READ_MAX_TRANSACTIONS)5798 return false;5799 5800 for (i = 0; i < num - 1; i++) {5801 if (msgs[i].flags & I2C_M_RD ||5802 msgs[i].len > 0xff)5803 return false;5804 }5805 5806 return msgs[num - 1].flags & I2C_M_RD &&5807 msgs[num - 1].len <= 0xff;5808}5809 5810static bool remote_i2c_write_ok(const struct i2c_msg msgs[], int num)5811{5812 int i;5813 5814 for (i = 0; i < num - 1; i++) {5815 if (msgs[i].flags & I2C_M_RD || !(msgs[i].flags & I2C_M_STOP) ||5816 msgs[i].len > 0xff)5817 return false;5818 }5819 5820 return !(msgs[num - 1].flags & I2C_M_RD) && msgs[num - 1].len <= 0xff;5821}5822 5823static int drm_dp_mst_i2c_read(struct drm_dp_mst_branch *mstb,5824 struct drm_dp_mst_port *port,5825 struct i2c_msg *msgs, int num)5826{5827 struct drm_dp_mst_topology_mgr *mgr = port->mgr;5828 unsigned int i;5829 struct drm_dp_sideband_msg_req_body msg;5830 struct drm_dp_sideband_msg_tx *txmsg = NULL;5831 int ret;5832 5833 memset(&msg, 0, sizeof(msg));5834 msg.req_type = DP_REMOTE_I2C_READ;5835 msg.u.i2c_read.num_transactions = num - 1;5836 msg.u.i2c_read.port_number = port->port_num;5837 for (i = 0; i < num - 1; i++) {5838 msg.u.i2c_read.transactions[i].i2c_dev_id = msgs[i].addr;5839 msg.u.i2c_read.transactions[i].num_bytes = msgs[i].len;5840 msg.u.i2c_read.transactions[i].bytes = msgs[i].buf;5841 msg.u.i2c_read.transactions[i].no_stop_bit = !(msgs[i].flags & I2C_M_STOP);5842 }5843 msg.u.i2c_read.read_i2c_device_id = msgs[num - 1].addr;5844 msg.u.i2c_read.num_bytes_read = msgs[num - 1].len;5845 5846 txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);5847 if (!txmsg) {5848 ret = -ENOMEM;5849 goto out;5850 }5851 5852 txmsg->dst = mstb;5853 drm_dp_encode_sideband_req(&msg, txmsg);5854 5855 drm_dp_queue_down_tx(mgr, txmsg);5856 5857 ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);5858 if (ret > 0) {5859 5860 if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {5861 ret = -EREMOTEIO;5862 goto out;5863 }5864 if (txmsg->reply.u.remote_i2c_read_ack.num_bytes != msgs[num - 1].len) {5865 ret = -EIO;5866 goto out;5867 }5868 memcpy(msgs[num - 1].buf, txmsg->reply.u.remote_i2c_read_ack.bytes, msgs[num - 1].len);5869 ret = num;5870 }5871out:5872 kfree(txmsg);5873 return ret;5874}5875 5876static int drm_dp_mst_i2c_write(struct drm_dp_mst_branch *mstb,5877 struct drm_dp_mst_port *port,5878 struct i2c_msg *msgs, int num)5879{5880 struct drm_dp_mst_topology_mgr *mgr = port->mgr;5881 unsigned int i;5882 struct drm_dp_sideband_msg_req_body msg;5883 struct drm_dp_sideband_msg_tx *txmsg = NULL;5884 int ret;5885 5886 txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);5887 if (!txmsg) {5888 ret = -ENOMEM;5889 goto out;5890 }5891 for (i = 0; i < num; i++) {5892 memset(&msg, 0, sizeof(msg));5893 msg.req_type = DP_REMOTE_I2C_WRITE;5894 msg.u.i2c_write.port_number = port->port_num;5895 msg.u.i2c_write.write_i2c_device_id = msgs[i].addr;5896 msg.u.i2c_write.num_bytes = msgs[i].len;5897 msg.u.i2c_write.bytes = msgs[i].buf;5898 5899 memset(txmsg, 0, sizeof(*txmsg));5900 txmsg->dst = mstb;5901 5902 drm_dp_encode_sideband_req(&msg, txmsg);5903 drm_dp_queue_down_tx(mgr, txmsg);5904 5905 ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);5906 if (ret > 0) {5907 if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {5908 ret = -EREMOTEIO;5909 goto out;5910 }5911 } else {5912 goto out;5913 }5914 }5915 ret = num;5916out:5917 kfree(txmsg);5918 return ret;5919}5920 5921/* I2C device */5922static int drm_dp_mst_i2c_xfer(struct i2c_adapter *adapter,5923 struct i2c_msg *msgs, int num)5924{5925 struct drm_dp_aux *aux = adapter->algo_data;5926 struct drm_dp_mst_port *port =5927 container_of(aux, struct drm_dp_mst_port, aux);5928 struct drm_dp_mst_branch *mstb;5929 struct drm_dp_mst_topology_mgr *mgr = port->mgr;5930 int ret;5931 5932 mstb = drm_dp_mst_topology_get_mstb_validated(mgr, port->parent);5933 if (!mstb)5934 return -EREMOTEIO;5935 5936 if (remote_i2c_read_ok(msgs, num)) {5937 ret = drm_dp_mst_i2c_read(mstb, port, msgs, num);5938 } else if (remote_i2c_write_ok(msgs, num)) {5939 ret = drm_dp_mst_i2c_write(mstb, port, msgs, num);5940 } else {5941 drm_dbg_kms(mgr->dev, "Unsupported I2C transaction for MST device\n");5942 ret = -EIO;5943 }5944 5945 drm_dp_mst_topology_put_mstb(mstb);5946 return ret;5947}5948 5949static u32 drm_dp_mst_i2c_functionality(struct i2c_adapter *adapter)5950{5951 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |5952 I2C_FUNC_SMBUS_READ_BLOCK_DATA |5953 I2C_FUNC_SMBUS_BLOCK_PROC_CALL |5954 I2C_FUNC_10BIT_ADDR;5955}5956 5957static const struct i2c_algorithm drm_dp_mst_i2c_algo = {5958 .functionality = drm_dp_mst_i2c_functionality,5959 .master_xfer = drm_dp_mst_i2c_xfer,5960};5961 5962/**5963 * drm_dp_mst_register_i2c_bus() - register an I2C adapter for I2C-over-AUX5964 * @port: The port to add the I2C bus on5965 *5966 * Returns 0 on success or a negative error code on failure.5967 */5968static int drm_dp_mst_register_i2c_bus(struct drm_dp_mst_port *port)5969{5970 struct drm_dp_aux *aux = &port->aux;5971 struct device *parent_dev = port->mgr->dev->dev;5972 5973 aux->ddc.algo = &drm_dp_mst_i2c_algo;5974 aux->ddc.algo_data = aux;5975 aux->ddc.retries = 3;5976 5977 aux->ddc.owner = THIS_MODULE;5978 /* FIXME: set the kdev of the port's connector as parent */5979 aux->ddc.dev.parent = parent_dev;5980 aux->ddc.dev.of_node = parent_dev->of_node;5981 5982 strscpy(aux->ddc.name, aux->name ? aux->name : dev_name(parent_dev),5983 sizeof(aux->ddc.name));5984 5985 return i2c_add_adapter(&aux->ddc);5986}5987 5988/**5989 * drm_dp_mst_unregister_i2c_bus() - unregister an I2C-over-AUX adapter5990 * @port: The port to remove the I2C bus from5991 */5992static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_mst_port *port)5993{5994 i2c_del_adapter(&port->aux.ddc);5995}5996 5997/**5998 * drm_dp_mst_is_virtual_dpcd() - Is the given port a virtual DP Peer Device5999 * @port: The port to check6000 *6001 * A single physical MST hub object can be represented in the topology6002 * by multiple branches, with virtual ports between those branches.6003 *6004 * As of DP1.4, An MST hub with internal (virtual) ports must expose6005 * certain DPCD registers over those ports. See sections 2.6.1.1.16006 * and 2.6.1.1.2 of Display Port specification v1.4 for details.6007 *6008 * May acquire mgr->lock6009 *6010 * Returns:6011 * true if the port is a virtual DP peer device, false otherwise6012 */6013static bool drm_dp_mst_is_virtual_dpcd(struct drm_dp_mst_port *port)6014{6015 struct drm_dp_mst_port *downstream_port;6016 6017 if (!port || port->dpcd_rev < DP_DPCD_REV_14)6018 return false;6019 6020 /* Virtual DP Sink (Internal Display Panel) */6021 if (drm_dp_mst_port_is_logical(port))6022 return true;6023 6024 /* DP-to-HDMI Protocol Converter */6025 if (port->pdt == DP_PEER_DEVICE_DP_LEGACY_CONV &&6026 !port->mcs &&6027 port->ldps)6028 return true;6029 6030 /* DP-to-DP */6031 mutex_lock(&port->mgr->lock);6032 if (port->pdt == DP_PEER_DEVICE_MST_BRANCHING &&6033 port->mstb &&6034 port->mstb->num_ports == 2) {6035 list_for_each_entry(downstream_port, &port->mstb->ports, next) {6036 if (downstream_port->pdt == DP_PEER_DEVICE_SST_SINK &&6037 !downstream_port->input) {6038 mutex_unlock(&port->mgr->lock);6039 return true;6040 }6041 }6042 }6043 mutex_unlock(&port->mgr->lock);6044 6045 return false;6046}6047 6048/**6049 * drm_dp_mst_aux_for_parent() - Get the AUX device for an MST port's parent6050 * @port: MST port whose parent's AUX device is returned6051 *6052 * Return the AUX device for @port's parent or NULL if port's parent is the6053 * root port.6054 */6055struct drm_dp_aux *drm_dp_mst_aux_for_parent(struct drm_dp_mst_port *port)6056{6057 if (!port->parent || !port->parent->port_parent)6058 return NULL;6059 6060 return &port->parent->port_parent->aux;6061}6062EXPORT_SYMBOL(drm_dp_mst_aux_for_parent);6063 6064/**6065 * drm_dp_mst_dsc_aux_for_port() - Find the correct aux for DSC6066 * @port: The port to check. A leaf of the MST tree with an attached display.6067 *6068 * Depending on the situation, DSC may be enabled via the endpoint aux,6069 * the immediately upstream aux, or the connector's physical aux.6070 *6071 * This is both the correct aux to read DSC_CAPABILITY and the6072 * correct aux to write DSC_ENABLED.6073 *6074 * This operation can be expensive (up to four aux reads), so6075 * the caller should cache the return.6076 *6077 * Returns:6078 * NULL if DSC cannot be enabled on this port, otherwise the aux device6079 */6080struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)6081{6082 struct drm_dp_mst_port *immediate_upstream_port;6083 struct drm_dp_aux *immediate_upstream_aux;6084 struct drm_dp_mst_port *fec_port;6085 struct drm_dp_desc desc = {};6086 u8 upstream_dsc;6087 u8 endpoint_fec;6088 u8 endpoint_dsc;6089 6090 if (!port)6091 return NULL;6092 6093 if (port->parent->port_parent)6094 immediate_upstream_port = port->parent->port_parent;6095 else6096 immediate_upstream_port = NULL;6097 6098 fec_port = immediate_upstream_port;6099 while (fec_port) {6100 /*6101 * Each physical link (i.e. not a virtual port) between the6102 * output and the primary device must support FEC6103 */6104 if (!drm_dp_mst_is_virtual_dpcd(fec_port) &&6105 !fec_port->fec_capable)6106 return NULL;6107 6108 fec_port = fec_port->parent->port_parent;6109 }6110 6111 /* DP-to-DP peer device */6112 if (drm_dp_mst_is_virtual_dpcd(immediate_upstream_port)) {6113 if (drm_dp_dpcd_read(&port->aux,6114 DP_DSC_SUPPORT, &endpoint_dsc, 1) != 1)6115 return NULL;6116 if (drm_dp_dpcd_read(&port->aux,6117 DP_FEC_CAPABILITY, &endpoint_fec, 1) != 1)6118 return NULL;6119 if (drm_dp_dpcd_read(&immediate_upstream_port->aux,6120 DP_DSC_SUPPORT, &upstream_dsc, 1) != 1)6121 return NULL;6122 6123 /* Enpoint decompression with DP-to-DP peer device */6124 if ((endpoint_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED) &&6125 (endpoint_fec & DP_FEC_CAPABLE) &&6126 (upstream_dsc & DP_DSC_PASSTHROUGH_IS_SUPPORTED)) {6127 port->passthrough_aux = &immediate_upstream_port->aux;6128 return &port->aux;6129 }6130 6131 /* Virtual DPCD decompression with DP-to-DP peer device */6132 return &immediate_upstream_port->aux;6133 }6134 6135 /* Virtual DPCD decompression with DP-to-HDMI or Virtual DP Sink */6136 if (drm_dp_mst_is_virtual_dpcd(port))6137 return &port->aux;6138 6139 /*6140 * Synaptics quirk6141 * Applies to ports for which:6142 * - Physical aux has Synaptics OUI6143 * - DPv1.4 or higher6144 * - Port is on primary branch device6145 * - Not a VGA adapter (DP_DWN_STRM_PORT_TYPE_ANALOG)6146 */6147 if (immediate_upstream_port)6148 immediate_upstream_aux = &immediate_upstream_port->aux;6149 else6150 immediate_upstream_aux = port->mgr->aux;6151 6152 if (drm_dp_read_desc(immediate_upstream_aux, &desc, true))6153 return NULL;6154 6155 if (drm_dp_has_quirk(&desc, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD)) {6156 u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];6157 6158 if (drm_dp_dpcd_read(immediate_upstream_aux,6159 DP_DSC_SUPPORT, &upstream_dsc, 1) != 1)6160 return NULL;6161 6162 if (!(upstream_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED))6163 return NULL;6164 6165 if (drm_dp_read_dpcd_caps(immediate_upstream_aux, dpcd_ext) < 0)6166 return NULL;6167 6168 if (dpcd_ext[DP_DPCD_REV] >= DP_DPCD_REV_14 &&6169 ((dpcd_ext[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT) &&6170 ((dpcd_ext[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_TYPE_MASK)6171 != DP_DWN_STRM_PORT_TYPE_ANALOG)))6172 return immediate_upstream_aux;6173 }6174 6175 /*6176 * The check below verifies if the MST sink6177 * connected to the GPU is capable of DSC -6178 * therefore the endpoint needs to be6179 * both DSC and FEC capable.6180 */6181 if (drm_dp_dpcd_read(&port->aux,6182 DP_DSC_SUPPORT, &endpoint_dsc, 1) != 1)6183 return NULL;6184 if (drm_dp_dpcd_read(&port->aux,6185 DP_FEC_CAPABILITY, &endpoint_fec, 1) != 1)6186 return NULL;6187 if ((endpoint_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED) &&6188 (endpoint_fec & DP_FEC_CAPABLE))6189 return &port->aux;6190 6191 return NULL;6192}6193EXPORT_SYMBOL(drm_dp_mst_dsc_aux_for_port);6194