On 27/02/2024 23:08, Dmitry Baryshkov wrote:
This reverts commit e467e0bde881 ("drm/msm/dp: use
drm_bridge_hpd_notify() to report HPD status changes").

The commit changed the way how the MSM DP driver communicates
HPD-related events to the userspace. The mentioned commit made some of
the HPD events being reported earlier. This way userspace starts poking
around. It interacts in a bad way with the dp_bridge_detect and the
driver's state machine, ending up either with the very long delays
during hotplug detection or even inability of the DP driver to report
the display as connected.

A proper fix will involve redesigning of the HPD handling in the MSM DP
driver. It is underway, but it will be intrusive and can not be thought
about as a simple fix for the issue. Thus, revert the offending commit.

Fixes: e467e0bde881 ("drm/msm/dp: use drm_bridge_hpd_notify() to report HPD status 
changes")
Link: https://gitlab.freedesktop.org/drm/msm/-/issues/50
Reported-by: Johan Hovold <jo...@kernel.org>
Link: https://lore.kernel.org/r/zd3ypgmrprxv-...@hovoldconsulting.com/
Signed-off-by: Dmitry Baryshkov <dmitry.barysh...@linaro.org>
---
  drivers/gpu/drm/msm/dp/dp_display.c | 20 ++++++++++++++++++--
  1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index d37d599aec27..4c72124ffb5d 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -329,10 +329,26 @@ static const struct component_ops dp_display_comp_ops = {
        .unbind = dp_display_unbind,
  };
+static void dp_display_send_hpd_event(struct msm_dp *dp_display)
+{
+       struct dp_display_private *dp;
+       struct drm_connector *connector;
+
+       dp = container_of(dp_display, struct dp_display_private, dp_display);
+
+       connector = dp->dp_display.connector;
+       drm_helper_hpd_irq_event(connector->dev);
+}
+
  static int dp_display_send_hpd_notification(struct dp_display_private *dp,
                                            bool hpd)
  {
-       struct drm_bridge *bridge = dp->dp_display.bridge;
+       if ((hpd && dp->dp_display.link_ready) ||
+                       (!hpd && !dp->dp_display.link_ready)) {
+               drm_dbg_dp(dp->drm_dev, "HPD already %s\n",
+                               (hpd ? "on" : "off"));
+               return 0;
+       }
/* reset video pattern flag on disconnect */
        if (!hpd) {
@@ -348,7 +364,7 @@ static int dp_display_send_hpd_notification(struct 
dp_display_private *dp,
drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n",
                        dp->dp_display.connector_type, hpd);
-       drm_bridge_hpd_notify(bridge, dp->dp_display.link_ready);
+       dp_display_send_hpd_event(&dp->dp_display);
return 0;
  }

Tested-by: Neil Armstrong <neil.armstr...@linaro.org> # on SM8650-HDK

Reply via email to