973
973
static u8 drm_dp_calculate_rad(struct drm_dp_mst_port *port,
976
int lct = port->parent->lct;
976
int parent_lct = port->parent->lct;
980
memcpy(rad, port->parent->rad, idx);
981
shift = (lct % 2) ? 4 : 0;
978
int idx = (parent_lct - 1) / 2;
979
if (parent_lct > 1) {
980
memcpy(rad, port->parent->rad, idx + 1);
981
shift = (parent_lct % 2) ? 4 : 0;
985
985
rad[idx] |= port->port_num << shift;
986
return parent_lct + 1;
1039
1039
snprintf(proppath, proppath_size, "mst:%d", mstb->mgr->conn_base_id);
1040
1040
for (i = 0; i < (mstb->lct - 1); i++) {
1041
1041
int shift = (i % 2) ? 0 : 4;
1042
int port_num = mstb->rad[i / 2] >> shift;
1042
int port_num = (mstb->rad[i / 2] >> shift) & 0xf;
1043
1043
snprintf(temp, sizeof(temp), "-%d", port_num);
1044
1044
strlcat(proppath, temp, proppath_size);
1212
static struct drm_dp_mst_branch *get_mst_branch_device_by_guid_helper(
1213
struct drm_dp_mst_branch *mstb,
1216
struct drm_dp_mst_branch *found_mstb;
1217
struct drm_dp_mst_port *port;
1219
list_for_each_entry(port, &mstb->ports, next) {
1223
if (port->guid_valid && memcmp(port->guid, guid, 16) == 0)
1226
found_mstb = get_mst_branch_device_by_guid_helper(port->mstb, guid);
1235
static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device_by_guid(
1236
struct drm_dp_mst_topology_mgr *mgr,
1239
struct drm_dp_mst_branch *mstb;
1241
/* find the port by iterating down */
1242
mutex_lock(&mgr->lock);
1244
if (mgr->guid_valid && memcmp(mgr->guid, guid, 16) == 0)
1245
mstb = mgr->mst_primary;
1247
mstb = get_mst_branch_device_by_guid_helper(mgr->mst_primary, guid);
1250
kref_get(&mstb->kref);
1252
mutex_unlock(&mgr->lock);
1212
1256
static void drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
1213
1257
struct drm_dp_mst_branch *mstb)
1440
1491
/* called holding qlock */
1441
static void process_single_up_tx_qlock(struct drm_dp_mst_topology_mgr *mgr)
1492
static void process_single_up_tx_qlock(struct drm_dp_mst_topology_mgr *mgr,
1493
struct drm_dp_sideband_msg_tx *txmsg)
1443
struct drm_dp_sideband_msg_tx *txmsg;
1446
1497
/* construct a chunk from the first msg in the tx_msg queue */
1447
if (list_empty(&mgr->tx_msg_upq)) {
1448
mgr->tx_up_in_progress = false;
1452
txmsg = list_first_entry(&mgr->tx_msg_upq, struct drm_dp_sideband_msg_tx, next);
1453
1498
ret = process_single_tx_qlock(mgr, txmsg, true);
1455
/* up txmsgs aren't put in slots - so free after we send it */
1456
list_del(&txmsg->next);
1459
1501
DRM_DEBUG_KMS("failed to send msg in q %d\n", ret);
1460
mgr->tx_up_in_progress = true;
1503
txmsg->dst->tx_slots[txmsg->seqno] = NULL;
1463
1506
static void drm_dp_queue_down_tx(struct drm_dp_mst_topology_mgr *mgr,
2144
2188
if (mgr->up_req_recv.have_eomt) {
2145
2189
struct drm_dp_sideband_msg_req_body msg;
2146
struct drm_dp_mst_branch *mstb;
2190
struct drm_dp_mst_branch *mstb = NULL;
2148
mstb = drm_dp_get_mst_branch_device(mgr,
2149
mgr->up_req_recv.initial_hdr.lct,
2150
mgr->up_req_recv.initial_hdr.rad);
2152
DRM_DEBUG_KMS("Got MST reply from unknown device %d\n", mgr->up_req_recv.initial_hdr.lct);
2153
memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
2193
if (!mgr->up_req_recv.initial_hdr.broadcast) {
2194
mstb = drm_dp_get_mst_branch_device(mgr,
2195
mgr->up_req_recv.initial_hdr.lct,
2196
mgr->up_req_recv.initial_hdr.rad);
2198
DRM_DEBUG_KMS("Got MST reply from unknown device %d\n", mgr->up_req_recv.initial_hdr.lct);
2199
memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
2157
2204
seqno = mgr->up_req_recv.initial_hdr.seqno;
2158
2205
drm_dp_sideband_parse_req(&mgr->up_req_recv, &msg);
2160
2207
if (msg.req_type == DP_CONNECTION_STATUS_NOTIFY) {
2161
drm_dp_send_up_ack_reply(mgr, mstb, msg.req_type, seqno, false);
2208
drm_dp_send_up_ack_reply(mgr, mgr->mst_primary, msg.req_type, seqno, false);
2211
mstb = drm_dp_get_mst_branch_device_by_guid(mgr, msg.u.conn_stat.guid);
2214
DRM_DEBUG_KMS("Got MST reply from unknown device %d\n", mgr->up_req_recv.initial_hdr.lct);
2215
memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
2162
2219
drm_dp_update_port(mstb, &msg.u.conn_stat);
2163
2220
DRM_DEBUG_KMS("Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n", msg.u.conn_stat.port_number, msg.u.conn_stat.legacy_device_plug_status, msg.u.conn_stat.displayport_device_plug_status, msg.u.conn_stat.message_capability_status, msg.u.conn_stat.input_port, msg.u.conn_stat.peer_device_type);
2164
2221
(*mgr->cbs->hotplug)(mgr);
2166
2223
} else if (msg.req_type == DP_RESOURCE_STATUS_NOTIFY) {
2167
drm_dp_send_up_ack_reply(mgr, mstb, msg.req_type, seqno, false);
2224
drm_dp_send_up_ack_reply(mgr, mgr->mst_primary, msg.req_type, seqno, false);
2226
mstb = drm_dp_get_mst_branch_device_by_guid(mgr, msg.u.resource_stat.guid);
2229
DRM_DEBUG_KMS("Got MST reply from unknown device %d\n", mgr->up_req_recv.initial_hdr.lct);
2230
memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
2168
2234
DRM_DEBUG_KMS("Got RSN: pn: %d avail_pbn %d\n", msg.u.resource_stat.port_number, msg.u.resource_stat.available_pbn);