drivers/gpu/drm/msm/dp/dp_mst_drm.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
On RB8 hardware, after drm_dp_add_payload_part2() completes, the
downstream MST dongle has a high probability of silently dropping the
short-pulse IRQ at specific timing windows.
Implement the .poll_hpd_irq topology callback so that the DRM MST core can
proactively poll for unhandled sideband events whenever it suspects a
missed IRQ.
Note: The new MST series will integrate this change into the introduce MST
IRQ patch
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
---
drivers/gpu/drm/msm/dp/dp_mst_drm.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_mst_drm.c b/drivers/gpu/drm/msm/dp/dp_mst_drm.c
index c8623849c001..8cc44dcc37cd 100644
--- a/drivers/gpu/drm/msm/dp/dp_mst_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_mst_drm.c
@@ -60,6 +60,8 @@ struct msm_dp_mst {
u32 max_streams;
/* Protects MST bridge enable/disable handling. */
struct mutex mst_lock;
+ /* Serializes HPD IRQ handling between IRQ handler and poll_hpd_irq. */
+ struct mutex hpd_irq_lock;
};
static struct drm_private_state *msm_dp_mst_duplicate_bridge_state(struct drm_private_obj *obj)
@@ -500,10 +502,12 @@ void msm_dp_mst_display_hpd_irq(struct msm_dp *dp_display)
unsigned int esi_res = DP_SINK_COUNT_ESI + 1;
bool handled;
+ mutex_lock(&mst->hpd_irq_lock);
+
rc = drm_dp_dpcd_read_data(mst->dp_aux, DP_SINK_COUNT_ESI, esi, 4);
if (rc < 0) {
DRM_ERROR("DPCD sink status read failed, rlen=%d\n", rc);
- return;
+ goto out_unlock;
}
drm_dbg_dp(dp_display->drm_dev, "MST irq: esi1[0x%x] esi2[0x%x] esi3[%x]\n",
@@ -516,12 +520,15 @@ void msm_dp_mst_display_hpd_irq(struct msm_dp *dp_display)
rc = drm_dp_dpcd_write_byte(mst->dp_aux, esi_res, ack[1]);
if (rc < 0) {
DRM_ERROR("DPCD esi_res failed. rc=%d\n", rc);
- return;
+ goto out_unlock;
}
drm_dp_mst_hpd_irq_send_new_request(&mst->mst_mgr);
}
drm_dbg_dp(dp_display->drm_dev, "MST display hpd_irq handled:%d rc:%d\n", handled, rc);
+
+out_unlock:
+ mutex_unlock(&mst->hpd_irq_lock);
}
/* DP MST Connector OPs */
@@ -749,8 +756,16 @@ msm_dp_mst_add_connector(struct drm_dp_mst_topology_mgr *mgr,
return connector;
}
+static void msm_dp_mst_poll_hpd_irq(struct drm_dp_mst_topology_mgr *mgr)
+{
+ struct msm_dp_mst *mst = container_of(mgr, struct msm_dp_mst, mst_mgr);
+
+ msm_dp_mst_display_hpd_irq(mst->msm_dp);
+}
+
static const struct drm_dp_mst_topology_cbs msm_dp_mst_drm_cbs = {
.add_connector = msm_dp_mst_add_connector,
+ .poll_hpd_irq = msm_dp_mst_poll_hpd_irq,
};
int msm_dp_mst_init(struct msm_dp *dp_display, u32 max_streams, struct drm_dp_aux *drm_aux)
@@ -791,5 +806,6 @@ int msm_dp_mst_init(struct msm_dp *dp_display, u32 max_streams, struct drm_dp_au
dp_display->msm_dp_mst = msm_dp_mst;
mutex_init(&msm_dp_mst->mst_lock);
+ mutex_init(&msm_dp_mst->hpd_irq_lock);
return ret;
}
---
base-commit: 3ef088b0c5772a6f75634e54aa34f5fc0a2c041c
change-id: 20260606-mst_irq-4d46e72137aa
prerequisite-change-id: 20260410-msm-dp-mst-35130b6e8b84:v4
prerequisite-patch-id: 8b3f7f40025e7a10c4646435e9cfec4f9e275871
prerequisite-patch-id: 017d8e6efd9c8f120d0a7dd89b3e6c358fdc2126
prerequisite-patch-id: 010d0a4f1a67dcbcd29ff183e8bcb0d043e2c26d
prerequisite-patch-id: 547db98962f20218380e966b976aede824ff8433
prerequisite-patch-id: 1867c344ef6ead1034523ba65d2640f9ad0606cd
prerequisite-patch-id: a58ebaf429385c622869c83e83ce7ffdfe9ea27e
prerequisite-patch-id: d0f570e57559248ba6ca733f96fdb02af29f3055
prerequisite-patch-id: 44d390f5319068ad534c4be698dd8dba99c0bfd1
prerequisite-patch-id: 85438690573583cf62065f43531dbb4e221e9dd0
prerequisite-patch-id: b37db0f0b10f16ed45ab056aa87f2275bb02df94
prerequisite-patch-id: dcccd204ee8a979328719d41334453474bcfdf98
prerequisite-patch-id: db07c3aa80a597c91ae2329bc677bfd72b63716a
prerequisite-patch-id: 9778cc1ab60a0870a74d58ff220bb01011fdf1c0
prerequisite-patch-id: 95692a605647e51bdaf8d5b2e61635a6978121f0
prerequisite-patch-id: af51d259753df3795c9fe16bc1f8f98d0f525bd5
prerequisite-patch-id: 68f5e67439fb83ea39fd82dd8559a20c99e56b6e
prerequisite-patch-id: be0f4b80697df7224c80362b161b8a9f0a542184
prerequisite-patch-id: 0af9e48f1e0b698557303ada9aeb226e5b7f7561
prerequisite-patch-id: 3887553893357c1ffbda99eb010801bc2166cbad
prerequisite-patch-id: 3ce7fe5264dcef7ff752837c525791de84f2669c
prerequisite-patch-id: 3e635f008f9b56823101abd9253905f078fcb3b5
prerequisite-patch-id: e39e0dc124ed043c7a419610ebe03ad105da27db
prerequisite-patch-id: 85bca44976ae5e7f2f2aaff91478dce62c65a9b0
prerequisite-patch-id: 4f87805ca60f2c816cb8e20eb1bcde5f1ab1f809
prerequisite-patch-id: 755afef095a10fc5fb6d5946cb9af5026cc3f34f
prerequisite-patch-id: ee83dcca3c614dda1073ee42a07c48d9f8424e5d
prerequisite-patch-id: 68b1b8605e582f6ba826bbec74eea643e7eb7116
prerequisite-patch-id: ab8fc659c8805c19ed0d97ababf47a98efe17b6a
prerequisite-patch-id: 8d84e97e9abb207e151fa3437d57dd3261e80413
prerequisite-patch-id: 27038c091f1176d8ab9b28551eca3fa4d60964f2
prerequisite-patch-id: cd061c6c74c5ef1326d91b8bcac2ab1f0afc025d
prerequisite-patch-id: 68aa5463159f226f33ad4d59b38779cbcb65a3ce
prerequisite-patch-id: a6b78895c4b94c5508312028e0f6bc97b331821e
prerequisite-patch-id: 52f00ae0a5c7fdca8c8d026be2ad4078c229691a
prerequisite-patch-id: 4cf62cd1cf74ec67c8d3f3d0857c522d24f87cd5
prerequisite-patch-id: 59a643104d4d88f5f7513b026c3743873af89c51
prerequisite-patch-id: 81cb1cae4c4563a2cb96327a3d4e0bd18ea5a8f5
prerequisite-patch-id: c5ea571615b6728f3622104e726f62f383c6e607
prerequisite-patch-id: 7dc0efb1bafa6752af3ed46c99b34bacb14388bc
prerequisite-patch-id: e84e884e747390a7b7a0f1481fae91ac5a8809da
prerequisite-patch-id: 56d282f6950ea9b3c6737da0e2ca78ebde8b199a
prerequisite-patch-id: c19b234de6e7c0f505148386f201e653da1052c3
prerequisite-patch-id: 7859b691e9019d31d167adb10cbad3e39af33489
prerequisite-patch-id: 5685ad34e365343c03d13fed0a20ed4a4afe7f7e
prerequisite-patch-id: a1722149fbd725c1b5d3a610b2532fe588461cc8
prerequisite-patch-id: 0e8158a6e2c8b54e308e0ea75de91f823aebe1bc
prerequisite-patch-id: e12fd2908ca33de1f1265fd40190eaad8637e569
prerequisite-patch-id: 1d8af90cb7cc47ba27877637262c4046927aba6c
prerequisite-patch-id: fe50641762421af252fabb41b97b496539798151
prerequisite-patch-id: 915722dd72c8d485c33068cbf2ad2a87c783bcf0
prerequisite-patch-id: 45c0b5cf8735cf36c4b484edecaf8214f8b5a020
prerequisite-patch-id: e593f6149a649effe3252f663249c70b41d8d684
prerequisite-patch-id: c8d444e2a6512f106da2675d4a42a92208d5c6f1
prerequisite-patch-id: 85222573dc5e5bdb529de33fe19185338c154fe2
Best regards,
--
Yongxing Mou <yongxing.mou@oss.qualcomm.com>
On Sat, Jun 06, 2026 at 08:05:29PM +0800, Yongxing Mou wrote:
> On RB8 hardware, after drm_dp_add_payload_part2() completes, the
> downstream MST dongle has a high probability of silently dropping the
> short-pulse IRQ at specific timing windows.
So, who does what? Is it RB8 missing the IRQ_HPD or is it a dongle not
sending the IRQ_HPD event? Why is it being missed?
>
> Implement the .poll_hpd_irq topology callback so that the DRM MST core can
> proactively poll for unhandled sideband events whenever it suspects a
> missed IRQ.
>
> Note: The new MST series will integrate this change into the introduce MST
> IRQ patch
This should not be a part of the commit message. And also the patch
should be a part of the MST series.
>
> Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
> ---
> drivers/gpu/drm/msm/dp/dp_mst_drm.c | 20 ++++++++++++++++++--
> 1 file changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_mst_drm.c b/drivers/gpu/drm/msm/dp/dp_mst_drm.c
> index c8623849c001..8cc44dcc37cd 100644
> --- a/drivers/gpu/drm/msm/dp/dp_mst_drm.c
> +++ b/drivers/gpu/drm/msm/dp/dp_mst_drm.c
> @@ -60,6 +60,8 @@ struct msm_dp_mst {
> u32 max_streams;
> /* Protects MST bridge enable/disable handling. */
> struct mutex mst_lock;
> + /* Serializes HPD IRQ handling between IRQ handler and poll_hpd_irq. */
> + struct mutex hpd_irq_lock;
> };
>
> static struct drm_private_state *msm_dp_mst_duplicate_bridge_state(struct drm_private_obj *obj)
> @@ -500,10 +502,12 @@ void msm_dp_mst_display_hpd_irq(struct msm_dp *dp_display)
> unsigned int esi_res = DP_SINK_COUNT_ESI + 1;
> bool handled;
>
> + mutex_lock(&mst->hpd_irq_lock);
guard(mutex)(&mst->hpd_irq_lock);
> +
--
With best wishes
Dmitry
© 2016 - 2026 Red Hat, Inc.