Skip to content

Commit 64e62bd

Browse files
Wayne LinLyude
authored andcommitted
drm/dp_mst: Remove VCPI while disabling topology mgr
[Why] This patch is trying to address the issue observed when hotplug DP daisy chain monitors. e.g. src-mstb-mstb-sst -> src (unplug) mstb-mstb-sst -> src-mstb-mstb-sst (plug in again) Once unplug a DP MST capable device, driver will call drm_dp_mst_topology_mgr_set_mst() to disable MST. In this function, it cleans data of topology manager while disabling mst_state. However, it doesn't clean up the proposed_vcpis of topology manager. If proposed_vcpi is not reset, once plug in MST daisy chain monitors later, code will fail at checking port validation while trying to allocate payloads. When MST capable device is plugged in again and try to allocate payloads by calling drm_dp_update_payload_part1(), this function will iterate over all proposed virtual channels to see if any proposed VCPI's num_slots is greater than 0. If any proposed VCPI's num_slots is greater than 0 and the port which the specific virtual channel directed to is not in the topology, code then fails at the port validation. Since there are stale VCPI allocations from the previous topology enablement in proposed_vcpi[], code will fail at port validation and reurn EINVAL. [How] Clean up the data of stale proposed_vcpi[] and reset mgr->proposed_vcpis to NULL while disabling mst in drm_dp_mst_topology_mgr_set_mst(). Changes since v1: *Add on more details in commit message to describe the issue which the patch is trying to fix Signed-off-by: Wayne Lin <[email protected]> [added cc to stable] Signed-off-by: Lyude Paul <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Cc: <[email protected]> # v3.17+
1 parent bc1152b commit 64e62bd

File tree

1 file changed

+13
-0
lines changed

1 file changed

+13
-0
lines changed

drivers/gpu/drm/drm_dp_mst_topology.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3054,6 +3054,7 @@ static int drm_dp_get_vc_payload_bw(u8 dp_link_bw, u8 dp_link_count)
30543054
int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool mst_state)
30553055
{
30563056
int ret = 0;
3057+
int i = 0;
30573058
struct drm_dp_mst_branch *mstb = NULL;
30583059

30593060
mutex_lock(&mgr->lock);
@@ -3114,10 +3115,22 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms
31143115
/* this can fail if the device is gone */
31153116
drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL, 0);
31163117
ret = 0;
3118+
mutex_lock(&mgr->payload_lock);
31173119
memset(mgr->payloads, 0, mgr->max_payloads * sizeof(struct drm_dp_payload));
31183120
mgr->payload_mask = 0;
31193121
set_bit(0, &mgr->payload_mask);
3122+
for (i = 0; i < mgr->max_payloads; i++) {
3123+
struct drm_dp_vcpi *vcpi = mgr->proposed_vcpis[i];
3124+
3125+
if (vcpi) {
3126+
vcpi->vcpi = 0;
3127+
vcpi->num_slots = 0;
3128+
}
3129+
mgr->proposed_vcpis[i] = NULL;
3130+
}
31203131
mgr->vcpi_mask = 0;
3132+
mutex_unlock(&mgr->payload_lock);
3133+
31213134
mgr->payload_id_table_cleared = false;
31223135
}
31233136

0 commit comments

Comments
 (0)