Skip to content

Commit 87212b5

Browse files
committed
drm/dp_mst: Reprobe path resources in CSN handler
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 <[email protected]> Fixes: cd82d82 ("drm/dp_mst: Add branch bandwidth validation to MST atomic check") Cc: Mikita Lipski <[email protected]> Cc: Hans de Goede <[email protected]> Cc: Sean Paul <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Reviewed-by: Alex Deucher <[email protected]> Tested-by: Hans de Goede <[email protected]>
1 parent fcf4638 commit 87212b5

File tree

1 file changed

+25
-23
lines changed

1 file changed

+25
-23
lines changed

drivers/gpu/drm/drm_dp_mst_topology.c

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2302,12 +2302,16 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,
23022302
mutex_unlock(&mgr->lock);
23032303
}
23042304

2305-
if (old_ddps != port->ddps) {
2306-
if (port->ddps) {
2307-
if (!port->input) {
2308-
drm_dp_send_enum_path_resources(mgr, mstb,
2309-
port);
2310-
}
2305+
/*
2306+
* Reprobe PBN caps on both hotplug, and when re-probing the link
2307+
* for our parent mstb
2308+
*/
2309+
if (old_ddps != port->ddps || !created) {
2310+
if (port->ddps && !port->input) {
2311+
ret = drm_dp_send_enum_path_resources(mgr, mstb,
2312+
port);
2313+
if (ret == 1)
2314+
changed = true;
23112315
} else {
23122316
port->full_pbn = 0;
23132317
}
@@ -2401,11 +2405,10 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
24012405
port->ddps = conn_stat->displayport_device_plug_status;
24022406

24032407
if (old_ddps != port->ddps) {
2404-
if (port->ddps) {
2405-
dowork = true;
2406-
} else {
2408+
if (port->ddps && !port->input)
2409+
drm_dp_send_enum_path_resources(mgr, mstb, port);
2410+
else
24072411
port->full_pbn = 0;
2408-
}
24092412
}
24102413

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

2559-
if (!port->full_pbn) {
2560-
drm_modeset_lock(&mgr->base.lock, NULL);
2561-
drm_dp_send_enum_path_resources(mgr, mstb, port);
2562-
drm_modeset_unlock(&mgr->base.lock);
2563-
changed = true;
2564-
}
2565-
25662562
if (port->mstb)
25672563
mstb_child = drm_dp_mst_topology_get_mstb_validated(
25682564
mgr, port->mstb);
@@ -2990,6 +2986,7 @@ drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr,
29902986

29912987
ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
29922988
if (ret > 0) {
2989+
ret = 0;
29932990
path_res = &txmsg->reply.u.path_resources;
29942991

29952992
if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
@@ -3002,13 +2999,22 @@ drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr,
30022999
path_res->port_number,
30033000
path_res->full_payload_bw_number,
30043001
path_res->avail_payload_bw_number);
3002+
3003+
/*
3004+
* If something changed, make sure we send a
3005+
* hotplug
3006+
*/
3007+
if (port->full_pbn != path_res->full_payload_bw_number ||
3008+
port->fec_capable != path_res->fec_capable)
3009+
ret = 1;
3010+
30053011
port->full_pbn = path_res->full_payload_bw_number;
30063012
port->fec_capable = path_res->fec_capable;
30073013
}
30083014
}
30093015

30103016
kfree(txmsg);
3011-
return 0;
3017+
return ret;
30123018
}
30133019

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

3598-
list_for_each_entry(port, &mstb->ports, next) {
3599-
/* The PBN for each port will also need to be re-probed */
3600-
port->full_pbn = 0;
3601-
3604+
list_for_each_entry(port, &mstb->ports, next)
36023605
if (port->mstb)
36033606
drm_dp_mst_topology_mgr_invalidate_mstb(port->mstb);
3604-
}
36053607
}
36063608

36073609
/**

0 commit comments

Comments
 (0)