[PATCH] drm/msm/dp: Introduce poll_hpd_irq callback for MST sideband handling

Yongxing Mou posted 1 patch 1 day, 17 hours ago
drivers/gpu/drm/msm/dp/dp_mst_drm.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
[PATCH] drm/msm/dp: Introduce poll_hpd_irq callback for MST sideband handling
Posted by Yongxing Mou 1 day, 17 hours ago
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>
Re: [PATCH] drm/msm/dp: Introduce poll_hpd_irq callback for MST sideband handling
Posted by Dmitry Baryshkov 1 day, 17 hours ago
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