diff options
author | Imre Deak <imre.deak@intel.com> | 2020-06-04 21:45:00 +0300 |
---|---|---|
committer | Imre Deak <imre.deak@intel.com> | 2020-06-11 15:28:45 +0300 |
commit | 471bdd0df0d5048d1e1bb0aa5da44f44f9856fb1 (patch) | |
tree | c920186c90a281f14e9f99c2c06e6f50e904a305 /drivers/gpu/drm/drm_dp_mst_topology.c | |
parent | 8b9f3437ff5b5d059f70f9ce44d169b0cc5650ee (diff) |
drm/i915/dp_mst: Work around out-of-spec adapters filtering short pulses
Some TypeC -> native DP adapters, at least the Club 3D CAC-1557 adapter,
incorrectly filter out HPD short pulses with a duration less than
~540 usec, leading to MST probe failures.
According to the DP Standard 2.0 section 5.1.4:
- DP sinks should generate short pulses in the 500 usec -> 1 msec range
- DP sources should detect short pulses in the 250 usec -> 2 msec range
According to the DP Alt Mode on TypeC Standard section 3.9.2, adapters
should detect and forward short pulses according to how sources should
detect them as specified in the DP Standard (250 usec -> 2 msec).
Based on the above filtering out short pulses with a duration less than
540 usec is incorrect.
To make such adapters work add support for a driver polling on MST
inerrupt flags, and wire this up in the i915 driver. The sink can clear
an interrupt it raised after 110 msec if the source doesn't respond, so
use a 50 msec poll period to avoid missing an interrupt. Polling of the
MST interrupt flags is explicitly allowed by the DP Standard.
This fixes MST probe failures I saw using this adapter and a DELL U2515H
monitor.
v2:
- Fix the wait event timeout for the no-poll case.
v3 (Ville):
- Fix the short pulse duration limits in the commit log prescribed by the
DP Standard.
- Add code comment explaining why/how polling is used.
- Factor out a helper to schedule the port's hpd irq handler and move it
to the rest of hotplug handlers.
- Document the new MST callback.
- s/update_hpd_irq_state/poll_hpd_irq/
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200604184500.23730-2-imre.deak@intel.com
Diffstat (limited to 'drivers/gpu/drm/drm_dp_mst_topology.c')
-rw-r--r-- | drivers/gpu/drm/drm_dp_mst_topology.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 469d3569d5ca..ca936ef41312 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -1178,11 +1178,37 @@ static int drm_dp_mst_wait_tx_reply(struct drm_dp_mst_branch *mstb, struct drm_dp_sideband_msg_tx *txmsg) { struct drm_dp_mst_topology_mgr *mgr = mstb->mgr; + unsigned long wait_timeout = msecs_to_jiffies(4000); + unsigned long wait_expires = jiffies + wait_timeout; int ret; - ret = wait_event_timeout(mgr->tx_waitq, - check_txmsg_state(mgr, txmsg), - (4 * HZ)); + for (;;) { + /* + * If the driver provides a way for this, change to + * poll-waiting for the MST reply interrupt if we didn't receive + * it for 50 msec. This would cater for cases where the HPD + * pulse signal got lost somewhere, even though the sink raised + * the corresponding MST interrupt correctly. One example is the + * Club 3D CAC-1557 TypeC -> DP adapter which for some reason + * filters out short pulses with a duration less than ~540 usec. + * + * The poll period is 50 msec to avoid missing an interrupt + * after the sink has cleared it (after a 110msec timeout + * since it raised the interrupt). + */ + ret = wait_event_timeout(mgr->tx_waitq, + check_txmsg_state(mgr, txmsg), + mgr->cbs->poll_hpd_irq ? + msecs_to_jiffies(50) : + wait_timeout); + + if (ret || !mgr->cbs->poll_hpd_irq || + time_after(jiffies, wait_expires)) + break; + + mgr->cbs->poll_hpd_irq(mgr); + } + mutex_lock(&mgr->qlock); if (ret > 0) { if (txmsg->state == DRM_DP_SIDEBAND_TX_TIMEOUT) { |