Commit fa3cdf8d authored by Lyude Paul's avatar Lyude Paul Committed by Ben Skeggs

drm/nouveau: Reset MST branching unit before enabling

When probing a new MST device, it's not safe to make any assumptions
about it's current state. While most well mannered MST hubs will just
disable the branching unit on hotplug disconnects, this isn't enough to
save us from various other scenarios that might have resulted in
something writing to the MST branching unit before we got control of it.
This could happen if a previous probe we tried failed, if we're booting
in kexec context and the hub is still in the state the last kernel put
it in, etc.

Luckily; there is no reason we can't just reset the branching unit
every time we enable a new topology. So, fix this by resetting it on
enabling new topologies to ensure that we always start off with a clean,
unmodified topology state on MST sinks.

This fixes occasional hard-lockups on my P50's laptop dock (e.g. AUX
times out all DPCD trasactions) observed after multiple docks, undocks,
and module reloads.
Signed-off-by: default avatarLyude Paul <lyude@redhat.com>
Cc: stable@vger.kernel.org
Cc: Karol Herbst <karolherbst@gmail.com>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent b26b4590
...@@ -1123,18 +1123,22 @@ nv50_mstm_enable(struct nv50_mstm *mstm, u8 dpcd, int state) ...@@ -1123,18 +1123,22 @@ nv50_mstm_enable(struct nv50_mstm *mstm, u8 dpcd, int state)
int ret; int ret;
if (dpcd >= 0x12) { if (dpcd >= 0x12) {
ret = drm_dp_dpcd_readb(mstm->mgr.aux, DP_MSTM_CTRL, &dpcd); /* Even if we're enabling MST, start with disabling the
* branching unit to clear any sink-side MST topology state
* that wasn't set by us
*/
ret = drm_dp_dpcd_writeb(mstm->mgr.aux, DP_MSTM_CTRL, 0);
if (ret < 0) if (ret < 0)
return ret; return ret;
dpcd &= ~DP_MST_EN; if (state) {
if (state) /* Now, start initializing */
dpcd |= DP_MST_EN; ret = drm_dp_dpcd_writeb(mstm->mgr.aux, DP_MSTM_CTRL,
DP_MST_EN);
ret = drm_dp_dpcd_writeb(mstm->mgr.aux, DP_MSTM_CTRL, dpcd);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
}
return nvif_mthd(disp, 0, &args, sizeof(args)); return nvif_mthd(disp, 0, &args, sizeof(args));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment