Skip to content

Commit

Permalink
drm/dp_mst: Reprobe path resources in CSN handler
Browse files Browse the repository at this point in the history
We used to punt off reprobing path resources to the link address probe
work, but now that we handle CSNs asynchronously from the driver's HPD
handling we can do whatever the heck we want from the CSN!

So, reprobe the path resources from drm_dp_mst_handle_conn_stat(). Also,
get rid of the path resource reprobing code in
drm_dp_check_and_send_link_address() since it's needlessly complicated
when we already reprobe path resources from
drm_dp_handle_link_address_port(). And finally, teach
drm_dp_send_enum_path_resources() to return 1 on PBN changes so we know
if we need to send another hotplug or not.

This fixes issues where we've indicated to userspace that a port has
just been connected, before we actually probed it's available PBN -
something that results in unexpected atomic check failures.

Signed-off-by: Lyude Paul <lyude@redhat.com>
Fixes: cd82d82 ("drm/dp_mst: Add branch bandwidth validation to MST atomic check")
Cc: Mikita Lipski <mikita.lipski@amd.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Sean Paul <sean@poorly.run>
Link: https://patchwork.freedesktop.org/patch/msgid/20200306234623.547525-4-lyude@redhat.com
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Tested-by: Hans de Goede <hdegoede@redhat.com>
  • Loading branch information
Lyude Paul committed Mar 12, 2020
1 parent fcf4638 commit 87212b5
Showing 1 changed file with 25 additions and 23 deletions.
48 changes: 25 additions & 23 deletions drivers/gpu/drm/drm_dp_mst_topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -2302,12 +2302,16 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,
mutex_unlock(&mgr->lock);
}

if (old_ddps != port->ddps) {
if (port->ddps) {
if (!port->input) {
drm_dp_send_enum_path_resources(mgr, mstb,
port);
}
/*
* Reprobe PBN caps on both hotplug, and when re-probing the link
* for our parent mstb
*/
if (old_ddps != port->ddps || !created) {
if (port->ddps && !port->input) {
ret = drm_dp_send_enum_path_resources(mgr, mstb,
port);
if (ret == 1)
changed = true;
} else {
port->full_pbn = 0;
}
Expand Down Expand Up @@ -2401,11 +2405,10 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
port->ddps = conn_stat->displayport_device_plug_status;

if (old_ddps != port->ddps) {
if (port->ddps) {
dowork = true;
} else {
if (port->ddps && !port->input)
drm_dp_send_enum_path_resources(mgr, mstb, port);
else
port->full_pbn = 0;
}
}

new_pdt = port->input ? DP_PEER_DEVICE_NONE : conn_stat->peer_device_type;
Expand Down Expand Up @@ -2556,13 +2559,6 @@ static int drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *mg
if (port->input || !port->ddps)
continue;

if (!port->full_pbn) {
drm_modeset_lock(&mgr->base.lock, NULL);
drm_dp_send_enum_path_resources(mgr, mstb, port);
drm_modeset_unlock(&mgr->base.lock);
changed = true;
}

if (port->mstb)
mstb_child = drm_dp_mst_topology_get_mstb_validated(
mgr, port->mstb);
Expand Down Expand Up @@ -2990,6 +2986,7 @@ drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr,

ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
if (ret > 0) {
ret = 0;
path_res = &txmsg->reply.u.path_resources;

if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
Expand All @@ -3002,13 +2999,22 @@ drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr,
path_res->port_number,
path_res->full_payload_bw_number,
path_res->avail_payload_bw_number);

/*
* If something changed, make sure we send a
* hotplug
*/
if (port->full_pbn != path_res->full_payload_bw_number ||
port->fec_capable != path_res->fec_capable)
ret = 1;

port->full_pbn = path_res->full_payload_bw_number;
port->fec_capable = path_res->fec_capable;
}
}

kfree(txmsg);
return 0;
return ret;
}

static struct drm_dp_mst_port *drm_dp_get_last_connected_port_to_mstb(struct drm_dp_mst_branch *mstb)
Expand Down Expand Up @@ -3595,13 +3601,9 @@ drm_dp_mst_topology_mgr_invalidate_mstb(struct drm_dp_mst_branch *mstb)
/* The link address will need to be re-sent on resume */
mstb->link_address_sent = false;

list_for_each_entry(port, &mstb->ports, next) {
/* The PBN for each port will also need to be re-probed */
port->full_pbn = 0;

list_for_each_entry(port, &mstb->ports, next)
if (port->mstb)
drm_dp_mst_topology_mgr_invalidate_mstb(port->mstb);
}
}

/**
Expand Down

0 comments on commit 87212b5

Please sign in to comment.