* [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine
@ 2026-03-14 1:09 Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 01/10] drm/msm/dp: fix HPD state status bit shift value Dmitry Baryshkov
` (10 more replies)
0 siblings, 11 replies; 17+ messages in thread
From: Dmitry Baryshkov @ 2026-03-14 1:09 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Kuogee Hsieh, Yongxing Mou
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jessica Zhang
Currently, all HPD interrupt handling must go through the HPD state
machine.
This has caused many issues where the DRM framework assumes that DP is
in one state while the state machine is stuck in another state.
As discussed here [1], this series:
- Removes the state machine
- Moves link training to atomic_enable()
- Changes the detect() behavior to return true if a display is physically
plugged in (as opposed to if the DP link is ready).
- Remove event queue and move internal HPD handling to hpd_notify()
To correctly detect the displays which are plugged on boot on the boards
which use dp-connector devices, this series depends on [2]. USB-C and
eDP panels are handled natively.
[1] https://patchwork.freedesktop.org/patch/656312/?series=142010&rev=2#comment_1201738
[2] https://lore.kernel.org/all/20260314-dp-connector-hpd-v1-0-786044cedc17@oss.qualcomm.com/
---
Changes in v5:
- Fixed the EDID clearing on display unplug
- Fixed the initial HPD issue via the external series
- Tested on eDP devices
- Link to v4: https://lore.kernel.org/r/20260305-hpd-refactor-v4-0-39c9d1fef321@oss.qualcomm.com
Changes in v4:
- Fixed PM runtime handling
- Fixed several cases where the HPD machine would loose its state
- Fixed the case where detection was ignoring the plugging in display.
- Link to v3: https://lore.kernel.org/r/20260115-hpd-refactor-v3-0-08e2f3bcd2e0@oss.qualcomm.com
Changes in v3:
- Take over the series (thanks, Jessica, for the previous work!)
- Major rework of the series, squashed the set of patches touching the
HPD states and handling, it is easier to do it this way rather than
pulling the strings one by one.
- Link to v2: https://lore.kernel.org/r/20250808-hpd-refactor-v2-0-7f4e1e741aa3@oss.qualcomm.com
Changes in v2:
- Dropped event queue (Dmitry)
- Moved internal HPD handling to use hpd_notify() (Dmitry)
- Reworked bridge detect() to read DPCP and sink count (Dmitry)
- Moved setting of link_trained to plug/unplugged handling
- Dropped msm_dp::connected (Dmitry)
- Squashed all hpd state related patches (Dmitry)
- Link to v1: https://lore.kernel.org/r/20250711-hpd-refactor-v1-0-33cbac823f34@oss.qualcomm.com
---
Dmitry Baryshkov (3):
drm/msm/dp: drop event data
drm/msm/dp: turn link_ready into plugged
drm/msm/dp: clear EDID on display unplug
Jessica Zhang (7):
drm/msm/dp: fix HPD state status bit shift value
drm/msm/dp: Fix the ISR_* enum values
drm/msm/dp: Read DPCD and sink count in bridge detect()
drm/msm/dp: Move link training to atomic_enable()
drm/msm/dp: Drop EV_USER_NOTIFICATION
drm/msm/dp: rework HPD handling
drm/msm/dp: Add sink_count to debug logs
drivers/gpu/drm/msm/dp/dp_ctrl.c | 22 --
drivers/gpu/drm/msm/dp/dp_ctrl.h | 1 -
drivers/gpu/drm/msm/dp/dp_display.c | 714 ++++++++++++------------------------
drivers/gpu/drm/msm/dp/dp_display.h | 3 +-
drivers/gpu/drm/msm/dp/dp_drm.c | 63 +---
drivers/gpu/drm/msm/dp/dp_drm.h | 2 +
drivers/gpu/drm/msm/dp/dp_panel.c | 8 +
drivers/gpu/drm/msm/dp/dp_panel.h | 2 +
drivers/gpu/drm/msm/dp/dp_reg.h | 4 +-
9 files changed, 249 insertions(+), 570 deletions(-)
---
base-commit: 5c9e55fecf9365890c64f14761a80f9413a3b1d1
change-id: 20250523-hpd-refactor-74e25b55620a
prerequisite-change-id: 20260314-dp-connector-hpd-f069e66bc6af:v1
prerequisite-patch-id: 90db75e3fb8bc9c81c67547db7bbd4eefd5d6c40
prerequisite-patch-id: 1c4d030b93a8cc6c98b3447a8685da24eb1f24d5
Best regards,
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v5 01/10] drm/msm/dp: fix HPD state status bit shift value
2026-03-14 1:09 [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine Dmitry Baryshkov
@ 2026-03-14 1:09 ` Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 02/10] drm/msm/dp: Fix the ISR_* enum values Dmitry Baryshkov
` (9 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Dmitry Baryshkov @ 2026-03-14 1:09 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Kuogee Hsieh, Yongxing Mou
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jessica Zhang
From: Jessica Zhang <jesszhan0024@gmail.com>
The HPD state status is the 3 most significant bits, not 4 bits of the
HPD_INT_STATUS register.
Fix the bit shift macro so that the correct bits are returned in
msm_dp_aux_is_link_connected().
Fixes: 19e52bcb27c2 ("drm/msm/dp: return correct connection status after suspend")
Signed-off-by: Jessica Zhang <jessica.zhang@oss.qualcomm.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/msm/dp/dp_reg.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_reg.h b/drivers/gpu/drm/msm/dp/dp_reg.h
index 7c44d4e2cf13..3689642b7fc0 100644
--- a/drivers/gpu/drm/msm/dp/dp_reg.h
+++ b/drivers/gpu/drm/msm/dp/dp_reg.h
@@ -68,8 +68,8 @@
#define DP_DP_IRQ_HPD_INT_ACK (0x00000002)
#define DP_DP_HPD_REPLUG_INT_ACK (0x00000004)
#define DP_DP_HPD_UNPLUG_INT_ACK (0x00000008)
-#define DP_DP_HPD_STATE_STATUS_BITS_MASK (0x0000000F)
-#define DP_DP_HPD_STATE_STATUS_BITS_SHIFT (0x1C)
+#define DP_DP_HPD_STATE_STATUS_BITS_MASK (0x00000007)
+#define DP_DP_HPD_STATE_STATUS_BITS_SHIFT (0x1D)
#define REG_DP_DP_HPD_INT_MASK (0x0000000C)
#define DP_DP_HPD_PLUG_INT_MASK (0x00000001)
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v5 02/10] drm/msm/dp: Fix the ISR_* enum values
2026-03-14 1:09 [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 01/10] drm/msm/dp: fix HPD state status bit shift value Dmitry Baryshkov
@ 2026-03-14 1:09 ` Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 03/10] drm/msm/dp: Read DPCD and sink count in bridge detect() Dmitry Baryshkov
` (8 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Dmitry Baryshkov @ 2026-03-14 1:09 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Kuogee Hsieh, Yongxing Mou
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jessica Zhang
From: Jessica Zhang <jesszhan0024@gmail.com>
The ISR_HPD_* enum should represent values that can be read from the
REG_DP_DP_HPD_INT_STATUS register. Swap ISR_HPD_IO_GLITCH_COUNT and
ISR_HPD_REPLUG_COUNT to map them correctly to register values.
While we are at it, correct the spelling for ISR_HPD_REPLUG_COUNT.
Fixes: 8ede2ecc3e5e ("drm/msm/dp: Add DP compliance tests on Snapdragon Chipsets")
Signed-off-by: Jessica Zhang <jessica.zhang@oss.qualcomm.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/msm/dp/dp_display.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 476848bf8cd1..5997cd28ba11 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -38,9 +38,9 @@ enum {
ISR_DISCONNECTED,
ISR_CONNECT_PENDING,
ISR_CONNECTED,
- ISR_HPD_REPLUG_COUNT,
+ ISR_HPD_IO_GLITCH_COUNT,
ISR_IRQ_HPD_PULSE_COUNT,
- ISR_HPD_LO_GLITH_COUNT,
+ ISR_HPD_REPLUG_COUNT,
};
/* event thread connection state */
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v5 03/10] drm/msm/dp: Read DPCD and sink count in bridge detect()
2026-03-14 1:09 [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 01/10] drm/msm/dp: fix HPD state status bit shift value Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 02/10] drm/msm/dp: Fix the ISR_* enum values Dmitry Baryshkov
@ 2026-03-14 1:09 ` Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 04/10] drm/msm/dp: Move link training to atomic_enable() Dmitry Baryshkov
` (7 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Dmitry Baryshkov @ 2026-03-14 1:09 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Kuogee Hsieh, Yongxing Mou
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jessica Zhang
From: Jessica Zhang <jesszhan0024@gmail.com>
Instead of relying on the link_ready flag to specify if DP is connected,
read the DPCD bits and get the sink count to accurately detect if DP is
connected.
Signed-off-by: Jessica Zhang <jessica.zhang@oss.qualcomm.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/msm/dp/dp_display.c | 60 +++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/msm/dp/dp_drm.c | 20 -------------
drivers/gpu/drm/msm/dp/dp_drm.h | 2 ++
3 files changed, 62 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 5997cd28ba11..a05144de3b93 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1151,6 +1151,66 @@ static int msm_dp_hpd_event_thread_start(struct msm_dp_display_private *msm_dp_p
return 0;
}
+/**
+ * msm_dp_bridge_detect - callback to determine if connector is connected
+ * @bridge: Pointer to drm bridge structure
+ * @connector: Pointer to drm connector structure
+ * Returns: Bridge's 'is connected' status
+ */
+enum drm_connector_status msm_dp_bridge_detect(struct drm_bridge *bridge,
+ struct drm_connector *connector)
+{
+ struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(bridge);
+ struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
+ struct msm_dp_display_private *priv;
+ int ret = 0;
+ int status = connector_status_disconnected;
+ u8 dpcd[DP_RECEIVER_CAP_SIZE];
+ struct drm_dp_desc desc;
+
+ dp = to_dp_bridge(bridge)->msm_dp_display;
+
+ priv = container_of(dp, struct msm_dp_display_private, msm_dp_display);
+
+ if (!dp->link_ready)
+ return status;
+
+ msm_dp_aux_enable_xfers(priv->aux, true);
+
+ ret = pm_runtime_resume_and_get(&dp->pdev->dev);
+ if (ret) {
+ DRM_ERROR("failed to pm_runtime_resume\n");
+ msm_dp_aux_enable_xfers(priv->aux, false);
+ return status;
+ }
+
+ ret = msm_dp_aux_is_link_connected(priv->aux);
+ if (dp->internal_hpd && !ret)
+ goto end;
+
+ ret = drm_dp_read_dpcd_caps(priv->aux, dpcd);
+ if (ret)
+ goto end;
+
+ ret = drm_dp_read_desc(priv->aux, &desc, drm_dp_is_branch(dpcd));
+ if (ret)
+ goto end;
+
+ status = connector_status_connected;
+ if (drm_dp_read_sink_count_cap(connector, dpcd, &desc)) {
+ int sink_count = drm_dp_read_sink_count(priv->aux);
+
+ drm_dbg_dp(dp->drm_dev, "sink_count = %d\n", sink_count);
+
+ if (sink_count <= 0)
+ status = connector_status_disconnected;
+ }
+
+end:
+ pm_runtime_put_sync(&dp->pdev->dev);
+ return status;
+}
+
static irqreturn_t msm_dp_display_irq_handler(int irq, void *dev_id)
{
struct msm_dp_display_private *dp = dev_id;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index fd6443d2b6ce..e4622c85fb66 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -15,26 +15,6 @@
#include "dp_audio.h"
#include "dp_drm.h"
-/**
- * msm_dp_bridge_detect - callback to determine if connector is connected
- * @bridge: Pointer to drm bridge structure
- * @connector: Pointer to drm connector structure
- * Returns: Bridge's 'is connected' status
- */
-static enum drm_connector_status
-msm_dp_bridge_detect(struct drm_bridge *bridge, struct drm_connector *connector)
-{
- struct msm_dp *dp;
-
- dp = to_dp_bridge(bridge)->msm_dp_display;
-
- drm_dbg_dp(dp->drm_dev, "link_ready = %s\n",
- str_true_false(dp->link_ready));
-
- return (dp->link_ready) ? connector_status_connected :
- connector_status_disconnected;
-}
-
static int msm_dp_bridge_atomic_check(struct drm_bridge *bridge,
struct drm_bridge_state *bridge_state,
struct drm_crtc_state *crtc_state,
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h b/drivers/gpu/drm/msm/dp/dp_drm.h
index 9eb3431dd93a..6c0426803d78 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.h
+++ b/drivers/gpu/drm/msm/dp/dp_drm.h
@@ -25,6 +25,8 @@ int msm_dp_bridge_init(struct msm_dp *msm_dp_display, struct drm_device *dev,
struct drm_encoder *encoder,
bool yuv_supported);
+enum drm_connector_status msm_dp_bridge_detect(struct drm_bridge *bridge,
+ struct drm_connector *connector);
void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
struct drm_atomic_state *state);
void msm_dp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v5 04/10] drm/msm/dp: Move link training to atomic_enable()
2026-03-14 1:09 [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine Dmitry Baryshkov
` (2 preceding siblings ...)
2026-03-14 1:09 ` [PATCH v5 03/10] drm/msm/dp: Read DPCD and sink count in bridge detect() Dmitry Baryshkov
@ 2026-03-14 1:09 ` Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 05/10] drm/msm/dp: Drop EV_USER_NOTIFICATION Dmitry Baryshkov
` (6 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Dmitry Baryshkov @ 2026-03-14 1:09 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Kuogee Hsieh, Yongxing Mou
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jessica Zhang
From: Jessica Zhang <jesszhan0024@gmail.com>
Currently, the DP link training is being done during HPD. Move
link training to atomic_enable() in accordance with the atomic_enable()
documentation.
Link disabling is already done in atomic_post_disable() (as part of the
dp_ctrl_off_link_stream() helper).
Finally, call the plug/unplug handlers directly in hpd_notify() instead
of queueing them in the event thread so that they aren't preempted by
other events.
Signed-off-by: Jessica Zhang <jessica.zhang@oss.qualcomm.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/msm/dp/dp_display.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index a05144de3b93..e7b1ed5491c4 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -436,11 +436,6 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)
msm_dp_link_psm_config(dp->link, &dp->panel->link_info, false);
msm_dp_link_reset_phy_params_vx_px(dp->link);
- rc = msm_dp_ctrl_on_link(dp->ctrl);
- if (rc) {
- DRM_ERROR("failed to complete DP link training\n");
- goto end;
- }
msm_dp_add_event(dp, EV_USER_NOTIFICATION, true, 0);
@@ -1695,6 +1690,11 @@ void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
force_link_train = true;
}
+ rc = msm_dp_ctrl_on_link(msm_dp_display->ctrl);
+ if (rc)
+ DRM_ERROR("Failed link training (rc=%d)\n", rc);
+ // TODO: schedule drm_connector_set_link_status_property()
+
msm_dp_display_enable(msm_dp_display, force_link_train);
rc = msm_dp_display_post_enable(dp);
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v5 05/10] drm/msm/dp: Drop EV_USER_NOTIFICATION
2026-03-14 1:09 [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine Dmitry Baryshkov
` (3 preceding siblings ...)
2026-03-14 1:09 ` [PATCH v5 04/10] drm/msm/dp: Move link training to atomic_enable() Dmitry Baryshkov
@ 2026-03-14 1:09 ` Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 06/10] drm/msm/dp: drop event data Dmitry Baryshkov
` (5 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Dmitry Baryshkov @ 2026-03-14 1:09 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Kuogee Hsieh, Yongxing Mou
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jessica Zhang
From: Jessica Zhang <jesszhan0024@gmail.com>
Currently, we queue an event for signalling HPD connect/disconnect. This
can mean a delay in plug/unplug handling and notifying DRM core when a
hotplug happens.
Drop EV_USER_NOTIFICATION and signal the IRQ event as part of hotplug
handling.
Signed-off-by: Jessica Zhang <jessica.zhang@oss.qualcomm.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/msm/dp/dp_display.c | 28 ++++++++--------------------
drivers/gpu/drm/msm/dp/dp_display.h | 1 +
drivers/gpu/drm/msm/dp/dp_drm.c | 2 ++
3 files changed, 11 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index e7b1ed5491c4..05c292e27126 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -58,7 +58,6 @@ enum {
EV_HPD_PLUG_INT,
EV_IRQ_HPD_INT,
EV_HPD_UNPLUG_INT,
- EV_USER_NOTIFICATION,
};
#define EVENT_TIMEOUT (HZ/10) /* 100ms */
@@ -343,17 +342,6 @@ static const struct component_ops msm_dp_display_comp_ops = {
.unbind = msm_dp_display_unbind,
};
-static void msm_dp_display_send_hpd_event(struct msm_dp *msm_dp_display)
-{
- struct msm_dp_display_private *dp;
- struct drm_connector *connector;
-
- dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
-
- connector = dp->msm_dp_display.connector;
- drm_helper_hpd_irq_event(connector->dev);
-}
-
static int msm_dp_display_send_hpd_notification(struct msm_dp_display_private *dp,
bool hpd)
{
@@ -377,7 +365,11 @@ static int msm_dp_display_send_hpd_notification(struct msm_dp_display_private *d
drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n",
dp->msm_dp_display.connector_type, hpd);
- msm_dp_display_send_hpd_event(&dp->msm_dp_display);
+
+ drm_bridge_hpd_notify(dp->msm_dp_display.bridge,
+ hpd ?
+ connector_status_connected :
+ connector_status_disconnected);
return 0;
}
@@ -437,7 +429,7 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)
msm_dp_link_reset_phy_params_vx_px(dp->link);
- msm_dp_add_event(dp, EV_USER_NOTIFICATION, true, 0);
+ msm_dp_display_send_hpd_notification(dp, true);
end:
return rc;
@@ -506,7 +498,7 @@ static int msm_dp_display_notify_disconnect(struct device *dev)
{
struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
- msm_dp_add_event(dp, EV_USER_NOTIFICATION, false, 0);
+ msm_dp_display_send_hpd_notification(dp, false);
return 0;
}
@@ -527,7 +519,7 @@ static int msm_dp_display_handle_port_status_changed(struct msm_dp_display_priva
drm_dbg_dp(dp->drm_dev, "sink count is zero, nothing to do\n");
if (dp->hpd_state != ST_DISCONNECTED) {
dp->hpd_state = ST_DISCONNECT_PENDING;
- msm_dp_add_event(dp, EV_USER_NOTIFICATION, false, 0);
+ msm_dp_display_send_hpd_notification(dp, false);
}
} else {
if (dp->hpd_state == ST_DISCONNECTED) {
@@ -1121,10 +1113,6 @@ static int hpd_event_thread(void *data)
case EV_IRQ_HPD_INT:
msm_dp_irq_hpd_handle(msm_dp_priv, todo->data);
break;
- case EV_USER_NOTIFICATION:
- msm_dp_display_send_hpd_notification(msm_dp_priv,
- todo->data);
- break;
default:
break;
}
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
index cc6e2cab36e9..60094061c102 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -16,6 +16,7 @@ struct msm_dp {
struct platform_device *pdev;
struct drm_connector *connector;
struct drm_bridge *next_bridge;
+ struct drm_bridge *bridge;
bool link_ready;
bool audio_enabled;
bool power_on;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index e4622c85fb66..f935093c4df4 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -340,6 +340,8 @@ int msm_dp_bridge_init(struct msm_dp *msm_dp_display, struct drm_device *dev,
}
}
+ msm_dp_display->bridge = bridge;
+
return 0;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v5 06/10] drm/msm/dp: drop event data
2026-03-14 1:09 [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine Dmitry Baryshkov
` (4 preceding siblings ...)
2026-03-14 1:09 ` [PATCH v5 05/10] drm/msm/dp: Drop EV_USER_NOTIFICATION Dmitry Baryshkov
@ 2026-03-14 1:09 ` Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 07/10] drm/msm/dp: rework HPD handling Dmitry Baryshkov
` (4 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Dmitry Baryshkov @ 2026-03-14 1:09 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Kuogee Hsieh, Yongxing Mou
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel
With EV_USER_NOTIFICATION gone event's data is no longer useful. Drop
it, removing also the argument from event handlers.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/msm/dp/dp_display.c | 39 +++++++++++++++++--------------------
1 file changed, 18 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 05c292e27126..bc4078c229cb 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -69,7 +69,6 @@ enum {
struct msm_dp_event {
u32 event_id;
- u32 data;
u32 delay;
};
@@ -218,7 +217,7 @@ static struct msm_dp_display_private *dev_get_dp_display_private(struct device *
}
static int msm_dp_add_event(struct msm_dp_display_private *msm_dp_priv, u32 event,
- u32 data, u32 delay)
+ u32 delay)
{
unsigned long flag;
struct msm_dp_event *todo;
@@ -236,7 +235,6 @@ static int msm_dp_add_event(struct msm_dp_display_private *msm_dp_priv, u32 even
todo = &msm_dp_priv->event_list[msm_dp_priv->event_pndx++];
msm_dp_priv->event_pndx %= DP_EVENT_Q_MAX;
todo->event_id = event;
- todo->data = data;
todo->delay = delay;
wake_up(&msm_dp_priv->event_q);
spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
@@ -576,7 +574,7 @@ static int msm_dp_display_usbpd_attention_cb(struct device *dev)
return rc;
}
-static int msm_dp_hpd_plug_handle(struct msm_dp_display_private *dp, u32 data)
+static int msm_dp_hpd_plug_handle(struct msm_dp_display_private *dp)
{
u32 state;
int ret;
@@ -602,7 +600,7 @@ static int msm_dp_hpd_plug_handle(struct msm_dp_display_private *dp, u32 data)
if (state == ST_DISCONNECT_PENDING) {
/* wait until ST_DISCONNECTED */
- msm_dp_add_event(dp, EV_HPD_PLUG_INT, 0, 1); /* delay = 1 */
+ msm_dp_add_event(dp, EV_HPD_PLUG_INT, 1);
mutex_unlock(&dp->event_mutex);
return 0;
}
@@ -644,7 +642,7 @@ static void msm_dp_display_handle_plugged_change(struct msm_dp *msm_dp_display,
plugged);
}
-static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp, u32 data)
+static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp)
{
u32 state;
struct platform_device *pdev = dp->msm_dp_display.pdev;
@@ -706,7 +704,7 @@ static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp, u32 data)
return 0;
}
-static int msm_dp_irq_hpd_handle(struct msm_dp_display_private *dp, u32 data)
+static int msm_dp_irq_hpd_handle(struct msm_dp_display_private *dp)
{
u32 state;
@@ -724,7 +722,7 @@ static int msm_dp_irq_hpd_handle(struct msm_dp_display_private *dp, u32 data)
if (state == ST_MAINLINK_READY || state == ST_DISCONNECT_PENDING) {
/* wait until ST_CONNECTED */
- msm_dp_add_event(dp, EV_IRQ_HPD_INT, 0, 1); /* delay = 1 */
+ msm_dp_add_event(dp, EV_IRQ_HPD_INT, 1);
mutex_unlock(&dp->event_mutex);
return 0;
}
@@ -1079,7 +1077,6 @@ static int hpd_event_thread(void *data)
todo_next = &msm_dp_priv->event_list[msm_dp_priv->event_pndx++];
msm_dp_priv->event_pndx %= DP_EVENT_Q_MAX;
todo_next->event_id = todo->event_id;
- todo_next->data = todo->data;
todo_next->delay = todo->delay - 1;
/* clean up older event */
@@ -1105,13 +1102,13 @@ static int hpd_event_thread(void *data)
switch (todo->event_id) {
case EV_HPD_PLUG_INT:
- msm_dp_hpd_plug_handle(msm_dp_priv, todo->data);
+ msm_dp_hpd_plug_handle(msm_dp_priv);
break;
case EV_HPD_UNPLUG_INT:
- msm_dp_hpd_unplug_handle(msm_dp_priv, todo->data);
+ msm_dp_hpd_unplug_handle(msm_dp_priv);
break;
case EV_IRQ_HPD_INT:
- msm_dp_irq_hpd_handle(msm_dp_priv, todo->data);
+ msm_dp_irq_hpd_handle(msm_dp_priv);
break;
default:
break;
@@ -1212,19 +1209,19 @@ static irqreturn_t msm_dp_display_irq_handler(int irq, void *dev_id)
dp->msm_dp_display.connector_type, hpd_isr_status);
/* hpd related interrupts */
if (hpd_isr_status & DP_DP_HPD_PLUG_INT_MASK)
- msm_dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0);
+ msm_dp_add_event(dp, EV_HPD_PLUG_INT, 0);
if (hpd_isr_status & DP_DP_IRQ_HPD_INT_MASK) {
- msm_dp_add_event(dp, EV_IRQ_HPD_INT, 0, 0);
+ msm_dp_add_event(dp, EV_IRQ_HPD_INT, 0);
}
if (hpd_isr_status & DP_DP_HPD_REPLUG_INT_MASK) {
- msm_dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
- msm_dp_add_event(dp, EV_HPD_PLUG_INT, 0, 3);
+ msm_dp_add_event(dp, EV_HPD_UNPLUG_INT, 0);
+ msm_dp_add_event(dp, EV_HPD_PLUG_INT, 3);
}
if (hpd_isr_status & DP_DP_HPD_UNPLUG_INT_MASK)
- msm_dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
+ msm_dp_add_event(dp, EV_HPD_UNPLUG_INT, 0);
ret = IRQ_HANDLED;
}
@@ -1649,7 +1646,7 @@ void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
}
if (dp->is_edp)
- msm_dp_hpd_plug_handle(msm_dp_display, 0);
+ msm_dp_hpd_plug_handle(msm_dp_display);
mutex_lock(&msm_dp_display->event_mutex);
if (pm_runtime_resume_and_get(&dp->pdev->dev)) {
@@ -1721,7 +1718,7 @@ void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
if (dp->is_edp)
- msm_dp_hpd_unplug_handle(msm_dp_display, 0);
+ msm_dp_hpd_unplug_handle(msm_dp_display);
mutex_lock(&msm_dp_display->event_mutex);
@@ -1843,7 +1840,7 @@ void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
return;
if (!msm_dp_display->link_ready && status == connector_status_connected)
- msm_dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0);
+ msm_dp_add_event(dp, EV_HPD_PLUG_INT, 0);
else if (msm_dp_display->link_ready && status == connector_status_disconnected)
- msm_dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
+ msm_dp_add_event(dp, EV_HPD_UNPLUG_INT, 0);
}
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v5 07/10] drm/msm/dp: rework HPD handling
2026-03-14 1:09 [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine Dmitry Baryshkov
` (5 preceding siblings ...)
2026-03-14 1:09 ` [PATCH v5 06/10] drm/msm/dp: drop event data Dmitry Baryshkov
@ 2026-03-14 1:09 ` Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 08/10] drm/msm/dp: Add sink_count to debug logs Dmitry Baryshkov
` (3 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Dmitry Baryshkov @ 2026-03-14 1:09 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Kuogee Hsieh, Yongxing Mou
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jessica Zhang
From: Jessica Zhang <jesszhan0024@gmail.com>
Handling of the HPD events in the MSM DP driver is plagued with lots of
problems. It tries to work aside of the main DRM framework, handling the
HPD signals on its own. There are two separate paths, one for the HPD
signals coming from the DP HPD pin and another path for signals coming
from outside (e.g. from the Type-C AltMode). It lies about the connected
state, returning the link established state instead. It is not easy to
understand or modify it. Having a separate event machine doesn't add
extra clarity.
Drop the whole event machine. When the DP receives a HPD event, send it
to the DRM core. Then handle the events in the hpd_notify callback,
unifying paths for HPD signals.
Signed-off-by: Jessica Zhang <jessica.zhang@oss.qualcomm.com>
Co-developed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/msm/dp/dp_ctrl.c | 22 --
drivers/gpu/drm/msm/dp/dp_ctrl.h | 1 -
drivers/gpu/drm/msm/dp/dp_display.c | 601 ++++++++----------------------------
drivers/gpu/drm/msm/dp/dp_display.h | 1 -
4 files changed, 134 insertions(+), 491 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index ef298c7d3e5e..3bb08c9a020e 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -2593,28 +2593,6 @@ void msm_dp_ctrl_off_link_stream(struct msm_dp_ctrl *msm_dp_ctrl)
phy, phy->init_count, phy->power_count);
}
-void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl)
-{
- struct msm_dp_ctrl_private *ctrl;
- struct phy *phy;
-
- ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
- phy = ctrl->phy;
-
- msm_dp_ctrl_mainlink_disable(ctrl);
-
- dev_pm_opp_set_rate(ctrl->dev, 0);
- msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
-
- DRM_DEBUG_DP("Before, phy=%p init_count=%d power_on=%d\n",
- phy, phy->init_count, phy->power_count);
-
- phy_power_off(phy);
-
- DRM_DEBUG_DP("After, phy=%p init_count=%d power_on=%d\n",
- phy, phy->init_count, phy->power_count);
-}
-
void msm_dp_ctrl_off(struct msm_dp_ctrl *msm_dp_ctrl)
{
struct msm_dp_ctrl_private *ctrl;
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.h b/drivers/gpu/drm/msm/dp/dp_ctrl.h
index 124b9b21bb7f..f68bee62713f 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.h
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.h
@@ -19,7 +19,6 @@ struct phy;
int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl);
int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train);
void msm_dp_ctrl_off_link_stream(struct msm_dp_ctrl *msm_dp_ctrl);
-void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl);
void msm_dp_ctrl_off(struct msm_dp_ctrl *msm_dp_ctrl);
void msm_dp_ctrl_push_idle(struct msm_dp_ctrl *msm_dp_ctrl);
irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index bc4078c229cb..d61a8ddd30a8 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -43,35 +43,6 @@ enum {
ISR_HPD_REPLUG_COUNT,
};
-/* event thread connection state */
-enum {
- ST_DISCONNECTED,
- ST_MAINLINK_READY,
- ST_CONNECTED,
- ST_DISCONNECT_PENDING,
- ST_DISPLAY_OFF,
-};
-
-enum {
- EV_NO_EVENT,
- /* hpd events */
- EV_HPD_PLUG_INT,
- EV_IRQ_HPD_INT,
- EV_HPD_UNPLUG_INT,
-};
-
-#define EVENT_TIMEOUT (HZ/10) /* 100ms */
-#define DP_EVENT_Q_MAX 8
-
-#define DP_TIMEOUT_NONE 0
-
-#define WAIT_FOR_RESUME_TIMEOUT_JIFFIES (HZ / 2)
-
-struct msm_dp_event {
- u32 event_id;
- u32 delay;
-};
-
struct msm_dp_display_private {
int irq;
@@ -95,15 +66,9 @@ struct msm_dp_display_private {
/* wait for audio signaling */
struct completion audio_comp;
- /* event related only access by event thread */
- struct mutex event_mutex;
- wait_queue_head_t event_q;
- u32 hpd_state;
- u32 event_pndx;
- u32 event_gndx;
- struct task_struct *ev_tsk;
- struct msm_dp_event event_list[DP_EVENT_Q_MAX];
- spinlock_t event_lock;
+ /* HPD IRQ handling */
+ spinlock_t irq_thread_lock;
+ u32 hpd_isr_status;
bool wide_bus_supported;
@@ -216,59 +181,6 @@ static struct msm_dp_display_private *dev_get_dp_display_private(struct device *
return container_of(dp, struct msm_dp_display_private, msm_dp_display);
}
-static int msm_dp_add_event(struct msm_dp_display_private *msm_dp_priv, u32 event,
- u32 delay)
-{
- unsigned long flag;
- struct msm_dp_event *todo;
- int pndx;
-
- spin_lock_irqsave(&msm_dp_priv->event_lock, flag);
- pndx = msm_dp_priv->event_pndx + 1;
- pndx %= DP_EVENT_Q_MAX;
- if (pndx == msm_dp_priv->event_gndx) {
- pr_err("event_q is full: pndx=%d gndx=%d\n",
- msm_dp_priv->event_pndx, msm_dp_priv->event_gndx);
- spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
- return -EPERM;
- }
- todo = &msm_dp_priv->event_list[msm_dp_priv->event_pndx++];
- msm_dp_priv->event_pndx %= DP_EVENT_Q_MAX;
- todo->event_id = event;
- todo->delay = delay;
- wake_up(&msm_dp_priv->event_q);
- spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
-
- return 0;
-}
-
-static int msm_dp_del_event(struct msm_dp_display_private *msm_dp_priv, u32 event)
-{
- unsigned long flag;
- struct msm_dp_event *todo;
- u32 gndx;
-
- spin_lock_irqsave(&msm_dp_priv->event_lock, flag);
- if (msm_dp_priv->event_pndx == msm_dp_priv->event_gndx) {
- spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
- return -ENOENT;
- }
-
- gndx = msm_dp_priv->event_gndx;
- while (msm_dp_priv->event_pndx != gndx) {
- todo = &msm_dp_priv->event_list[gndx];
- if (todo->event_id == event) {
- todo->event_id = EV_NO_EVENT; /* deleted */
- todo->delay = 0;
- }
- gndx++;
- gndx %= DP_EVENT_Q_MAX;
- }
- spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
-
- return 0;
-}
-
void msm_dp_display_signal_audio_start(struct msm_dp *msm_dp_display)
{
struct msm_dp_display_private *dp;
@@ -287,8 +199,6 @@ void msm_dp_display_signal_audio_complete(struct msm_dp *msm_dp_display)
complete_all(&dp->audio_comp);
}
-static int msm_dp_hpd_event_thread_start(struct msm_dp_display_private *msm_dp_priv);
-
static int msm_dp_display_bind(struct device *dev, struct device *master,
void *data)
{
@@ -308,12 +218,6 @@ static int msm_dp_display_bind(struct device *dev, struct device *master,
goto end;
}
- rc = msm_dp_hpd_event_thread_start(dp);
- if (rc) {
- DRM_ERROR("Event thread create failed\n");
- goto end;
- }
-
return 0;
end:
return rc;
@@ -325,8 +229,6 @@ static void msm_dp_display_unbind(struct device *dev, struct device *master,
struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
struct msm_drm_private *priv = dev_get_drvdata(master);
- kthread_stop(dp->ev_tsk);
-
of_dp_aux_depopulate_bus(dp->aux);
msm_dp_aux_unregister(dp->aux);
@@ -340,38 +242,6 @@ static const struct component_ops msm_dp_display_comp_ops = {
.unbind = msm_dp_display_unbind,
};
-static int msm_dp_display_send_hpd_notification(struct msm_dp_display_private *dp,
- bool hpd)
-{
- if ((hpd && dp->msm_dp_display.link_ready) ||
- (!hpd && !dp->msm_dp_display.link_ready)) {
- drm_dbg_dp(dp->drm_dev, "HPD already %s\n", str_on_off(hpd));
- return 0;
- }
-
- /* reset video pattern flag on disconnect */
- if (!hpd) {
- dp->panel->video_test = false;
- if (!dp->msm_dp_display.is_edp)
- drm_dp_set_subconnector_property(dp->msm_dp_display.connector,
- connector_status_disconnected,
- dp->panel->dpcd,
- dp->panel->downstream_ports);
- }
-
- dp->msm_dp_display.link_ready = hpd;
-
- drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n",
- dp->msm_dp_display.connector_type, hpd);
-
- drm_bridge_hpd_notify(dp->msm_dp_display.bridge,
- hpd ?
- connector_status_connected :
- connector_status_disconnected);
-
- return 0;
-}
-
static int msm_dp_display_lttpr_init(struct msm_dp_display_private *dp, u8 *dpcd)
{
int rc, lttpr_count;
@@ -414,6 +284,8 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)
dp->panel->dpcd,
dp->panel->downstream_ports);
+ dp->msm_dp_display.link_ready = true;
+
dp->msm_dp_display.psr_supported = dp->panel->psr_cap.version && psr_enabled;
dp->audio_supported = info->has_audio;
@@ -427,8 +299,6 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)
msm_dp_link_reset_phy_params_vx_px(dp->link);
- msm_dp_display_send_hpd_notification(dp, true);
-
end:
return rc;
}
@@ -483,24 +353,6 @@ static void msm_dp_display_host_deinit(struct msm_dp_display_private *dp)
dp->core_initialized = false;
}
-static int msm_dp_display_usbpd_configure_cb(struct device *dev)
-{
- struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
-
- msm_dp_display_host_phy_init(dp);
-
- return msm_dp_display_process_hpd_high(dp);
-}
-
-static int msm_dp_display_notify_disconnect(struct device *dev)
-{
- struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
-
- msm_dp_display_send_hpd_notification(dp, false);
-
- return 0;
-}
-
static void msm_dp_display_handle_video_request(struct msm_dp_display_private *dp)
{
if (dp->link->sink_request & DP_TEST_LINK_VIDEO_PATTERN) {
@@ -509,34 +361,12 @@ static void msm_dp_display_handle_video_request(struct msm_dp_display_private *d
}
}
-static int msm_dp_display_handle_port_status_changed(struct msm_dp_display_private *dp)
-{
- int rc = 0;
-
- if (drm_dp_is_branch(dp->panel->dpcd) && dp->link->sink_count == 0) {
- drm_dbg_dp(dp->drm_dev, "sink count is zero, nothing to do\n");
- if (dp->hpd_state != ST_DISCONNECTED) {
- dp->hpd_state = ST_DISCONNECT_PENDING;
- msm_dp_display_send_hpd_notification(dp, false);
- }
- } else {
- if (dp->hpd_state == ST_DISCONNECTED) {
- dp->hpd_state = ST_MAINLINK_READY;
- rc = msm_dp_display_process_hpd_high(dp);
- if (rc)
- dp->hpd_state = ST_DISCONNECTED;
- }
- }
-
- return rc;
-}
-
static int msm_dp_display_handle_irq_hpd(struct msm_dp_display_private *dp)
{
u32 sink_request = dp->link->sink_request;
drm_dbg_dp(dp->drm_dev, "%d\n", sink_request);
- if (dp->hpd_state == ST_DISCONNECTED) {
+ if (!dp->msm_dp_display.link_ready) {
if (sink_request & DP_LINK_STATUS_UPDATED) {
drm_dbg_dp(dp->drm_dev, "Disconnected sink_request: %d\n",
sink_request);
@@ -553,76 +383,36 @@ static int msm_dp_display_handle_irq_hpd(struct msm_dp_display_private *dp)
return 0;
}
-static int msm_dp_display_usbpd_attention_cb(struct device *dev)
-{
- int rc = 0;
- u32 sink_request;
- struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
-
- /* check for any test request issued by sink */
- rc = msm_dp_link_process_request(dp->link);
- if (!rc) {
- sink_request = dp->link->sink_request;
- drm_dbg_dp(dp->drm_dev, "hpd_state=%d sink_request=%d\n",
- dp->hpd_state, sink_request);
- if (sink_request & DS_PORT_STATUS_CHANGED)
- rc = msm_dp_display_handle_port_status_changed(dp);
- else
- rc = msm_dp_display_handle_irq_hpd(dp);
- }
-
- return rc;
-}
-
static int msm_dp_hpd_plug_handle(struct msm_dp_display_private *dp)
{
- u32 state;
int ret;
struct platform_device *pdev = dp->msm_dp_display.pdev;
- msm_dp_aux_enable_xfers(dp->aux, true);
-
- mutex_lock(&dp->event_mutex);
-
- state = dp->hpd_state;
- drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
- dp->msm_dp_display.connector_type, state);
-
- if (state == ST_DISPLAY_OFF) {
- mutex_unlock(&dp->event_mutex);
- return 0;
- }
-
- if (state == ST_MAINLINK_READY || state == ST_CONNECTED) {
- mutex_unlock(&dp->event_mutex);
- return 0;
- }
+ drm_dbg_dp(dp->drm_dev, "Before, type=%d\n",
+ dp->msm_dp_display.connector_type);
- if (state == ST_DISCONNECT_PENDING) {
- /* wait until ST_DISCONNECTED */
- msm_dp_add_event(dp, EV_HPD_PLUG_INT, 1);
- mutex_unlock(&dp->event_mutex);
+ if (dp->msm_dp_display.link_ready)
return 0;
- }
ret = pm_runtime_resume_and_get(&pdev->dev);
if (ret) {
DRM_ERROR("failed to pm_runtime_resume\n");
- mutex_unlock(&dp->event_mutex);
return ret;
}
- ret = msm_dp_display_usbpd_configure_cb(&pdev->dev);
+ msm_dp_aux_enable_xfers(dp->aux, true);
+
+ msm_dp_display_host_phy_init(dp);
+
+ ret = msm_dp_display_process_hpd_high(dp);
if (ret) { /* link train failed */
- dp->hpd_state = ST_DISCONNECTED;
+ dp->msm_dp_display.link_ready = false;
+ msm_dp_aux_enable_xfers(dp->aux, false);
pm_runtime_put_sync(&pdev->dev);
- } else {
- dp->hpd_state = ST_MAINLINK_READY;
}
- drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
- dp->msm_dp_display.connector_type, state);
- mutex_unlock(&dp->event_mutex);
+ drm_dbg_dp(dp->drm_dev, "After, type=%d\n",
+ dp->msm_dp_display.connector_type);
/* uevent will complete connection part */
return 0;
@@ -644,97 +434,69 @@ static void msm_dp_display_handle_plugged_change(struct msm_dp *msm_dp_display,
static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp)
{
- u32 state;
struct platform_device *pdev = dp->msm_dp_display.pdev;
- msm_dp_aux_enable_xfers(dp->aux, false);
-
- mutex_lock(&dp->event_mutex);
-
- state = dp->hpd_state;
+ dp->panel->video_test = false;
- drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
- dp->msm_dp_display.connector_type, state);
+ msm_dp_aux_enable_xfers(dp->aux, false);
- /* unplugged, no more irq_hpd handle */
- msm_dp_del_event(dp, EV_IRQ_HPD_INT);
+ drm_dbg_dp(dp->drm_dev, "Before, type=%d\n",
+ dp->msm_dp_display.connector_type);
- if (state == ST_DISCONNECTED) {
- /* triggered by irq_hdp with sink_count = 0 */
- if (dp->link->sink_count == 0) {
- msm_dp_display_host_phy_exit(dp);
- }
- msm_dp_display_notify_disconnect(&dp->msm_dp_display.pdev->dev);
- mutex_unlock(&dp->event_mutex);
+ if (!dp->msm_dp_display.link_ready)
return 0;
- } else if (state == ST_DISCONNECT_PENDING) {
- mutex_unlock(&dp->event_mutex);
- return 0;
- } else if (state == ST_MAINLINK_READY) {
- msm_dp_ctrl_off_link(dp->ctrl);
+
+ /* triggered by irq_hdp with sink_count = 0 */
+ if (dp->link->sink_count == 0)
msm_dp_display_host_phy_exit(dp);
- dp->hpd_state = ST_DISCONNECTED;
- msm_dp_display_notify_disconnect(&dp->msm_dp_display.pdev->dev);
- pm_runtime_put_sync(&pdev->dev);
- mutex_unlock(&dp->event_mutex);
- return 0;
- }
/*
* We don't need separate work for disconnect as
* connect/attention interrupts are disabled
*/
- msm_dp_display_notify_disconnect(&dp->msm_dp_display.pdev->dev);
+ if (!dp->msm_dp_display.is_edp)
+ drm_dp_set_subconnector_property(dp->msm_dp_display.connector,
+ connector_status_disconnected,
+ dp->panel->dpcd,
+ dp->panel->downstream_ports);
- if (state == ST_DISPLAY_OFF) {
- dp->hpd_state = ST_DISCONNECTED;
- } else {
- dp->hpd_state = ST_DISCONNECT_PENDING;
- }
+ dp->msm_dp_display.link_ready = false;
/* signal the disconnect event early to ensure proper teardown */
msm_dp_display_handle_plugged_change(&dp->msm_dp_display, false);
- drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
- dp->msm_dp_display.connector_type, state);
+ drm_dbg_dp(dp->drm_dev, "After, type=%d\n",
+ dp->msm_dp_display.connector_type);
/* uevent will complete disconnection part */
pm_runtime_put_sync(&pdev->dev);
- mutex_unlock(&dp->event_mutex);
return 0;
}
static int msm_dp_irq_hpd_handle(struct msm_dp_display_private *dp)
{
- u32 state;
-
- mutex_lock(&dp->event_mutex);
+ u32 sink_request;
+ int rc = 0;
/* irq_hpd can happen at either connected or disconnected state */
- state = dp->hpd_state;
- drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
- dp->msm_dp_display.connector_type, state);
+ drm_dbg_dp(dp->drm_dev, "Before, type=%d\n",
+ dp->msm_dp_display.connector_type);
- if (state == ST_DISPLAY_OFF) {
- mutex_unlock(&dp->event_mutex);
- return 0;
- }
-
- if (state == ST_MAINLINK_READY || state == ST_DISCONNECT_PENDING) {
- /* wait until ST_CONNECTED */
- msm_dp_add_event(dp, EV_IRQ_HPD_INT, 1);
- mutex_unlock(&dp->event_mutex);
- return 0;
+ /* check for any test request issued by sink */
+ rc = msm_dp_link_process_request(dp->link);
+ if (!rc) {
+ sink_request = dp->link->sink_request;
+ drm_dbg_dp(dp->drm_dev, "sink_request=%d\n", sink_request);
+ if (sink_request & DS_PORT_STATUS_CHANGED)
+ rc = msm_dp_display_process_hpd_high(dp);
+ else
+ rc = msm_dp_display_handle_irq_hpd(dp);
}
- msm_dp_display_usbpd_attention_cb(&dp->msm_dp_display.pdev->dev);
+ drm_dbg_dp(dp->drm_dev, "After, type=%d\n",
+ dp->msm_dp_display.connector_type);
- drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
- dp->msm_dp_display.connector_type, state);
-
- mutex_unlock(&dp->event_mutex);
-
- return 0;
+ return rc;
}
static void msm_dp_display_deinit_sub_modules(struct msm_dp_display_private *dp)
@@ -1010,12 +772,8 @@ void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp)
* power_on status before dumping DP registers to avoid crash due
* to unclocked access
*/
- mutex_lock(&msm_dp_display->event_mutex);
-
- if (!dp->power_on) {
- mutex_unlock(&msm_dp_display->event_mutex);
+ if (!dp->power_on)
return;
- }
msm_disp_snapshot_add_block(disp_state, msm_dp_display->ahb_len,
msm_dp_display->ahb_base, "dp_ahb");
@@ -1025,8 +783,6 @@ void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp)
msm_dp_display->link_base, "dp_link");
msm_disp_snapshot_add_block(disp_state, msm_dp_display->p0_len,
msm_dp_display->p0_base, "dp_p0");
-
- mutex_unlock(&msm_dp_display->event_mutex);
}
void msm_dp_display_set_psr(struct msm_dp *msm_dp_display, bool enter)
@@ -1042,95 +798,6 @@ void msm_dp_display_set_psr(struct msm_dp *msm_dp_display, bool enter)
msm_dp_ctrl_set_psr(dp->ctrl, enter);
}
-static int hpd_event_thread(void *data)
-{
- struct msm_dp_display_private *msm_dp_priv;
- unsigned long flag;
- struct msm_dp_event *todo;
- int timeout_mode = 0;
-
- msm_dp_priv = (struct msm_dp_display_private *)data;
-
- while (1) {
- if (timeout_mode) {
- wait_event_timeout(msm_dp_priv->event_q,
- (msm_dp_priv->event_pndx == msm_dp_priv->event_gndx) ||
- kthread_should_stop(), EVENT_TIMEOUT);
- } else {
- wait_event_interruptible(msm_dp_priv->event_q,
- (msm_dp_priv->event_pndx != msm_dp_priv->event_gndx) ||
- kthread_should_stop());
- }
-
- if (kthread_should_stop())
- break;
-
- spin_lock_irqsave(&msm_dp_priv->event_lock, flag);
- todo = &msm_dp_priv->event_list[msm_dp_priv->event_gndx];
- if (todo->delay) {
- struct msm_dp_event *todo_next;
-
- msm_dp_priv->event_gndx++;
- msm_dp_priv->event_gndx %= DP_EVENT_Q_MAX;
-
- /* re enter delay event into q */
- todo_next = &msm_dp_priv->event_list[msm_dp_priv->event_pndx++];
- msm_dp_priv->event_pndx %= DP_EVENT_Q_MAX;
- todo_next->event_id = todo->event_id;
- todo_next->delay = todo->delay - 1;
-
- /* clean up older event */
- todo->event_id = EV_NO_EVENT;
- todo->delay = 0;
-
- /* switch to timeout mode */
- timeout_mode = 1;
- spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
- continue;
- }
-
- /* timeout with no events in q */
- if (msm_dp_priv->event_pndx == msm_dp_priv->event_gndx) {
- spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
- continue;
- }
-
- msm_dp_priv->event_gndx++;
- msm_dp_priv->event_gndx %= DP_EVENT_Q_MAX;
- timeout_mode = 0;
- spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
-
- switch (todo->event_id) {
- case EV_HPD_PLUG_INT:
- msm_dp_hpd_plug_handle(msm_dp_priv);
- break;
- case EV_HPD_UNPLUG_INT:
- msm_dp_hpd_unplug_handle(msm_dp_priv);
- break;
- case EV_IRQ_HPD_INT:
- msm_dp_irq_hpd_handle(msm_dp_priv);
- break;
- default:
- break;
- }
- }
-
- return 0;
-}
-
-static int msm_dp_hpd_event_thread_start(struct msm_dp_display_private *msm_dp_priv)
-{
- /* set event q to empty */
- msm_dp_priv->event_gndx = 0;
- msm_dp_priv->event_pndx = 0;
-
- msm_dp_priv->ev_tsk = kthread_run(hpd_event_thread, msm_dp_priv, "dp_hpd_handler");
- if (IS_ERR(msm_dp_priv->ev_tsk))
- return PTR_ERR(msm_dp_priv->ev_tsk);
-
- return 0;
-}
-
/**
* msm_dp_bridge_detect - callback to determine if connector is connected
* @bridge: Pointer to drm bridge structure
@@ -1155,26 +822,31 @@ enum drm_connector_status msm_dp_bridge_detect(struct drm_bridge *bridge,
if (!dp->link_ready)
return status;
- msm_dp_aux_enable_xfers(priv->aux, true);
-
ret = pm_runtime_resume_and_get(&dp->pdev->dev);
if (ret) {
DRM_ERROR("failed to pm_runtime_resume\n");
- msm_dp_aux_enable_xfers(priv->aux, false);
return status;
}
+ msm_dp_aux_enable_xfers(priv->aux, true);
+
ret = msm_dp_aux_is_link_connected(priv->aux);
- if (dp->internal_hpd && !ret)
+ if (!ret) {
+ DRM_DEBUG_DP("aux not connected\n");
goto end;
+ }
ret = drm_dp_read_dpcd_caps(priv->aux, dpcd);
- if (ret)
+ if (ret) {
+ DRM_DEBUG_DP("failed to read caps\n");
goto end;
+ }
ret = drm_dp_read_desc(priv->aux, &desc, drm_dp_is_branch(dpcd));
- if (ret)
+ if (ret) {
+ DRM_DEBUG_DP("failed to read desc\n");
goto end;
+ }
status = connector_status_connected;
if (drm_dp_read_sink_count_cap(connector, dpcd, &desc)) {
@@ -1194,36 +866,20 @@ enum drm_connector_status msm_dp_bridge_detect(struct drm_bridge *bridge,
static irqreturn_t msm_dp_display_irq_handler(int irq, void *dev_id)
{
struct msm_dp_display_private *dp = dev_id;
- irqreturn_t ret = IRQ_NONE;
u32 hpd_isr_status;
-
- if (!dp) {
- DRM_ERROR("invalid data\n");
- return IRQ_NONE;
- }
+ unsigned long flags;
+ irqreturn_t ret = IRQ_HANDLED;
hpd_isr_status = msm_dp_aux_get_hpd_intr_status(dp->aux);
if (hpd_isr_status & 0x0F) {
drm_dbg_dp(dp->drm_dev, "type=%d isr=0x%x\n",
dp->msm_dp_display.connector_type, hpd_isr_status);
- /* hpd related interrupts */
- if (hpd_isr_status & DP_DP_HPD_PLUG_INT_MASK)
- msm_dp_add_event(dp, EV_HPD_PLUG_INT, 0);
-
- if (hpd_isr_status & DP_DP_IRQ_HPD_INT_MASK) {
- msm_dp_add_event(dp, EV_IRQ_HPD_INT, 0);
- }
- if (hpd_isr_status & DP_DP_HPD_REPLUG_INT_MASK) {
- msm_dp_add_event(dp, EV_HPD_UNPLUG_INT, 0);
- msm_dp_add_event(dp, EV_HPD_PLUG_INT, 3);
- }
-
- if (hpd_isr_status & DP_DP_HPD_UNPLUG_INT_MASK)
- msm_dp_add_event(dp, EV_HPD_UNPLUG_INT, 0);
-
- ret = IRQ_HANDLED;
+ spin_lock_irqsave(&dp->irq_thread_lock, flags);
+ dp->hpd_isr_status |= hpd_isr_status;
+ ret = IRQ_WAKE_THREAD;
+ spin_unlock_irqrestore(&dp->irq_thread_lock, flags);
}
/* DP controller isr */
@@ -1232,6 +888,36 @@ static irqreturn_t msm_dp_display_irq_handler(int irq, void *dev_id)
return ret;
}
+static irqreturn_t msm_dp_display_irq_thread(int irq, void *dev_id)
+{
+ struct msm_dp_display_private *dp = dev_id;
+ irqreturn_t ret = IRQ_NONE;
+ unsigned long flags;
+ u32 hpd_isr_status;
+
+ spin_lock_irqsave(&dp->irq_thread_lock, flags);
+ hpd_isr_status = dp->hpd_isr_status;
+ dp->hpd_isr_status = 0;
+ spin_unlock_irqrestore(&dp->irq_thread_lock, flags);
+
+ if (hpd_isr_status & DP_DP_HPD_UNPLUG_INT_MASK)
+ drm_bridge_hpd_notify(dp->msm_dp_display.bridge,
+ connector_status_disconnected);
+
+ if (hpd_isr_status & DP_DP_HPD_PLUG_INT_MASK)
+ drm_bridge_hpd_notify(dp->msm_dp_display.bridge,
+ connector_status_connected);
+
+ /* Send HPD as connected and distinguish it in the notifier */
+ if (hpd_isr_status & DP_DP_IRQ_HPD_INT_MASK)
+ drm_bridge_hpd_notify(dp->msm_dp_display.bridge,
+ connector_status_connected);
+
+ ret = IRQ_HANDLED;
+
+ return ret;
+}
+
static int msm_dp_display_request_irq(struct msm_dp_display_private *dp)
{
int rc = 0;
@@ -1243,9 +929,13 @@ static int msm_dp_display_request_irq(struct msm_dp_display_private *dp)
return dp->irq;
}
- rc = devm_request_irq(&pdev->dev, dp->irq, msm_dp_display_irq_handler,
- IRQF_TRIGGER_HIGH|IRQF_NO_AUTOEN,
- "dp_display_isr", dp);
+ spin_lock_init(&dp->irq_thread_lock);
+ irq_set_status_flags(dp->irq, IRQ_NOAUTOEN);
+ rc = devm_request_threaded_irq(&pdev->dev, dp->irq,
+ msm_dp_display_irq_handler,
+ msm_dp_display_irq_thread,
+ IRQ_TYPE_LEVEL_HIGH,
+ "dp_display_isr", dp);
if (rc < 0) {
DRM_ERROR("failed to request IRQ%u: %d\n",
@@ -1425,6 +1115,7 @@ static int msm_dp_display_probe(struct platform_device *pdev)
dp->wide_bus_supported = desc->wide_bus_supported;
dp->msm_dp_display.is_edp =
(dp->msm_dp_display.connector_type == DRM_MODE_CONNECTOR_eDP);
+ dp->hpd_isr_status = 0;
rc = msm_dp_display_get_io(dp);
if (rc)
@@ -1436,11 +1127,6 @@ static int msm_dp_display_probe(struct platform_device *pdev)
return -EPROBE_DEFER;
}
- /* setup event q */
- mutex_init(&dp->event_mutex);
- init_waitqueue_head(&dp->event_q);
- spin_lock_init(&dp->event_lock);
-
/* Store DP audio handle inside DP display */
dp->msm_dp_display.msm_dp_audio = dp->audio;
@@ -1636,7 +1322,6 @@ void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
int rc = 0;
struct msm_dp_display_private *msm_dp_display;
- u32 hpd_state;
bool force_link_train = false;
msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
@@ -1648,29 +1333,21 @@ void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
if (dp->is_edp)
msm_dp_hpd_plug_handle(msm_dp_display);
- mutex_lock(&msm_dp_display->event_mutex);
if (pm_runtime_resume_and_get(&dp->pdev->dev)) {
DRM_ERROR("failed to pm_runtime_resume\n");
- mutex_unlock(&msm_dp_display->event_mutex);
return;
}
- hpd_state = msm_dp_display->hpd_state;
- if (hpd_state != ST_DISPLAY_OFF && hpd_state != ST_MAINLINK_READY) {
- mutex_unlock(&msm_dp_display->event_mutex);
+ if (msm_dp_display->link->sink_count == 0)
return;
- }
rc = msm_dp_display_set_mode(dp, &msm_dp_display->msm_dp_mode);
if (rc) {
DRM_ERROR("Failed to perform a mode set, rc=%d\n", rc);
- mutex_unlock(&msm_dp_display->event_mutex);
return;
}
- hpd_state = msm_dp_display->hpd_state;
-
- if (hpd_state == ST_DISPLAY_OFF) {
+ if (dp->link_ready && !dp->power_on) {
msm_dp_display_host_phy_init(msm_dp_display);
force_link_train = true;
}
@@ -1688,11 +1365,7 @@ void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
msm_dp_display_disable(msm_dp_display);
}
- /* completed connection */
- msm_dp_display->hpd_state = ST_CONNECTED;
-
drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);
- mutex_unlock(&msm_dp_display->event_mutex);
}
void msm_dp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
@@ -1712,7 +1385,6 @@ void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
{
struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge);
struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
- u32 hpd_state;
struct msm_dp_display_private *msm_dp_display;
msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
@@ -1720,27 +1392,14 @@ void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
if (dp->is_edp)
msm_dp_hpd_unplug_handle(msm_dp_display);
- mutex_lock(&msm_dp_display->event_mutex);
-
- hpd_state = msm_dp_display->hpd_state;
- if (hpd_state != ST_DISCONNECT_PENDING && hpd_state != ST_CONNECTED)
- drm_dbg_dp(dp->drm_dev, "type=%d wrong hpd_state=%d\n",
- dp->connector_type, hpd_state);
+ if (!dp->link_ready)
+ drm_dbg_dp(dp->drm_dev, "type=%d is disconnected\n", dp->connector_type);
msm_dp_display_disable(msm_dp_display);
- hpd_state = msm_dp_display->hpd_state;
- if (hpd_state == ST_DISCONNECT_PENDING) {
- /* completed disconnection */
- msm_dp_display->hpd_state = ST_DISCONNECTED;
- } else {
- msm_dp_display->hpd_state = ST_DISPLAY_OFF;
- }
-
drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);
pm_runtime_put_sync(&dp->pdev->dev);
- mutex_unlock(&msm_dp_display->event_mutex);
}
void msm_dp_bridge_mode_set(struct drm_bridge *drm_bridge,
@@ -1796,18 +1455,13 @@ void msm_dp_bridge_hpd_enable(struct drm_bridge *bridge)
* step-4: DP PHY is initialized at plugin handler before link training
*
*/
- mutex_lock(&dp->event_mutex);
if (pm_runtime_resume_and_get(&msm_dp_display->pdev->dev)) {
DRM_ERROR("failed to resume power\n");
- mutex_unlock(&dp->event_mutex);
return;
}
msm_dp_aux_hpd_enable(dp->aux);
msm_dp_aux_hpd_intr_enable(dp->aux);
-
- msm_dp_display->internal_hpd = true;
- mutex_unlock(&dp->event_mutex);
}
void msm_dp_bridge_hpd_disable(struct drm_bridge *bridge)
@@ -1816,15 +1470,10 @@ void msm_dp_bridge_hpd_disable(struct drm_bridge *bridge)
struct msm_dp *msm_dp_display = msm_dp_bridge->msm_dp_display;
struct msm_dp_display_private *dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
- mutex_lock(&dp->event_mutex);
-
msm_dp_aux_hpd_intr_disable(dp->aux);
msm_dp_aux_hpd_disable(dp->aux);
- msm_dp_display->internal_hpd = false;
-
pm_runtime_put_sync(&msm_dp_display->pdev->dev);
- mutex_unlock(&dp->event_mutex);
}
void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
@@ -1834,13 +1483,31 @@ void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(bridge);
struct msm_dp *msm_dp_display = msm_dp_bridge->msm_dp_display;
struct msm_dp_display_private *dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+ u32 hpd_link_status = 0;
- /* Without next_bridge interrupts are handled by the DP core directly */
- if (msm_dp_display->internal_hpd)
+ if (pm_runtime_resume_and_get(&msm_dp_display->pdev->dev)) {
+ DRM_ERROR("failed to pm_runtime_resume\n");
return;
+ }
+
+ hpd_link_status = msm_dp_aux_is_link_connected(dp->aux);
- if (!msm_dp_display->link_ready && status == connector_status_connected)
- msm_dp_add_event(dp, EV_HPD_PLUG_INT, 0);
- else if (msm_dp_display->link_ready && status == connector_status_disconnected)
- msm_dp_add_event(dp, EV_HPD_UNPLUG_INT, 0);
+ drm_dbg_dp(dp->drm_dev, "type=%d link hpd_link_status=0x%x, link_ready=%d, status=%d\n",
+ msm_dp_display->connector_type, hpd_link_status,
+ msm_dp_display->link_ready, status);
+
+ if (status == connector_status_connected) {
+ if (hpd_link_status == ISR_HPD_REPLUG_COUNT) {
+ msm_dp_hpd_unplug_handle(dp);
+ msm_dp_hpd_plug_handle(dp);
+ } else if (hpd_link_status == ISR_IRQ_HPD_PULSE_COUNT) {
+ msm_dp_irq_hpd_handle(dp);
+ } else {
+ msm_dp_hpd_plug_handle(dp);
+ }
+ } else {
+ msm_dp_hpd_unplug_handle(dp);
+ }
+
+ pm_runtime_put_sync(&msm_dp_display->pdev->dev);
}
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
index 60094061c102..d2d3d61eb0b0 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -22,7 +22,6 @@ struct msm_dp {
bool power_on;
unsigned int connector_type;
bool is_edp;
- bool internal_hpd;
struct msm_dp_audio *msm_dp_audio;
bool psr_supported;
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v5 08/10] drm/msm/dp: Add sink_count to debug logs
2026-03-14 1:09 [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine Dmitry Baryshkov
` (6 preceding siblings ...)
2026-03-14 1:09 ` [PATCH v5 07/10] drm/msm/dp: rework HPD handling Dmitry Baryshkov
@ 2026-03-14 1:09 ` Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 09/10] drm/msm/dp: turn link_ready into plugged Dmitry Baryshkov
` (2 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Dmitry Baryshkov @ 2026-03-14 1:09 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Kuogee Hsieh, Yongxing Mou
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jessica Zhang
From: Jessica Zhang <jesszhan0024@gmail.com>
Add sink count to the debug logs for [un]plug and HPD IRQ handling.
Signed-off-by: Jessica Zhang <jessica.zhang@oss.qualcomm.com>
[DB: dropped link_ready handling]
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/msm/dp/dp_display.c | 30 ++++++++++++++++++------------
1 file changed, 18 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index d61a8ddd30a8..b4deeea0ec59 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -388,8 +388,9 @@ static int msm_dp_hpd_plug_handle(struct msm_dp_display_private *dp)
int ret;
struct platform_device *pdev = dp->msm_dp_display.pdev;
- drm_dbg_dp(dp->drm_dev, "Before, type=%d\n",
- dp->msm_dp_display.connector_type);
+ drm_dbg_dp(dp->drm_dev, "Before, type=%d sink_count=%d\n",
+ dp->msm_dp_display.connector_type,
+ dp->link->sink_count);
if (dp->msm_dp_display.link_ready)
return 0;
@@ -411,8 +412,9 @@ static int msm_dp_hpd_plug_handle(struct msm_dp_display_private *dp)
pm_runtime_put_sync(&pdev->dev);
}
- drm_dbg_dp(dp->drm_dev, "After, type=%d\n",
- dp->msm_dp_display.connector_type);
+ drm_dbg_dp(dp->drm_dev, "After, type=%d sink_count=%d\n",
+ dp->msm_dp_display.connector_type,
+ dp->link->sink_count);
/* uevent will complete connection part */
return 0;
@@ -440,8 +442,9 @@ static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp)
msm_dp_aux_enable_xfers(dp->aux, false);
- drm_dbg_dp(dp->drm_dev, "Before, type=%d\n",
- dp->msm_dp_display.connector_type);
+ drm_dbg_dp(dp->drm_dev, "Before, type=%d sink_count=%d\n",
+ dp->msm_dp_display.connector_type,
+ dp->link->sink_count);
if (!dp->msm_dp_display.link_ready)
return 0;
@@ -465,8 +468,9 @@ static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp)
/* signal the disconnect event early to ensure proper teardown */
msm_dp_display_handle_plugged_change(&dp->msm_dp_display, false);
- drm_dbg_dp(dp->drm_dev, "After, type=%d\n",
- dp->msm_dp_display.connector_type);
+ drm_dbg_dp(dp->drm_dev, "After, type=%d, sink_count=%d\n",
+ dp->msm_dp_display.connector_type,
+ dp->link->sink_count);
/* uevent will complete disconnection part */
pm_runtime_put_sync(&pdev->dev);
@@ -479,8 +483,9 @@ static int msm_dp_irq_hpd_handle(struct msm_dp_display_private *dp)
int rc = 0;
/* irq_hpd can happen at either connected or disconnected state */
- drm_dbg_dp(dp->drm_dev, "Before, type=%d\n",
- dp->msm_dp_display.connector_type);
+ drm_dbg_dp(dp->drm_dev, "Before, type=%d, sink_count=%d\n",
+ dp->msm_dp_display.connector_type,
+ dp->link->sink_count);
/* check for any test request issued by sink */
rc = msm_dp_link_process_request(dp->link);
@@ -493,8 +498,9 @@ static int msm_dp_irq_hpd_handle(struct msm_dp_display_private *dp)
rc = msm_dp_display_handle_irq_hpd(dp);
}
- drm_dbg_dp(dp->drm_dev, "After, type=%d\n",
- dp->msm_dp_display.connector_type);
+ drm_dbg_dp(dp->drm_dev, "After, type=%d, sink_count=%d\n",
+ dp->msm_dp_display.connector_type,
+ dp->link->sink_count);
return rc;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v5 09/10] drm/msm/dp: turn link_ready into plugged
2026-03-14 1:09 [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine Dmitry Baryshkov
` (7 preceding siblings ...)
2026-03-14 1:09 ` [PATCH v5 08/10] drm/msm/dp: Add sink_count to debug logs Dmitry Baryshkov
@ 2026-03-14 1:09 ` Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 10/10] drm/msm/dp: clear EDID on display unplug Dmitry Baryshkov
2026-03-15 0:51 ` [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine Val Packett
10 siblings, 0 replies; 17+ messages in thread
From: Dmitry Baryshkov @ 2026-03-14 1:09 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Kuogee Hsieh, Yongxing Mou
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel
Tracking when the DP link is ready isn't that useful from the driver
point of view. It doesn't provide a direct information if the device
should be suspended, etc. Replace it with the 'plugged' boolean, which
is set when the driver knows that there is DPRX plugged.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/msm/dp/dp_display.c | 94 ++++++++++++++++++++++---------------
drivers/gpu/drm/msm/dp/dp_display.h | 1 -
drivers/gpu/drm/msm/dp/dp_drm.c | 41 ++--------------
3 files changed, 61 insertions(+), 75 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index b4deeea0ec59..0a38957ea901 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -53,6 +53,9 @@ struct msm_dp_display_private {
bool phy_initialized;
bool audio_supported;
+ struct mutex plugged_lock;
+ bool plugged;
+
struct drm_device *drm_dev;
struct drm_dp_aux *aux;
@@ -284,8 +287,6 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)
dp->panel->dpcd,
dp->panel->downstream_ports);
- dp->msm_dp_display.link_ready = true;
-
dp->msm_dp_display.psr_supported = dp->panel->psr_cap.version && psr_enabled;
dp->audio_supported = info->has_audio;
@@ -303,7 +304,7 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)
return rc;
}
-static void msm_dp_display_host_phy_init(struct msm_dp_display_private *dp)
+static bool msm_dp_display_host_phy_init(struct msm_dp_display_private *dp)
{
drm_dbg_dp(dp->drm_dev, "type=%d core_init=%d phy_init=%d\n",
dp->msm_dp_display.connector_type, dp->core_initialized,
@@ -312,7 +313,10 @@ static void msm_dp_display_host_phy_init(struct msm_dp_display_private *dp)
if (!dp->phy_initialized) {
msm_dp_ctrl_phy_init(dp->ctrl);
dp->phy_initialized = true;
+ return true;
}
+
+ return false;
}
static void msm_dp_display_host_phy_exit(struct msm_dp_display_private *dp)
@@ -366,14 +370,6 @@ static int msm_dp_display_handle_irq_hpd(struct msm_dp_display_private *dp)
u32 sink_request = dp->link->sink_request;
drm_dbg_dp(dp->drm_dev, "%d\n", sink_request);
- if (!dp->msm_dp_display.link_ready) {
- if (sink_request & DP_LINK_STATUS_UPDATED) {
- drm_dbg_dp(dp->drm_dev, "Disconnected sink_request: %d\n",
- sink_request);
- DRM_ERROR("Disconnected, no DP_LINK_STATUS_UPDATED\n");
- return -EINVAL;
- }
- }
msm_dp_ctrl_handle_sink_request(dp->ctrl);
@@ -392,11 +388,11 @@ static int msm_dp_hpd_plug_handle(struct msm_dp_display_private *dp)
dp->msm_dp_display.connector_type,
dp->link->sink_count);
- if (dp->msm_dp_display.link_ready)
- return 0;
+ mutex_lock(&dp->plugged_lock);
ret = pm_runtime_resume_and_get(&pdev->dev);
if (ret) {
+ mutex_unlock(&dp->plugged_lock);
DRM_ERROR("failed to pm_runtime_resume\n");
return ret;
}
@@ -406,18 +402,16 @@ static int msm_dp_hpd_plug_handle(struct msm_dp_display_private *dp)
msm_dp_display_host_phy_init(dp);
ret = msm_dp_display_process_hpd_high(dp);
- if (ret) { /* link train failed */
- dp->msm_dp_display.link_ready = false;
- msm_dp_aux_enable_xfers(dp->aux, false);
- pm_runtime_put_sync(&pdev->dev);
- }
drm_dbg_dp(dp->drm_dev, "After, type=%d sink_count=%d\n",
dp->msm_dp_display.connector_type,
dp->link->sink_count);
- /* uevent will complete connection part */
- return 0;
+ dp->plugged = true;
+
+ mutex_unlock(&dp->plugged_lock);
+
+ return ret;
};
static void msm_dp_display_handle_plugged_change(struct msm_dp *msm_dp_display,
@@ -446,8 +440,12 @@ static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp)
dp->msm_dp_display.connector_type,
dp->link->sink_count);
- if (!dp->msm_dp_display.link_ready)
+ mutex_lock(&dp->plugged_lock);
+ if (!dp->plugged) {
+ mutex_unlock(&dp->plugged_lock);
+
return 0;
+ }
/* triggered by irq_hdp with sink_count = 0 */
if (dp->link->sink_count == 0)
@@ -463,8 +461,6 @@ static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp)
dp->panel->dpcd,
dp->panel->downstream_ports);
- dp->msm_dp_display.link_ready = false;
-
/* signal the disconnect event early to ensure proper teardown */
msm_dp_display_handle_plugged_change(&dp->msm_dp_display, false);
@@ -472,8 +468,12 @@ static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp)
dp->msm_dp_display.connector_type,
dp->link->sink_count);
- /* uevent will complete disconnection part */
- pm_runtime_put_sync(&pdev->dev);
+ if (dp->plugged) {
+ pm_runtime_put_sync(&pdev->dev);
+ dp->plugged = false;
+ }
+ mutex_unlock(&dp->plugged_lock);
+
return 0;
}
@@ -820,41 +820,49 @@ enum drm_connector_status msm_dp_bridge_detect(struct drm_bridge *bridge,
int status = connector_status_disconnected;
u8 dpcd[DP_RECEIVER_CAP_SIZE];
struct drm_dp_desc desc;
+ bool phy_deinit;
dp = to_dp_bridge(bridge)->msm_dp_display;
priv = container_of(dp, struct msm_dp_display_private, msm_dp_display);
- if (!dp->link_ready)
- return status;
-
+ mutex_lock(&priv->plugged_lock);
ret = pm_runtime_resume_and_get(&dp->pdev->dev);
if (ret) {
DRM_ERROR("failed to pm_runtime_resume\n");
+ mutex_unlock(&priv->plugged_lock);
return status;
}
+ phy_deinit = msm_dp_display_host_phy_init(priv);
+
msm_dp_aux_enable_xfers(priv->aux, true);
ret = msm_dp_aux_is_link_connected(priv->aux);
- if (!ret) {
+ DRM_DEBUG_DP("aux link status: %x\n", ret);
+ if (!priv->plugged && !ret) {
DRM_DEBUG_DP("aux not connected\n");
+ priv->plugged = false;
goto end;
}
ret = drm_dp_read_dpcd_caps(priv->aux, dpcd);
if (ret) {
DRM_DEBUG_DP("failed to read caps\n");
+ priv->plugged = false;
goto end;
}
ret = drm_dp_read_desc(priv->aux, &desc, drm_dp_is_branch(dpcd));
if (ret) {
DRM_DEBUG_DP("failed to read desc\n");
+ priv->plugged = false;
goto end;
}
status = connector_status_connected;
+ priv->plugged = true;
+
if (drm_dp_read_sink_count_cap(connector, dpcd, &desc)) {
int sink_count = drm_dp_read_sink_count(priv->aux);
@@ -865,7 +873,21 @@ enum drm_connector_status msm_dp_bridge_detect(struct drm_bridge *bridge,
}
end:
- pm_runtime_put_sync(&dp->pdev->dev);
+ /*
+ * If we detected the DPRX, leave the controller on so that it doesn't
+ * loose the state.
+ */
+ if (!priv->plugged) {
+ if (phy_deinit) {
+ msm_dp_aux_enable_xfers(priv->aux, false);
+ msm_dp_display_host_phy_exit(priv);
+ }
+
+ pm_runtime_put_sync(&dp->pdev->dev);
+ }
+
+ mutex_unlock(&priv->plugged_lock);
+
return status;
}
@@ -1123,6 +1145,8 @@ static int msm_dp_display_probe(struct platform_device *pdev)
(dp->msm_dp_display.connector_type == DRM_MODE_CONNECTOR_eDP);
dp->hpd_isr_status = 0;
+ mutex_init(&dp->plugged_lock);
+
rc = msm_dp_display_get_io(dp);
if (rc)
return rc;
@@ -1353,7 +1377,7 @@ void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
return;
}
- if (dp->link_ready && !dp->power_on) {
+ if (!dp->power_on) {
msm_dp_display_host_phy_init(msm_dp_display);
force_link_train = true;
}
@@ -1398,9 +1422,6 @@ void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
if (dp->is_edp)
msm_dp_hpd_unplug_handle(msm_dp_display);
- if (!dp->link_ready)
- drm_dbg_dp(dp->drm_dev, "type=%d is disconnected\n", dp->connector_type);
-
msm_dp_display_disable(msm_dp_display);
drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);
@@ -1498,9 +1519,8 @@ void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
hpd_link_status = msm_dp_aux_is_link_connected(dp->aux);
- drm_dbg_dp(dp->drm_dev, "type=%d link hpd_link_status=0x%x, link_ready=%d, status=%d\n",
- msm_dp_display->connector_type, hpd_link_status,
- msm_dp_display->link_ready, status);
+ drm_dbg_dp(dp->drm_dev, "type=%d link hpd_link_status=0x%x, status=%d\n",
+ msm_dp_display->connector_type, hpd_link_status, status);
if (status == connector_status_connected) {
if (hpd_link_status == ISR_HPD_REPLUG_COUNT) {
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
index d2d3d61eb0b0..0b65e16c790d 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -17,7 +17,6 @@ struct msm_dp {
struct drm_connector *connector;
struct drm_bridge *next_bridge;
struct drm_bridge *bridge;
- bool link_ready;
bool audio_enabled;
bool power_on;
unsigned int connector_type;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index f935093c4df4..8dc0dabd275c 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -15,36 +15,6 @@
#include "dp_audio.h"
#include "dp_drm.h"
-static int msm_dp_bridge_atomic_check(struct drm_bridge *bridge,
- struct drm_bridge_state *bridge_state,
- struct drm_crtc_state *crtc_state,
- struct drm_connector_state *conn_state)
-{
- struct msm_dp *dp;
-
- dp = to_dp_bridge(bridge)->msm_dp_display;
-
- drm_dbg_dp(dp->drm_dev, "link_ready = %s\n",
- str_true_false(dp->link_ready));
-
- /*
- * There is no protection in the DRM framework to check if the display
- * pipeline has been already disabled before trying to disable it again.
- * Hence if the sink is unplugged, the pipeline gets disabled, but the
- * crtc->active is still true. Any attempt to set the mode or manually
- * disable this encoder will result in the crash.
- *
- * TODO: add support for telling the DRM subsystem that the pipeline is
- * disabled by the hardware and thus all access to it should be forbidden.
- * After that this piece of code can be removed.
- */
- if (bridge->ops & DRM_BRIDGE_OP_HPD)
- return (dp->link_ready) ? 0 : -ENOTCONN;
-
- return 0;
-}
-
-
/**
* msm_dp_bridge_get_modes - callback to add drm modes via drm_mode_probed_add()
* @bridge: Poiner to drm bridge
@@ -62,12 +32,10 @@ static int msm_dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connect
dp = to_dp_bridge(bridge)->msm_dp_display;
/* pluggable case assumes EDID is read when HPD */
- if (dp->link_ready) {
- rc = msm_dp_display_get_modes(dp);
- if (rc <= 0) {
- DRM_ERROR("failed to get DP sink modes, rc=%d\n", rc);
- return rc;
- }
+ rc = msm_dp_display_get_modes(dp);
+ if (rc <= 0) {
+ DRM_ERROR("failed to get DP sink modes, rc=%d\n", rc);
+ return rc;
} else {
drm_dbg_dp(connector->dev, "No sink connected\n");
}
@@ -92,7 +60,6 @@ static const struct drm_bridge_funcs msm_dp_bridge_ops = {
.mode_valid = msm_dp_bridge_mode_valid,
.get_modes = msm_dp_bridge_get_modes,
.detect = msm_dp_bridge_detect,
- .atomic_check = msm_dp_bridge_atomic_check,
.hpd_enable = msm_dp_bridge_hpd_enable,
.hpd_disable = msm_dp_bridge_hpd_disable,
.hpd_notify = msm_dp_bridge_hpd_notify,
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v5 10/10] drm/msm/dp: clear EDID on display unplug
2026-03-14 1:09 [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine Dmitry Baryshkov
` (8 preceding siblings ...)
2026-03-14 1:09 ` [PATCH v5 09/10] drm/msm/dp: turn link_ready into plugged Dmitry Baryshkov
@ 2026-03-14 1:09 ` Dmitry Baryshkov
2026-03-15 0:51 ` [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine Val Packett
10 siblings, 0 replies; 17+ messages in thread
From: Dmitry Baryshkov @ 2026-03-14 1:09 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Kuogee Hsieh, Yongxing Mou
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel
Currently the driver only updates the EDID when it detects a connected
monitor, which results in the connector still listing outdated modes
even after the display is unplugged. Set connector's EDID to NULL on
unplug to clear the list of modes.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/msm/dp/dp_display.c | 4 ++++
drivers/gpu/drm/msm/dp/dp_panel.c | 8 ++++++++
drivers/gpu/drm/msm/dp/dp_panel.h | 2 ++
3 files changed, 14 insertions(+)
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 0a38957ea901..5c6a24ec140d 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -447,6 +447,10 @@ static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp)
return 0;
}
+ /* Don't forget modes for eDP */
+ if (!dp->msm_dp_display.is_edp)
+ msm_dp_panel_unplugged(dp->panel, dp->msm_dp_display.connector);
+
/* triggered by irq_hdp with sink_count = 0 */
if (dp->link->sink_count == 0)
msm_dp_display_host_phy_exit(dp);
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c
index 891211b23202..6bb021820d7c 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.c
+++ b/drivers/gpu/drm/msm/dp/dp_panel.c
@@ -293,6 +293,14 @@ int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel,
return rc;
}
+void msm_dp_panel_unplugged(struct msm_dp_panel *msm_dp_panel,
+ struct drm_connector *connector)
+{
+ drm_edid_connector_update(connector, NULL);
+ drm_edid_free(msm_dp_panel->drm_edid);
+ msm_dp_panel->drm_edid = NULL;
+}
+
u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel,
u32 mode_edid_bpp, u32 mode_pclk_khz)
{
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.h b/drivers/gpu/drm/msm/dp/dp_panel.h
index 177c1328fd99..9173e90a5053 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.h
+++ b/drivers/gpu/drm/msm/dp/dp_panel.h
@@ -49,6 +49,8 @@ int msm_dp_panel_deinit(struct msm_dp_panel *msm_dp_panel);
int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel, bool wide_bus_en);
int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel,
struct drm_connector *connector);
+void msm_dp_panel_unplugged(struct msm_dp_panel *msm_dp_panel,
+ struct drm_connector *connector);
u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel, u32 mode_max_bpp,
u32 mode_pclk_khz);
int msm_dp_panel_get_modes(struct msm_dp_panel *msm_dp_panel,
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine
2026-03-14 1:09 [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine Dmitry Baryshkov
` (9 preceding siblings ...)
2026-03-14 1:09 ` [PATCH v5 10/10] drm/msm/dp: clear EDID on display unplug Dmitry Baryshkov
@ 2026-03-15 0:51 ` Val Packett
2026-03-15 1:10 ` Val Packett
10 siblings, 1 reply; 17+ messages in thread
From: Val Packett @ 2026-03-15 0:51 UTC (permalink / raw)
To: Dmitry Baryshkov, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, Kuogee Hsieh, Yongxing Mou
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel
On 3/13/26 10:09 PM, Dmitry Baryshkov wrote:
> Currently, all HPD interrupt handling must go through the HPD state
> machine.
>
> This has caused many issues where the DRM framework assumes that DP is
> in one state while the state machine is stuck in another state.
>
> As discussed here [1], this series:
>
> - Removes the state machine
> - Moves link training to atomic_enable()
> - Changes the detect() behavior to return true if a display is physically
> plugged in (as opposed to if the DP link is ready).
> - Remove event queue and move internal HPD handling to hpd_notify()
>
> To correctly detect the displays which are plugged on boot on the boards
> which use dp-connector devices, this series depends on [2]. USB-C and
> eDP panels are handled natively.
>
> [1] https://patchwork.freedesktop.org/patch/656312/?series=142010&rev=2#comment_1201738
> [2] https://lore.kernel.org/all/20260314-dp-connector-hpd-v1-0-786044cedc17@oss.qualcomm.com/
Unfortunately this currently seems to mostly break link training with
USB-C, on x1e80100-dell-latitude-7455:
[ 102.190083] [drm:msm_dp_ctrl_link_train_1_2 [msm]] *ERROR* link
training #2 on phy 1 failed. ret=-110
[ 102.192846] [drm:msm_dp_ctrl_setup_main_link [msm]] *ERROR* link
training of LTTPR(s) failed. ret=-110
[ 102.211095] [drm:msm_dp_bridge_atomic_enable [msm]] *ERROR* Failed
link training (rc=-104)
[ 102.211164] [drm:msm_dp_aux_isr [msm]] *ERROR* Unexpected DP AUX IRQ
0x01000000 when not busy
[ 102.247168] [drm:msm_dp_ctrl_link_train_1_2 [msm]] *ERROR* link
training #2 on phy 1 failed. ret=-110
[ 102.252859] [drm:msm_dp_ctrl_setup_main_link [msm]] *ERROR* link
training of LTTPR(s) failed. ret=-110
Once I did get it to connect on one of the ports, but then on unplug it
didn't detect the unplug properly and continued trying to use the link:
[ 1418.418954] disp_cc_mdss_dptx1_link_clk status stuck at 'off'
<trace cut>
[ 1418.420950] Failed to enable clk 'ctrl_link': -16
[ 1418.420959] [drm:msm_dp_ctrl_enable_mainlink_clocks [msm]] *ERROR*
Unable to start link clocks. ret=-16
[ 1418.421058] [drm:msm_dp_bridge_atomic_enable [msm]] *ERROR* Failed
link training (rc=-16)
<trace cut>
[ 1418.423228] Failed to enable clk 'ctrl_link': -16
[ 1418.423234] [drm:msm_dp_ctrl_enable_mainlink_clocks [msm]] *ERROR*
Unable to start link clocks. ret=-16
[ 1418.423325] [drm:msm_dp_ctrl_on_stream [msm]] *ERROR* Failed to start
link clocks. ret=-16
[ 1418.476234] [drm:dpu_encoder_phys_vid_wait_for_commit_done:543] [dpu
error]vblank timeout: 808208c0
[ 1418.476272] [drm:dpu_kms_wait_for_commit_done:527] [dpu error]wait
for commit done returned -110
[ 1418.509204] [drm:dpu_encoder_frame_done_timeout:2731] [dpu
error]enc37 frame done timeout
[ 1419.163337] [drm:dpu_encoder_phys_vid_wait_for_commit_done:543] [dpu
error]vblank timeout: 808208c0
[ 1419.163365] [drm:dpu_kms_wait_for_commit_done:527] [dpu error]wait
for commit done returned -110
But after reboot, link training was failing on both ports..
Thanks,
~val
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine
2026-03-15 0:51 ` [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine Val Packett
@ 2026-03-15 1:10 ` Val Packett
2026-03-16 3:23 ` Dmitry Baryshkov
0 siblings, 1 reply; 17+ messages in thread
From: Val Packett @ 2026-03-15 1:10 UTC (permalink / raw)
To: Dmitry Baryshkov, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, Kuogee Hsieh, Yongxing Mou
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel
On 3/14/26 9:51 PM, Val Packett wrote:
>
> On 3/13/26 10:09 PM, Dmitry Baryshkov wrote:
>> Currently, all HPD interrupt handling must go through the HPD state
>> machine.
>>
>> This has caused many issues where the DRM framework assumes that DP is
>> in one state while the state machine is stuck in another state.
>>
>> As discussed here [1], this series:
>>
>> - Removes the state machine
>> - Moves link training to atomic_enable()
>> - Changes the detect() behavior to return true if a display is
>> physically
>> plugged in (as opposed to if the DP link is ready).
>> - Remove event queue and move internal HPD handling to hpd_notify()
>>
>> To correctly detect the displays which are plugged on boot on the boards
>> which use dp-connector devices, this series depends on [2]. USB-C and
>> eDP panels are handled natively.
>>
>> [1]
>> https://patchwork.freedesktop.org/patch/656312/?series=142010&rev=2#comment_1201738
>> [2]
>> https://lore.kernel.org/all/20260314-dp-connector-hpd-v1-0-786044cedc17@oss.qualcomm.com/
>
> Unfortunately this currently seems to mostly break link training with
> USB-C, on x1e80100-dell-latitude-7455:
>
> [ 102.190083] [drm:msm_dp_ctrl_link_train_1_2 [msm]] *ERROR* link
> training #2 on phy 1 failed. ret=-110
> [ 102.192846] [drm:msm_dp_ctrl_setup_main_link [msm]] *ERROR* link
> training of LTTPR(s) failed. ret=-110
> [ 102.211095] [drm:msm_dp_bridge_atomic_enable [msm]] *ERROR* Failed
> link training (rc=-104)
> [ 102.211164] [drm:msm_dp_aux_isr [msm]] *ERROR* Unexpected DP AUX
> IRQ 0x01000000 when not busy
> [ 102.247168] [drm:msm_dp_ctrl_link_train_1_2 [msm]] *ERROR* link
> training #2 on phy 1 failed. ret=-110
> [ 102.252859] [drm:msm_dp_ctrl_setup_main_link [msm]] *ERROR* link
> training of LTTPR(s) failed. ret=-110
>
> [..]
Actually looks like that might've been due to having applied the [2]
dp-connector series from above.
Removed it and rebooted, now plugging and unplugging multiple times
between the 2 ports works fine.
Except unplug is still not reliable, the "ghost" monitor often remains
after unplugging.
Almost nothing is logged to dmesg, literally I've only seen this line once:
[drm:msm_dp_panel_read_sink_caps [msm]] *ERROR* panel edid read failed
But I have unplugged the monitor now and I still see:
crtc[108]: crtc-1
enable=1
active=1
self_refresh_active=0
planes_changed=1
mode_changed=0
active_changed=0
connectors_changed=0
color_mgmt_changed=0
plane_mask=2
connector_mask=2
encoder_mask=2
mode: "3840x2560": 60 631750 3840 3888 3920 4000 2560 2563 2573
2633 0x48 0x9
lm[0]=2
ctl[0]=1
lm[1]=3
ctl[1]=1
connector[38]: DP-2
crtc=crtc-1
[..]
and the compositor thinks it's still present, I can move the mouse to
where the screen was etc.
~val
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine
2026-03-15 1:10 ` Val Packett
@ 2026-03-16 3:23 ` Dmitry Baryshkov
2026-03-17 23:15 ` Val Packett
0 siblings, 1 reply; 17+ messages in thread
From: Dmitry Baryshkov @ 2026-03-16 3:23 UTC (permalink / raw)
To: Val Packett
Cc: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Kuogee Hsieh, Yongxing Mou, linux-arm-msm, dri-devel, freedreno,
linux-kernel
On Sat, Mar 14, 2026 at 10:10:26PM -0300, Val Packett wrote:
>
> On 3/14/26 9:51 PM, Val Packett wrote:
> >
> > On 3/13/26 10:09 PM, Dmitry Baryshkov wrote:
> > > Currently, all HPD interrupt handling must go through the HPD state
> > > machine.
> > >
> > > This has caused many issues where the DRM framework assumes that DP is
> > > in one state while the state machine is stuck in another state.
> > >
> > > As discussed here [1], this series:
> > >
> > > - Removes the state machine
> > > - Moves link training to atomic_enable()
> > > - Changes the detect() behavior to return true if a display is
> > > physically
> > > plugged in (as opposed to if the DP link is ready).
> > > - Remove event queue and move internal HPD handling to hpd_notify()
> > >
> > > To correctly detect the displays which are plugged on boot on the boards
> > > which use dp-connector devices, this series depends on [2]. USB-C and
> > > eDP panels are handled natively.
> > >
> > > [1] https://patchwork.freedesktop.org/patch/656312/?series=142010&rev=2#comment_1201738
> > > [2] https://lore.kernel.org/all/20260314-dp-connector-hpd-v1-0-786044cedc17@oss.qualcomm.com/
> >
> > Unfortunately this currently seems to mostly break link training with
> > USB-C, on x1e80100-dell-latitude-7455:
> >
> > [ 102.190083] [drm:msm_dp_ctrl_link_train_1_2 [msm]] *ERROR* link
> > training #2 on phy 1 failed. ret=-110
> > [ 102.192846] [drm:msm_dp_ctrl_setup_main_link [msm]] *ERROR* link
> > training of LTTPR(s) failed. ret=-110
> > [ 102.211095] [drm:msm_dp_bridge_atomic_enable [msm]] *ERROR* Failed
> > link training (rc=-104)
> > [ 102.211164] [drm:msm_dp_aux_isr [msm]] *ERROR* Unexpected DP AUX IRQ
> > 0x01000000 when not busy
> > [ 102.247168] [drm:msm_dp_ctrl_link_train_1_2 [msm]] *ERROR* link
> > training #2 on phy 1 failed. ret=-110
> > [ 102.252859] [drm:msm_dp_ctrl_setup_main_link [msm]] *ERROR* link
> > training of LTTPR(s) failed. ret=-110
> >
> > [..]
>
> Actually looks like that might've been due to having applied the [2]
> dp-connector series from above.
Interesting. The series only affects dp-connector. It can't affect
pmic-glink usecase.
>
> Removed it and rebooted, now plugging and unplugging multiple times between
> the 2 ports works fine.
>
> Except unplug is still not reliable, the "ghost" monitor often remains after
> unplugging.
Does the patch at [3] fix the issue?
[3] https://lore.kernel.org/linux-arm-msm/177362655076.7429.3868048981197120360.b4-ty@kernel.org/
>
> Almost nothing is logged to dmesg, literally I've only seen this line once:
> [drm:msm_dp_panel_read_sink_caps [msm]] *ERROR* panel edid read failed
You might want to use drm.debug=0x100 to get DP-related messages.
>
> But I have unplugged the monitor now and I still see:
>
> crtc[108]: crtc-1
> enable=1
> active=1
> self_refresh_active=0
> planes_changed=1
> mode_changed=0
> active_changed=0
> connectors_changed=0
> color_mgmt_changed=0
> plane_mask=2
> connector_mask=2
> encoder_mask=2
> mode: "3840x2560": 60 631750 3840 3888 3920 4000 2560 2563 2573 2633
> 0x48 0x9
> lm[0]=2
> ctl[0]=1
> lm[1]=3
> ctl[1]=1
> connector[38]: DP-2
> crtc=crtc-1
> [..]
>
> and the compositor thinks it's still present, I can move the mouse to where
> the screen was etc.
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine
2026-03-16 3:23 ` Dmitry Baryshkov
@ 2026-03-17 23:15 ` Val Packett
2026-03-18 1:03 ` Dmitry Baryshkov
0 siblings, 1 reply; 17+ messages in thread
From: Val Packett @ 2026-03-17 23:15 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Kuogee Hsieh, Yongxing Mou, linux-arm-msm, dri-devel, freedreno,
linux-kernel
On 3/16/26 12:23 AM, Dmitry Baryshkov wrote:
> On Sat, Mar 14, 2026 at 10:10:26PM -0300, Val Packett wrote:
>> On 3/14/26 9:51 PM, Val Packett wrote:
>>> On 3/13/26 10:09 PM, Dmitry Baryshkov wrote:
>>>> Currently, all HPD interrupt handling must go through the HPD state
>>>> machine.
>>>>
>>>> This has caused many issues where the DRM framework assumes that DP is
>>>> in one state while the state machine is stuck in another state.
>>>>
>>>> As discussed here [1], this series:
>>>>
>>>> - Removes the state machine
>>>> - Moves link training to atomic_enable()
>>>> - Changes the detect() behavior to return true if a display is
>>>> physically
>>>> plugged in (as opposed to if the DP link is ready).
>>>> - Remove event queue and move internal HPD handling to hpd_notify()
>>>>
>>>> To correctly detect the displays which are plugged on boot on the boards
>>>> which use dp-connector devices, this series depends on [2]. USB-C and
>>>> eDP panels are handled natively.
>>>>
>>>> [1] https://patchwork.freedesktop.org/patch/656312/?series=142010&rev=2#comment_1201738
>>>> [2] https://lore.kernel.org/all/20260314-dp-connector-hpd-v1-0-786044cedc17@oss.qualcomm.com/
>>> Unfortunately this currently seems to mostly break link training with
>>> USB-C, on x1e80100-dell-latitude-7455:
>>>
>>> [ 102.190083] [drm:msm_dp_ctrl_link_train_1_2 [msm]] *ERROR* link
>>> training #2 on phy 1 failed. ret=-110
>>> [ 102.192846] [drm:msm_dp_ctrl_setup_main_link [msm]] *ERROR* link
>>> training of LTTPR(s) failed. ret=-110
>>> [ 102.211095] [drm:msm_dp_bridge_atomic_enable [msm]] *ERROR* Failed
>>> link training (rc=-104)
>>> [ 102.211164] [drm:msm_dp_aux_isr [msm]] *ERROR* Unexpected DP AUX IRQ
>>> 0x01000000 when not busy
>>> [ 102.247168] [drm:msm_dp_ctrl_link_train_1_2 [msm]] *ERROR* link
>>> training #2 on phy 1 failed. ret=-110
>>> [ 102.252859] [drm:msm_dp_ctrl_setup_main_link [msm]] *ERROR* link
>>> training of LTTPR(s) failed. ret=-110
>>>
>>> [..]
>> Actually looks like that might've been due to having applied the [2]
>> dp-connector series from above.
> Interesting. The series only affects dp-connector. It can't affect
> pmic-glink usecase.
>
>> Removed it and rebooted, now plugging and unplugging multiple times between
>> the 2 ports works fine.
>>
>> Except unplug is still not reliable, the "ghost" monitor often remains after
>> unplugging.
> Does the patch at [3] fix the issue?
>
> [3] https://lore.kernel.org/linux-arm-msm/177362655076.7429.3868048981197120360.b4-ty@kernel.org/
Yes!
Overall works better than ever now, looks like I can unplug the cable
with the laptop closed and then open it and it's all fine, and even play
with dual-role / gadget mode USB and plug the alt-mode/dock cable back
in and it doesn't crash.
Still, rare link training failures can happen, e.g.:
>> Almost nothing is logged to dmesg, literally I've only seen this line once:
>> [drm:msm_dp_panel_read_sink_caps [msm]] *ERROR* panel edid read failed
> You might want to use drm.debug=0x100 to get DP-related messages.
[ 3357.388123] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_hpd_notify [msm]] type=10 link hpd_link_status=0x0,
status=2
[ 3357.388259] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_unplug_handle.isra.0 [msm]] Before, type=10 sink_count=1
[ 3357.388383] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_unplug_handle.isra.0 [msm]] After, type=10, sink_count=1
[ 3357.413042] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_init [msm]] type=10 core_init=1 phy_init=1
[ 3357.413115] [drm:msm_dp_bridge_detect [msm]] aux link status: 0
[ 3357.413147] [drm:msm_dp_bridge_detect [msm]] aux not connected
[ 3357.413179] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_hpd_notify [msm]] type=10 link hpd_link_status=0x0,
status=2
[ 3357.413208] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_unplug_handle.isra.0 [msm]] Before, type=10 sink_count=1
[ 3357.413251] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_init [msm]] type=10 core_init=1 phy_init=1
[ 3357.413282] [drm:msm_dp_bridge_detect [msm]] aux link status: 0
[ 3357.413309] [drm:msm_dp_bridge_detect [msm]] aux not connected
[ 3357.413340] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_hpd_notify [msm]] type=10 link hpd_link_status=0x0,
status=2
[ 3357.413367] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_unplug_handle.isra.0 [msm]] Before, type=10 sink_count=1
[ 3357.413400] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_init [msm]] type=10 core_init=1 phy_init=0
[ 3357.414554] [drm:msm_dp_ctrl_phy_init [msm]] phy=00000000fe5b208d
init=1 power_on=0
[ 3357.414587] [drm:msm_dp_bridge_detect [msm]] aux link status: 0
[ 3357.414614] [drm:msm_dp_bridge_detect [msm]] aux not connected
[ 3357.414641] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_exit [msm]] type=10 core_init=1 phy_init=1
[ 3357.415781] [drm:msm_dp_ctrl_phy_exit [msm]] phy=00000000fe5b208d
init=0 power_on=0
[ 3357.415812] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_hpd_notify [msm]] type=10 link hpd_link_status=0x0,
status=2
[ 3357.415840] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_unplug_handle.isra.0 [msm]] Before, type=10 sink_count=1
[ 3357.415871] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_init [msm]] type=10 core_init=1 phy_init=0
[ 3357.417034] [drm:msm_dp_ctrl_phy_init [msm]] phy=00000000fe5b208d
init=1 power_on=0
[ 3357.417065] [drm:msm_dp_bridge_detect [msm]] aux link status: 0
[ 3357.417091] [drm:msm_dp_bridge_detect [msm]] aux not connected
[ 3357.417118] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_exit [msm]] type=10 core_init=1 phy_init=1
[ 3357.418258] [drm:msm_dp_ctrl_phy_exit [msm]] phy=00000000fe5b208d
init=0 power_on=0
[ 3357.418290] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_hpd_notify [msm]] type=10 link hpd_link_status=0x0,
status=2
[ 3357.418318] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_unplug_handle.isra.0 [msm]] Before, type=10 sink_count=1
[ 3357.434909] [drm:msm_dp_ctrl_isr [msm]] idle_patterns_sent
[ 3357.435218] [drm:msm_dp_ctrl_push_idle [msm]] mainlink off
[ 3357.450864] [drm:msm_dp_panel_disable_vsc_sdp [msm]] vsc sdp enable=0
[ 3357.450971] [drm:msm_dp_ctrl_off [msm]] disable
[ 3357.452190] [drm:msm_dp_ctrl_link_clk_disable [msm]] disabled link clocks
[ 3357.452241] [drm:msm_dp_ctrl_link_clk_disable [msm]] stream_clks:off
link_clks:off core_clks:on
[ 3357.452300] [drm:msm_dp_ctrl_off [msm]] phy=00000000646c90e2 init=1
power_on=0
[ 3357.452354] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_exit [msm]] type=10 core_init=1 phy_init=1
[ 3357.453601] [drm:msm_dp_ctrl_phy_exit [msm]] phy=00000000646c90e2
init=0 power_on=0
[ 3357.453657] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_atomic_post_disable [msm]] sink count: 1
[ 3357.453689] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_atomic_post_disable [msm]] type=10 Done
[ 3361.476013] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_hpd_notify [msm]] type=10 link hpd_link_status=0x0,
status=2
[ 3361.476159] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_unplug_handle.isra.0 [msm]] Before, type=10 sink_count=1
[ 3361.486575] [drm:msm_dp_ctrl_phy_init [msm]] phy=00000000646c90e2
init=1 power_on=0
[ 3361.486649] [drm:msm_dp_bridge_detect [msm]] aux link status: 0
[ 3361.486710] [drm:msm_dp_bridge_detect [msm]] aux not connected
[ 3361.486770] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_exit [msm]] type=10 core_init=1 phy_init=1
[ 3361.487945] [drm:msm_dp_ctrl_phy_exit [msm]] phy=00000000646c90e2
init=0 power_on=0
[ 3361.488008] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_hpd_notify [msm]] type=10 link hpd_link_status=0x0,
status=2
[ 3361.488069] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_unplug_handle.isra.0 [msm]] Before, type=10 sink_count=1
[ 3361.488139] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_init [msm]] type=10 core_init=1 phy_init=0
[ 3361.489325] [drm:msm_dp_ctrl_phy_init [msm]] phy=00000000646c90e2
init=1 power_on=0
[ 3361.489387] [drm:msm_dp_bridge_detect [msm]] aux link status: 0
[ 3361.489445] [drm:msm_dp_bridge_detect [msm]] aux not connected
[ 3361.489504] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_exit [msm]] type=10 core_init=1 phy_init=1
[ 3361.490791] [drm:msm_dp_ctrl_phy_exit [msm]] phy=00000000646c90e2
init=0 power_on=0
[ 3361.490917] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_hpd_notify [msm]] type=10 link hpd_link_status=0x0,
status=2
[ 3361.490987] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_unplug_handle.isra.0 [msm]] Before, type=10 sink_count=1
[ 3361.491062] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_init [msm]] type=10 core_init=1 phy_init=0
[ 3361.492249] [drm:msm_dp_ctrl_phy_init [msm]] phy=00000000fe5b208d
init=1 power_on=0
[ 3361.492311] [drm:msm_dp_bridge_detect [msm]] aux link status: 0
[ 3361.492369] [drm:msm_dp_bridge_detect [msm]] aux not connected
[ 3361.492428] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_exit [msm]] type=10 core_init=1 phy_init=1
[ 3361.493560] [drm:msm_dp_ctrl_phy_exit [msm]] phy=00000000fe5b208d
init=0 power_on=0
[ 3361.493621] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_hpd_notify [msm]] type=10 link hpd_link_status=0x0,
status=2
[ 3361.493681] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_unplug_handle.isra.0 [msm]] Before, type=10 sink_count=1
[ 3361.493747] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_init [msm]] type=10 core_init=1 phy_init=0
[ 3361.494934] [drm:msm_dp_ctrl_phy_init [msm]] phy=00000000fe5b208d
init=1 power_on=0
[ 3361.494995] [drm:msm_dp_bridge_detect [msm]] aux link status: 0
[ 3361.495053] [drm:msm_dp_bridge_detect [msm]] aux not connected
[ 3361.495111] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_exit [msm]] type=10 core_init=1 phy_init=1
[ 3361.496282] [drm:msm_dp_ctrl_phy_exit [msm]] phy=00000000fe5b208d
init=0 power_on=0
[ 3361.496343] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_hpd_notify [msm]] type=10 link hpd_link_status=0x0,
status=2
[ 3361.496403] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_unplug_handle.isra.0 [msm]] Before, type=10 sink_count=1
[ 3361.992555] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_hpd_notify [msm]] type=10 link hpd_link_status=0x0,
status=2
[ 3361.992598] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_unplug_handle.isra.0 [msm]] Before, type=10 sink_count=1
[ 3361.992803] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_hpd_notify [msm]] type=10 link hpd_link_status=0x0,
status=1
[ 3361.992823] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_plug_handle.isra.0 [msm]] Before, type=10 sink_count=1
[ 3361.992841] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_init [msm]] type=10 core_init=1 phy_init=0
[ 3361.994079] [drm:msm_dp_ctrl_phy_init [msm]] phy=00000000fe5b208d
init=1 power_on=0
[ 3361.994688] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3361.995528] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00000 AUX -> (ret= 15) 12 14 c4 81
01 00 01 80 02 00 06 00 00 00 84
[ 3361.996132] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3361.996955] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x02200 AUX -> (ret= 15) 14 1e c4 81
01 00 01 80 02 00 06 00 00 00 84
[ 3361.997548] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.000160] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_init [msm]] type=10 core_init=1 phy_init=0
[ 3362.001067] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0000 AUX -> (ret= 8) 20 1e 80 55
04 00 01 07
[ 3362.001388] [drm:msm_dp_ctrl_phy_init [msm]] phy=00000000646c90e2
init=1 power_on=0
[ 3362.001491] [drm:msm_dp_bridge_detect [msm]] aux link status: 0
[ 3362.001595] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0003 AUX <-
(ret= 1) 55
[ 3362.001710] [drm:msm_dp_bridge_detect [msm]] aux not connected
[ 3362.001780] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_exit [msm]] type=10 core_init=1 phy_init=1
[ 3362.002103] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0003 AUX <-
(ret= 1) aa
[ 3362.002609] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.002963] [drm:msm_dp_ctrl_phy_exit [msm]] phy=00000000646c90e2
init=0 power_on=0
[ 3362.003029] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_hpd_notify [msm]] type=10 link hpd_link_status=0x0,
status=2
[ 3362.003089] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_unplug_handle.isra.0 [msm]] Before, type=10 sink_count=1
[ 3362.003161] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_init [msm]] type=10 core_init=1 phy_init=0
[ 3362.003357] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00000 AUX -> (ret= 15) 12 14 c4 81
01 00 01 80 02 00 06 00 00 00 84
[ 3362.003860] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.004344] [drm:msm_dp_ctrl_phy_init [msm]] phy=00000000646c90e2
init=1 power_on=0
[ 3362.004405] [drm:msm_dp_bridge_detect [msm]] aux link status: 0
[ 3362.004463] [drm:msm_dp_bridge_detect [msm]] aux not connected
[ 3362.004521] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_exit [msm]] type=10 core_init=1 phy_init=1
[ 3362.004646] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x02200 AUX -> (ret= 15) 14 1e c4 81
01 00 01 80 02 00 06 00 00 00 84
[ 3362.005149] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.005656] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x02210 AUX -> (ret= 1) 0a
[ 3362.005674] [drm:msm_dp_panel_read_sink_caps [msm]] max_lanes=4
max_link_rate=810000
[ 3362.005929] [drm:msm_dp_panel_read_sink_caps [msm]] version: 1.4
[ 3362.005915] [drm:msm_dp_ctrl_phy_exit [msm]] phy=00000000646c90e2
init=0 power_on=0
[ 3362.005982] [drm:msm_dp_panel_read_sink_caps [msm]] link_rate=810000
[ 3362.006035] [drm:msm_dp_panel_read_sink_caps [msm]] link_rate_set=0
[ 3362.006033] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_hpd_notify [msm]] type=10 link hpd_link_status=0x0,
status=2
[ 3362.006094] [drm:msm_dp_panel_read_sink_caps [msm]] use_rate_set=0
[ 3362.006105] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_unplug_handle.isra.0 [msm]] Before, type=10 sink_count=1
[ 3362.006290] [drm:msm_dp_panel_read_sink_caps [msm]] lane_count=4
[ 3362.184415] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.187917] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00200 AUX -> (ret= 1) 41
[ 3362.188478] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.191955] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00202 AUX -> (ret= 6) 00 00 80 00 00 00
[ 3362.192515] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.195938] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00201 AUX -> (ret= 1) 00
[ 3362.195989] [drm:msm_dp_link_process_request [msm]] device service
irq vector = 0x0
[ 3362.196104] [drm:msm_dp_link_process_request [msm]] no test requested
[ 3362.196167] [drm:msm_dp_link_process_request [msm]] no phy test
[ 3362.196792] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.197346] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x02006 AUX -> (ret= 1) 00
[ 3362.198130] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.198764] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x02007 AUX -> (ret= 1) 00
[ 3362.198786] [drm:msm_dp_link_process_request [msm]] channel_eq_done =
0, clock_recovery_done = 0
[ 3362.198900] [drm:msm_dp_link_process_request [msm]] sink request=0x80
[ 3362.199479] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.202837] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00600 AUX -> (ret= 1) 01
[ 3362.203442] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0x00600 AUX <-
(ret= 1) 01
[ 3362.205529] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_plug_handle.isra.0 [msm]] After, type=10 sink_count=1
[ 3362.205773] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_init [msm]] type=10 core_init=1 phy_init=1
[ 3362.205899] [drm:msm_dp_bridge_detect [msm]] aux link status: 0
[ 3362.206484] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.207282] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00000 AUX -> (ret= 15) 12 14 c4 81
01 00 01 80 02 00 06 00 00 00 84
[ 3362.207879] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.208760] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x02200 AUX -> (ret= 15) 14 1e c4 81
01 00 01 80 02 00 06 00 00 00 84
[ 3362.209308] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.213021] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00400 AUX -> (ret= 12) 00 e0 4c 44
70 31 2e 34 00 20 03 00
[ 3362.213084] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_hpd_notify [msm]] type=10 link hpd_link_status=0x0,
status=1
[ 3362.213202] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_plug_handle.isra.0 [msm]] Before, type=10 sink_count=1
[ 3362.213270] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_init [msm]] type=10 core_init=1 phy_init=1
[ 3362.214083] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.214987] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00000 AUX -> (ret= 15) 12 14 c4 81
01 00 01 80 02 00 06 00 00 00 84
[ 3362.215598] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.216480] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x02200 AUX -> (ret= 15) 14 1e c4 81
01 00 01 80 02 00 06 00 00 00 84
[ 3362.217346] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.218261] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0000 AUX -> (ret= 8) 20 1e 80 aa
04 00 01 07
[ 3362.219080] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0003 AUX <-
(ret= 1) 55
[ 3362.219802] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0003 AUX <-
(ret= 1) aa
[ 3362.220413] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.221259] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00000 AUX -> (ret= 15) 12 14 c4 81
01 00 01 80 02 00 06 00 00 00 84
[ 3362.221959] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.222911] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x02200 AUX -> (ret= 15) 14 1e c4 81
01 00 01 80 02 00 06 00 00 00 84
[ 3362.223519] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.226930] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x02210 AUX -> (ret= 1) 0a
[ 3362.226982] [drm:msm_dp_panel_read_sink_caps [msm]] max_lanes=4
max_link_rate=810000
[ 3362.227098] [drm:msm_dp_panel_read_sink_caps [msm]] version: 1.4
[ 3362.227161] [drm:msm_dp_panel_read_sink_caps [msm]] link_rate=810000
[ 3362.227220] [drm:msm_dp_panel_read_sink_caps [msm]] link_rate_set=0
[ 3362.227278] [drm:msm_dp_panel_read_sink_caps [msm]] use_rate_set=0
[ 3362.227335] [drm:msm_dp_panel_read_sink_caps [msm]] lane_count=4
[ 3362.364434] sysfs: cannot create duplicate filename
'/devices/platform/pmic-glink/pmic_glink.ucsi.0/typec/port1/port1.0/partner'
[ 3362.364458] CPU: 7 UID: 0 PID: 8343 Comm: kworker/u48:1 Tainted: G
W 7.0.0-rc4-next-20260316-00127-g71918c60b326-dirty #66 PREEMPT(full)
[ 3362.364470] Tainted: [W]=WARN
[ 3362.364472] Hardware name: Dell Inc. Latitude 7455/0FK7MX, BIOS
2.13.0 09/19/2025
[ 3362.364477] Workqueue: pmic_glink.ucsi.0-con2 ucsi_poll_worker
[typec_ucsi]
[ 3362.364505] Call trace:
[ 3362.364509] show_stack+0x20/0x38 (C)
[ 3362.364524] dump_stack_lvl+0x60/0x80
[ 3362.364534] dump_stack+0x18/0x28
[ 3362.364542] sysfs_warn_dup+0x6c/0x90
[ 3362.364550] sysfs_do_create_link_sd+0xf8/0x108
[ 3362.364556] sysfs_create_link+0x28/0x50
[ 3362.364561] typec_probe+0x98/0x120 [typec]
[ 3362.364587] really_probe+0xc8/0x3f0
[ 3362.364598] __driver_probe_device+0x88/0x170
[ 3362.364607] driver_probe_device+0x48/0x130
[ 3362.364615] __device_attach_driver+0xc4/0x190
[ 3362.364624] bus_for_each_drv+0x90/0x100
[ 3362.364632] __device_attach+0xa4/0x1e0
[ 3362.364640] device_initial_probe+0x5c/0x78
[ 3362.364649] bus_probe_device+0x3c/0xa8
[ 3362.364656] device_add+0x61c/0x880
[ 3362.364665] device_register+0x24/0x40
[ 3362.364671] typec_register_altmode+0x1fc/0x300 [typec]
[ 3362.364687] typec_partner_register_altmode+0x24/0x40 [typec]
[ 3362.364702] ucsi_register_altmode.constprop.0+0x234/0x420 [typec_ucsi]
[ 3362.364713] ucsi_register_altmodes+0x13c/0x200 [typec_ucsi]
[ 3362.364721] ucsi_check_altmodes+0x24/0x100 [typec_ucsi]
[ 3362.364730] ucsi_poll_worker+0x3c/0x100 [typec_ucsi]
[ 3362.364738] process_one_work+0x174/0x540
[ 3362.364750] worker_thread+0x1a8/0x320
[ 3362.364760] kthread+0x140/0x158
[ 3362.364768] ret_from_fork+0x10/0x20
[ 3362.364893] typec_displayport port1-partner.1: failed to create symlinks
[ 3362.364902] typec_displayport port1-partner.1: probe with driver
typec_displayport failed with error -17
[ 3362.375605] sysfs: cannot create duplicate filename
'/devices/platform/pmic-glink/pmic_glink.ucsi.0/typec/port1/port1.0/partner'
[ 3362.375630] CPU: 7 UID: 0 PID: 8343 Comm: kworker/u48:1 Tainted: G
W 7.0.0-rc4-next-20260316-00127-g71918c60b326-dirty #66 PREEMPT(full)
[ 3362.375641] Tainted: [W]=WARN
[ 3362.375644] Hardware name: Dell Inc. Latitude 7455/0FK7MX, BIOS
2.13.0 09/19/2025
[ 3362.375649] Workqueue: pmic_glink.ucsi.0-con2 ucsi_poll_worker
[typec_ucsi]
[ 3362.375676] Call trace: <cut, same as before>
[ 3362.375971] typec_displayport port1-partner.2: failed to create symlinks
[ 3362.376030] typec_displayport port1-partner.2: probe with driver
typec_displayport failed with error -17
[ 3362.376669] sysfs: cannot create duplicate filename
'/devices/platform/pmic-glink/pmic_glink.ucsi.0/typec/port1/port1.0/partner'
[ 3362.376678] CPU: 7 UID: 0 PID: 8343 Comm: kworker/u48:1 Tainted: G
W 7.0.0-rc4-next-20260316-00127-g71918c60b326-dirty #66 PREEMPT(full)
[ 3362.376685] Tainted: [W]=WARN
[ 3362.376688] Hardware name: Dell Inc. Latitude 7455/0FK7MX, BIOS
2.13.0 09/19/2025
[ 3362.376691] Workqueue: pmic_glink.ucsi.0-con2 ucsi_poll_worker
[typec_ucsi]
[ 3362.375676] Call trace: <cut, same as before>
[ 3362.377006] typec_displayport port1-partner.3: failed to create symlinks
[ 3362.377063] typec_displayport port1-partner.3: probe with driver
typec_displayport failed with error -17
[ 3362.378069] sysfs: cannot create duplicate filename
'/devices/platform/pmic-glink/pmic_glink.ucsi.0/typec/port1/port1.0/partner'
[ 3362.378077] CPU: 7 UID: 0 PID: 8343 Comm: kworker/u48:1 Tainted: G
W 7.0.0-rc4-next-20260316-00127-g71918c60b326-dirty #66 PREEMPT(full)
[ 3362.378083] Tainted: [W]=WARN
[ 3362.378085] Hardware name: Dell Inc. Latitude 7455/0FK7MX, BIOS
2.13.0 09/19/2025
[ 3362.378089] Workqueue: pmic_glink.ucsi.0-con2 ucsi_poll_worker
[typec_ucsi]
[ 3362.375676] Call trace: <cut, same as before>
[ 3362.378341] typec_displayport port1-partner.4: failed to create symlinks
[ 3362.378398] typec_displayport port1-partner.4: probe with driver
typec_displayport failed with error -17
[ 3362.379173] sysfs: cannot create duplicate filename
'/devices/platform/pmic-glink/pmic_glink.ucsi.0/typec/port1/port1.0/partner'
[ 3362.379187] CPU: 5 UID: 0 PID: 8343 Comm: kworker/u48:1 Tainted: G
W 7.0.0-rc4-next-20260316-00127-g71918c60b326-dirty #66 PREEMPT(full)
[ 3362.379197] Tainted: [W]=WARN
[ 3362.379200] Hardware name: Dell Inc. Latitude 7455/0FK7MX, BIOS
2.13.0 09/19/2025
[ 3362.379204] Workqueue: pmic_glink.ucsi.0-con2 ucsi_poll_worker
[typec_ucsi]
[ 3362.375676] Call trace: <cut, same as before>
[ 3362.379507] typec_displayport port1-partner.5: failed to create symlinks
[ 3362.379589] typec_displayport port1-partner.5: probe with driver
typec_displayport failed with error -17
[ 3362.381535] sysfs: cannot create duplicate filename
'/devices/platform/pmic-glink/pmic_glink.ucsi.0/typec/port1/port1.0/partner'
[ 3362.381548] CPU: 4 UID: 0 PID: 8343 Comm: kworker/u48:1 Tainted: G
W 7.0.0-rc4-next-20260316-00127-g71918c60b326-dirty #66 PREEMPT(full)
[ 3362.381559] Tainted: [W]=WARN
[ 3362.381561] Hardware name: Dell Inc. Latitude 7455/0FK7MX, BIOS
2.13.0 09/19/2025
[ 3362.381565] Workqueue: pmic_glink.ucsi.0-con2 ucsi_poll_worker
[typec_ucsi]
[ 3362.375676] Call trace: <cut, same as before>
[ 3362.381920] typec_displayport port1-partner.6: failed to create symlinks
[ 3362.381927] typec_displayport port1-partner.6: probe with driver
typec_displayport failed with error -17
[ 3362.383333] sysfs: cannot create duplicate filename
'/devices/platform/pmic-glink/pmic_glink.ucsi.0/typec/port1/port1.0/partner'
[ 3362.383348] CPU: 5 UID: 0 PID: 8343 Comm: kworker/u48:1 Tainted: G
W 7.0.0-rc4-next-20260316-00127-g71918c60b326-dirty #66 PREEMPT(full)
[ 3362.383358] Tainted: [W]=WARN
[ 3362.383361] Hardware name: Dell Inc. Latitude 7455/0FK7MX, BIOS
2.13.0 09/19/2025
[ 3362.383365] Workqueue: pmic_glink.ucsi.0-con2 ucsi_poll_worker
[typec_ucsi]
[ 3362.375676] Call trace: <cut, same as before>
[ 3362.383722] typec_displayport port1-partner.7: failed to create symlinks
[ 3362.383730] typec_displayport port1-partner.7: probe with driver
typec_displayport failed with error -17
[ 3362.384590] ucsi_glink.pmic_glink_ucsi pmic_glink.ucsi.0: con2:
failed to register partner alt modes (-34)
[ 3362.516835] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.517434] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00200 AUX -> (ret= 1) 41
[ 3362.520983] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.521724] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00202 AUX -> (ret= 6) 00 00 00 00 00 00
[ 3362.522372] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.525930] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00201 AUX -> (ret= 1) 00
[ 3362.525982] [drm:msm_dp_link_process_request [msm]] device service
irq vector = 0x0
[ 3362.526097] [drm:msm_dp_link_process_request [msm]] no test requested
[ 3362.526162] [drm:msm_dp_link_process_request [msm]] no phy test
[ 3362.527011] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.527666] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x02006 AUX -> (ret= 1) 00
[ 3362.528307] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.529169] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x02007 AUX -> (ret= 1) 00
[ 3362.529221] [drm:msm_dp_link_process_request [msm]] channel_eq_done =
0, clock_recovery_done = 0
[ 3362.529336] [drm:msm_dp_link_process_request [msm]] sink request=0x80
[ 3362.530205] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.531083] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00600 AUX -> (ret= 1) 01
[ 3362.531727] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0x00600 AUX <-
(ret= 1) 01
[ 3362.533630] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_plug_handle.isra.0 [msm]] After, type=10 sink_count=1
[ 3362.534076] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_get_modes [msm]] No sink connected
[ 3362.538898] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_init [msm]] type=10 core_init=1 phy_init=0
[ 3362.540170] [drm:msm_dp_ctrl_phy_init [msm]] phy=00000000646c90e2
init=1 power_on=0
[ 3362.540253] [drm:msm_dp_bridge_detect [msm]] aux link status: 0
[ 3362.540321] [drm:msm_dp_bridge_detect [msm]] aux not connected
[ 3362.540388] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_exit [msm]] type=10 core_init=1 phy_init=1
[ 3362.541639] [drm:msm_dp_ctrl_phy_exit [msm]] phy=00000000646c90e2
init=0 power_on=0
[ 3362.541767] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_hpd_notify [msm]] type=10 link hpd_link_status=0x0,
status=2
[ 3362.541837] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_unplug_handle.isra.0 [msm]] Before, type=10 sink_count=1
[ 3362.541912] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_init [msm]] type=10 core_init=1 phy_init=0
[ 3362.543117] [drm:msm_dp_ctrl_phy_init [msm]] phy=00000000646c90e2
init=1 power_on=0
[ 3362.543180] [drm:msm_dp_bridge_detect [msm]] aux link status: 0
[ 3362.543239] [drm:msm_dp_bridge_detect [msm]] aux not connected
[ 3362.543298] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_exit [msm]] type=10 core_init=1 phy_init=1
[ 3362.544959] [drm:msm_dp_ctrl_phy_exit [msm]] phy=00000000646c90e2
init=0 power_on=0
[ 3362.545086] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_hpd_notify [msm]] type=10 link hpd_link_status=0x0,
status=2
[ 3362.545155] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_unplug_handle.isra.0 [msm]] Before, type=10 sink_count=1
[ 3362.545233] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_init [msm]] type=10 core_init=1 phy_init=1
[ 3362.545296] [drm:msm_dp_bridge_detect [msm]] aux link status: 0
[ 3362.545889] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.546706] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00000 AUX -> (ret= 15) 12 14 c4 81
01 00 01 80 02 00 06 00 00 00 84
[ 3362.547212] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.547974] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x02200 AUX -> (ret= 15) 14 1e c4 81
01 00 01 80 02 00 06 00 00 00 84
[ 3362.548485] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.549187] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00400 AUX -> (ret= 12) 00 e0 4c 44
70 31 2e 34 00 20 03 00
[ 3362.549196] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_hpd_notify [msm]] type=10 link hpd_link_status=0x0,
status=1
[ 3362.549229] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_plug_handle.isra.0 [msm]] Before, type=10 sink_count=1
[ 3362.549248] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_init [msm]] type=10 core_init=1 phy_init=1
[ 3362.549767] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.550522] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00000 AUX -> (ret= 15) 12 14 c4 81
01 00 01 80 02 00 06 00 00 00 84
[ 3362.551028] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.551783] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x02200 AUX -> (ret= 15) 14 1e c4 81
01 00 01 80 02 00 06 00 00 00 84
[ 3362.552289] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.552929] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0000 AUX -> (ret= 8) 20 1e 80 aa
04 00 01 07
[ 3362.553432] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0003 AUX <-
(ret= 1) 55
[ 3362.553936] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0003 AUX <-
(ret= 1) aa
[ 3362.554440] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.555211] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00000 AUX -> (ret= 15) 12 14 c4 81
01 00 01 80 02 00 06 00 00 00 84
[ 3362.555719] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.556475] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x02200 AUX -> (ret= 15) 14 1e c4 81
01 00 01 80 02 00 06 00 00 00 84
[ 3362.556982] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.557489] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x02210 AUX -> (ret= 1) 0a
[ 3362.557496] [drm:msm_dp_panel_read_sink_caps [msm]] max_lanes=4
max_link_rate=810000
[ 3362.557516] [drm:msm_dp_panel_read_sink_caps [msm]] version: 1.4
[ 3362.557533] [drm:msm_dp_panel_read_sink_caps [msm]] link_rate=810000
[ 3362.557550] [drm:msm_dp_panel_read_sink_caps [msm]] link_rate_set=0
[ 3362.557572] [drm:msm_dp_panel_read_sink_caps [msm]] use_rate_set=0
[ 3362.557589] [drm:msm_dp_panel_read_sink_caps [msm]] lane_count=4
[ 3362.735545] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.736142] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00200 AUX -> (ret= 1) 41
[ 3362.736705] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.737305] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00202 AUX -> (ret= 6) 00 00 00 00 00 00
[ 3362.737847] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.738357] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00201 AUX -> (ret= 1) 00
[ 3362.738364] [drm:msm_dp_link_process_request [msm]] device service
irq vector = 0x0
[ 3362.738401] [drm:msm_dp_link_process_request [msm]] no test requested
[ 3362.738420] [drm:msm_dp_link_process_request [msm]] no phy test
[ 3362.739147] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.739710] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x02006 AUX -> (ret= 1) 00
[ 3362.740220] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.740926] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x02007 AUX -> (ret= 1) 00
[ 3362.740955] [drm:msm_dp_link_process_request [msm]] channel_eq_done =
0, clock_recovery_done = 0
[ 3362.740993] [drm:msm_dp_link_process_request [msm]] sink request=0x80
[ 3362.741526] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.742240] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0x00600 AUX -> (ret= 1) 01
[ 3362.742802] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0x00600 AUX <-
(ret= 1) 01
[ 3362.744562] msm_dpu ae01000.display-controller:
[drm:msm_dp_hpd_plug_handle.isra.0 [msm]] After, type=10 sink_count=1
[ 3362.744737] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_get_modes [msm]] No sink connected
[ 3362.793900] [drm:msm_dp_panel_init_panel_info [msm]] SET NEW RESOLUTION:
[ 3362.794035] [drm:msm_dp_panel_init_panel_info [msm]] 3840x2560@60fps
[ 3362.794103] [drm:msm_dp_panel_init_panel_info [msm]]
h_porches(back|front|width) = (80|48|32)
[ 3362.794163] [drm:msm_dp_panel_init_panel_info [msm]]
v_porches(back|front|width) = (60|3|10)
[ 3362.794223] [drm:msm_dp_panel_init_panel_info [msm]] pixel clock
(KHz)=(631750)
[ 3362.794281] [drm:msm_dp_panel_init_panel_info [msm]] bpp = 30
[ 3362.794339] [drm:msm_dp_panel_init_panel_info [msm]] updated bpp = 30
[ 3362.794401] msm_dpu ae01000.display-controller:
[drm:msm_dp_display_host_phy_init [msm]] type=10 core_init=1 phy_init=1
[ 3362.794464] [drm:msm_dp_ctrl_core_clk_enable [msm]] core clks already
enabled
[ 3362.794523] [drm:msm_dp_ctrl_on_link [msm]] rate=810000, num_lanes=4,
pixel_rate=631750
[ 3362.798148] [drm:msm_dp_ctrl_enable_mainlink_clocks [msm]] enable
link clocks
[ 3362.798207] [drm:msm_dp_ctrl_enable_mainlink_clocks [msm]]
stream_clks:off link_clks:on core_clks:on
[ 3362.798266] [drm:msm_dp_ctrl_enable_mainlink_clocks [msm]] link
rate=810000
[ 3362.798326] [drm:msm_dp_ctrl_setup_main_link [msm]] enable
[ 3362.798396] [drm:msm_dp_ctrl_config_ctrl [msm]]
DP_CONFIGURATION_CTRL=0x4277
[ 3362.801890] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0x00101 AUX <-
(ret= 1) 84
[ 3362.801943] [drm:msm_dp_ctrl_setup_main_link [msm]] using
LINK_BW_SET: 0x1e
[ 3362.802738] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0x00100 AUX <-
(ret= 1) 1e
[ 3362.803338] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0x00107 AUX <-
(ret= 2) 10 01
[ 3362.803374] [drm:msm_dp_ctrl_set_pattern_state_bit [msm]] hw: bit=1
train=1
[ 3362.803495] [drm:msm_dp_ctrl_train_pattern_set.isra.0 [msm]] sink:
pattern=21
[ 3362.804149] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0010 AUX <-
(ret= 1) 21
[ 3362.804185] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] voltage level: 0
emphasis level: 0
[ 3362.804316] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] sink: p|v=0x0
[ 3362.808024] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0011 AUX <-
(ret= 4) 00 00 00 00
[ 3362.808948] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.814044] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0030 AUX -> (ret= 5) 51 51 80 cc cc
[ 3362.814111] [drm:msm_dp_ctrl_link_train_1_2 [msm]] link training #1
on phy 1 successful
[ 3362.818952] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.819651] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0020 AUX -> (ret= 1) 00
[ 3362.819681] [drm:msm_dp_ctrl_set_pattern_state_bit [msm]] hw: bit=8
train=4
[ 3362.819852] [drm:msm_dp_ctrl_train_pattern_set.isra.0 [msm]] sink:
pattern=7
[ 3362.820550] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0010 AUX <-
(ret= 1) 07
[ 3362.825989] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.826718] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0030 AUX -> (ret= 5) 44 00 80 88 88
[ 3362.826749] [drm:msm_dp_link_adjust_levels [msm]] lane=0
req_vol_swing=0 req_pre_emphasis=16
[ 3362.826910] [drm:msm_dp_link_adjust_levels [msm]] lane=1
req_vol_swing=0 req_pre_emphasis=16
[ 3362.827003] [drm:msm_dp_link_adjust_levels [msm]] lane=2
req_vol_swing=0 req_pre_emphasis=16
[ 3362.827087] [drm:msm_dp_link_adjust_levels [msm]] lane=3
req_vol_swing=0 req_pre_emphasis=16
[ 3362.827170] [drm:msm_dp_link_adjust_levels [msm]] adjusted:
v_level=0, p_level=2
[ 3362.827253] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] voltage level: 0
emphasis level: 2
[ 3362.827357] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] sink: p|v=0x10
[ 3362.828263] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0011 AUX <-
(ret= 4) 10 10 10 10
[ 3362.829446] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.830219] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0030 AUX -> (ret= 5) 44 00 00 cc cc
[ 3362.830269] [drm:msm_dp_link_adjust_levels [msm]] lane=0
req_vol_swing=0 req_pre_emphasis=24
[ 3362.830428] [drm:msm_dp_link_adjust_levels [msm]] lane=1
req_vol_swing=0 req_pre_emphasis=24
[ 3362.830519] [drm:msm_dp_link_adjust_levels [msm]] lane=2
req_vol_swing=0 req_pre_emphasis=24
[ 3362.830627] [drm:msm_dp_link_adjust_levels [msm]] lane=3
req_vol_swing=0 req_pre_emphasis=24
[ 3362.830709] [drm:msm_dp_link_adjust_levels [msm]] adjusted:
v_level=0, p_level=3
[ 3362.830791] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] voltage level: 0
emphasis level: 3
[ 3362.830893] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] max.
pre-emphasis level reached 3
[ 3362.830975] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] sink: p|v=0x18
[ 3362.831727] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0011 AUX <-
(ret= 4) 38 38 38 38
[ 3362.835630] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.840955] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0030 AUX -> (ret= 5) 44 00 00 cc cc
[ 3362.841024] [drm:msm_dp_link_adjust_levels [msm]] lane=0
req_vol_swing=0 req_pre_emphasis=24
[ 3362.841187] [drm:msm_dp_link_adjust_levels [msm]] lane=1
req_vol_swing=0 req_pre_emphasis=24
[ 3362.841279] [drm:msm_dp_link_adjust_levels [msm]] lane=2
req_vol_swing=0 req_pre_emphasis=24
[ 3362.841363] [drm:msm_dp_link_adjust_levels [msm]] lane=3
req_vol_swing=0 req_pre_emphasis=24
[ 3362.841445] [drm:msm_dp_link_adjust_levels [msm]] adjusted:
v_level=0, p_level=3
[ 3362.841528] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] voltage level: 0
emphasis level: 3
[ 3362.841686] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] max.
pre-emphasis level reached 3
[ 3362.841769] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] sink: p|v=0x18
[ 3362.842745] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0011 AUX <-
(ret= 4) 38 38 38 38
[ 3362.844085] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.844983] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0030 AUX -> (ret= 5) 44 00 00 cc cc
[ 3362.845034] [drm:msm_dp_link_adjust_levels [msm]] lane=0
req_vol_swing=0 req_pre_emphasis=24
[ 3362.845193] [drm:msm_dp_link_adjust_levels [msm]] lane=1
req_vol_swing=0 req_pre_emphasis=24
[ 3362.845283] [drm:msm_dp_link_adjust_levels [msm]] lane=2
req_vol_swing=0 req_pre_emphasis=24
[ 3362.845366] [drm:msm_dp_link_adjust_levels [msm]] lane=3
req_vol_swing=0 req_pre_emphasis=24
[ 3362.845448] [drm:msm_dp_link_adjust_levels [msm]] adjusted:
v_level=0, p_level=3
[ 3362.845530] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] voltage level: 0
emphasis level: 3
[ 3362.845650] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] max.
pre-emphasis level reached 3
[ 3362.845731] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] sink: p|v=0x18
[ 3362.846654] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0011 AUX <-
(ret= 4) 38 38 38 38
[ 3362.848029] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.848710] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0030 AUX -> (ret= 5) 44 00 00 cc cc
[ 3362.848742] [drm:msm_dp_link_adjust_levels [msm]] lane=0
req_vol_swing=0 req_pre_emphasis=24
[ 3362.848901] [drm:msm_dp_link_adjust_levels [msm]] lane=1
req_vol_swing=0 req_pre_emphasis=24
[ 3362.848992] [drm:msm_dp_link_adjust_levels [msm]] lane=2
req_vol_swing=0 req_pre_emphasis=24
[ 3362.849075] [drm:msm_dp_link_adjust_levels [msm]] lane=3
req_vol_swing=0 req_pre_emphasis=24
[ 3362.849157] [drm:msm_dp_link_adjust_levels [msm]] adjusted:
v_level=0, p_level=3
[ 3362.849239] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] voltage level: 0
emphasis level: 3
[ 3362.849340] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] max.
pre-emphasis level reached 3
[ 3362.849422] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] sink: p|v=0x18
[ 3362.854846] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0011 AUX <-
(ret= 4) 38 38 38 38
[ 3362.856226] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.861388] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0030 AUX -> (ret= 5) 44 00 00 cc cc
[ 3362.861456] [drm:msm_dp_link_adjust_levels [msm]] lane=0
req_vol_swing=0 req_pre_emphasis=24
[ 3362.861677] [drm:msm_dp_link_adjust_levels [msm]] lane=1
req_vol_swing=0 req_pre_emphasis=24
[ 3362.861769] [drm:msm_dp_link_adjust_levels [msm]] lane=2
req_vol_swing=0 req_pre_emphasis=24
[ 3362.861854] [drm:msm_dp_link_adjust_levels [msm]] lane=3
req_vol_swing=0 req_pre_emphasis=24
[ 3362.861937] [drm:msm_dp_link_adjust_levels [msm]] adjusted:
v_level=0, p_level=3
[ 3362.862020] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] voltage level: 0
emphasis level: 3
[ 3362.862123] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] max.
pre-emphasis level reached 3
[ 3362.862205] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] sink: p|v=0x18
[ 3362.866462] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0011 AUX <-
(ret= 4) 38 38 38 38
[ 3362.866528] [drm:msm_dp_ctrl_link_train_1_2 [msm]] *ERROR* link
training #2 on phy 1 failed. ret=-110
[ 3362.866760] [drm:msm_dp_ctrl_train_pattern_set.isra.0 [msm]] sink:
pattern=0
[ 3362.871130] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0010 AUX <-
(ret= 1) 00
[ 3362.871970] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.872606] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0020 AUX -> (ret= 1) 00
[ 3362.873148] [drm:msm_dp_ctrl_setup_main_link [msm]] *ERROR* link
training of LTTPR(s) failed. ret=-110
[ 3362.873322] [drm:msm_dp_ctrl_train_pattern_set.isra.0 [msm]] sink:
pattern=0
[ 3362.874047] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0x00102 AUX <-
(ret= 1) 00
[ 3362.892535] [drm:msm_dp_ctrl_on_link [msm]] disable
[ 3362.893940] [drm:msm_dp_ctrl_link_clk_disable [msm]] disabled link clocks
[ 3362.894108] [drm:msm_dp_ctrl_link_clk_disable [msm]] stream_clks:off
link_clks:off core_clks:on
[ 3362.894236] [drm:msm_dp_ctrl_on_link [msm]] phy=00000000fe5b208d
init=1 power_on=0
[ 3362.894325] [drm:msm_dp_bridge_atomic_enable [msm]] *ERROR* Failed
link training (rc=-104)
[ 3362.894423] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_atomic_enable [msm]] sink_count=1
[ 3362.894509] [drm:msm_dp_ctrl_on_stream [msm]] rate=810000,
num_lanes=4, pixel_rate=315875
[ 3362.894614] [drm:msm_dp_ctrl_on_stream [msm]] core_clk_on=1
link_clk_on=0 stream_clk_on=0
[ 3362.894660] [drm:msm_dp_aux_isr [msm]] *ERROR* Unexpected DP AUX IRQ
0x01000000 when not busy
[ 3362.898143] [drm:msm_dp_ctrl_enable_mainlink_clocks [msm]] enable
link clocks
[ 3362.898226] [drm:msm_dp_ctrl_enable_mainlink_clocks [msm]]
stream_clks:off link_clks:on core_clks:on
[ 3362.898308] [drm:msm_dp_ctrl_enable_mainlink_clocks [msm]] link
rate=810000
[ 3362.898404] [drm:msm_dp_ctrl_setup_main_link [msm]] enable
[ 3362.898496] [drm:msm_dp_ctrl_config_ctrl [msm]]
DP_CONFIGURATION_CTRL=0x4277
[ 3362.903345] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0x00101 AUX <-
(ret= 1) 84
[ 3362.903410] [drm:msm_dp_ctrl_setup_main_link [msm]] using
LINK_BW_SET: 0x1e
[ 3362.907853] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0x00100 AUX <-
(ret= 1) 1e
[ 3362.908716] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0x00107 AUX <-
(ret= 2) 10 01
[ 3362.908746] [drm:msm_dp_ctrl_set_pattern_state_bit [msm]] hw: bit=1
train=1
[ 3362.908915] [drm:msm_dp_ctrl_train_pattern_set.isra.0 [msm]] sink:
pattern=21
[ 3362.909789] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0010 AUX <-
(ret= 1) 21
[ 3362.909839] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] voltage level: 0
emphasis level: 0
[ 3362.910017] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] sink: p|v=0x0
[ 3362.910931] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0011 AUX <-
(ret= 4) 00 00 00 00
[ 3362.911852] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.912490] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0030 AUX -> (ret= 5) 55 11 80 00 00
[ 3362.912520] [drm:msm_dp_ctrl_link_train_1_2 [msm]] link training #1
on phy 1 successful
[ 3362.913296] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.913935] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0020 AUX -> (ret= 1) 00
[ 3362.913986] [drm:msm_dp_ctrl_set_pattern_state_bit [msm]] hw: bit=8
train=4
[ 3362.914153] [drm:msm_dp_ctrl_train_pattern_set.isra.0 [msm]] sink:
pattern=7
[ 3362.919517] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0010 AUX <-
(ret= 1) 07
[ 3362.922815] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.923667] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0030 AUX -> (ret= 5) 44 00 80 88 88
[ 3362.923698] [drm:msm_dp_link_adjust_levels [msm]] lane=0
req_vol_swing=0 req_pre_emphasis=16
[ 3362.923859] [drm:msm_dp_link_adjust_levels [msm]] lane=1
req_vol_swing=0 req_pre_emphasis=16
[ 3362.923951] [drm:msm_dp_link_adjust_levels [msm]] lane=2
req_vol_swing=0 req_pre_emphasis=16
[ 3362.924036] [drm:msm_dp_link_adjust_levels [msm]] lane=3
req_vol_swing=0 req_pre_emphasis=16
[ 3362.924120] [drm:msm_dp_link_adjust_levels [msm]] adjusted:
v_level=0, p_level=2
[ 3362.924202] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] voltage level: 0
emphasis level: 2
[ 3362.924306] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] sink: p|v=0x10
[ 3362.925224] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0011 AUX <-
(ret= 4) 10 10 10 10
[ 3362.926580] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.927474] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0030 AUX -> (ret= 5) 44 00 00 cc cc
[ 3362.927524] [drm:msm_dp_link_adjust_levels [msm]] lane=0
req_vol_swing=0 req_pre_emphasis=24
[ 3362.927709] [drm:msm_dp_link_adjust_levels [msm]] lane=1
req_vol_swing=0 req_pre_emphasis=24
[ 3362.927801] [drm:msm_dp_link_adjust_levels [msm]] lane=2
req_vol_swing=0 req_pre_emphasis=24
[ 3362.927884] [drm:msm_dp_link_adjust_levels [msm]] lane=3
req_vol_swing=0 req_pre_emphasis=24
[ 3362.927967] [drm:msm_dp_link_adjust_levels [msm]] adjusted:
v_level=0, p_level=3
[ 3362.928049] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] voltage level: 0
emphasis level: 3
[ 3362.928150] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] max.
pre-emphasis level reached 3
[ 3362.928233] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] sink: p|v=0x18
[ 3362.929028] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0011 AUX <-
(ret= 4) 38 38 38 38
[ 3362.930175] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.930889] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0030 AUX -> (ret= 5) 44 00 00 cc cc
[ 3362.930940] [drm:msm_dp_link_adjust_levels [msm]] lane=0
req_vol_swing=0 req_pre_emphasis=24
[ 3362.931099] [drm:msm_dp_link_adjust_levels [msm]] lane=1
req_vol_swing=0 req_pre_emphasis=24
[ 3362.931189] [drm:msm_dp_link_adjust_levels [msm]] lane=2
req_vol_swing=0 req_pre_emphasis=24
[ 3362.931272] [drm:msm_dp_link_adjust_levels [msm]] lane=3
req_vol_swing=0 req_pre_emphasis=24
[ 3362.931354] [drm:msm_dp_link_adjust_levels [msm]] adjusted:
v_level=0, p_level=3
[ 3362.931436] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] voltage level: 0
emphasis level: 3
[ 3362.931536] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] max.
pre-emphasis level reached 3
[ 3362.931646] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] sink: p|v=0x18
[ 3362.932371] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0011 AUX <-
(ret= 4) 38 38 38 38
[ 3362.936053] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.936963] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0030 AUX -> (ret= 5) 44 00 00 cc cc
[ 3362.937016] [drm:msm_dp_link_adjust_levels [msm]] lane=0
req_vol_swing=0 req_pre_emphasis=24
[ 3362.937177] [drm:msm_dp_link_adjust_levels [msm]] lane=1
req_vol_swing=0 req_pre_emphasis=24
[ 3362.937268] [drm:msm_dp_link_adjust_levels [msm]] lane=2
req_vol_swing=0 req_pre_emphasis=24
[ 3362.937351] [drm:msm_dp_link_adjust_levels [msm]] lane=3
req_vol_swing=0 req_pre_emphasis=24
[ 3362.937433] [drm:msm_dp_link_adjust_levels [msm]] adjusted:
v_level=0, p_level=3
[ 3362.937514] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] voltage level: 0
emphasis level: 3
[ 3362.937641] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] max.
pre-emphasis level reached 3
[ 3362.937723] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] sink: p|v=0x18
[ 3362.938501] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0011 AUX <-
(ret= 4) 38 38 38 38
[ 3362.943935] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.945316] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0030 AUX -> (ret= 5) 44 40 00 cc cc
[ 3362.945367] [drm:msm_dp_link_adjust_levels [msm]] lane=0
req_vol_swing=0 req_pre_emphasis=24
[ 3362.945529] [drm:msm_dp_link_adjust_levels [msm]] lane=1
req_vol_swing=0 req_pre_emphasis=24
[ 3362.945635] [drm:msm_dp_link_adjust_levels [msm]] lane=2
req_vol_swing=0 req_pre_emphasis=24
[ 3362.945718] [drm:msm_dp_link_adjust_levels [msm]] lane=3
req_vol_swing=0 req_pre_emphasis=24
[ 3362.945800] [drm:msm_dp_link_adjust_levels [msm]] adjusted:
v_level=0, p_level=3
[ 3362.945882] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] voltage level: 0
emphasis level: 3
[ 3362.945986] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] max.
pre-emphasis level reached 3
[ 3362.946067] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] sink: p|v=0x18
[ 3362.950952] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0011 AUX <-
(ret= 4) 38 38 38 38
[ 3362.952314] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.953207] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0030 AUX -> (ret= 5) 44 40 00 cc cc
[ 3362.953258] [drm:msm_dp_link_adjust_levels [msm]] lane=0
req_vol_swing=0 req_pre_emphasis=24
[ 3362.953419] [drm:msm_dp_link_adjust_levels [msm]] lane=1
req_vol_swing=0 req_pre_emphasis=24
[ 3362.953510] [drm:msm_dp_link_adjust_levels [msm]] lane=2
req_vol_swing=0 req_pre_emphasis=24
[ 3362.953609] [drm:msm_dp_link_adjust_levels [msm]] lane=3
req_vol_swing=0 req_pre_emphasis=24
[ 3362.953691] [drm:msm_dp_link_adjust_levels [msm]] adjusted:
v_level=0, p_level=3
[ 3362.953774] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] voltage level: 0
emphasis level: 3
[ 3362.953877] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] max.
pre-emphasis level reached 3
[ 3362.953960] [drm:msm_dp_ctrl_update_phy_vx_px [msm]] sink: p|v=0x18
[ 3362.954679] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0011 AUX <-
(ret= 4) 38 38 38 38
[ 3362.954711] [drm:msm_dp_ctrl_link_train_1_2 [msm]] *ERROR* link
training #2 on phy 1 failed. ret=-110
[ 3362.954801] [drm:msm_dp_ctrl_train_pattern_set.isra.0 [msm]] sink:
pattern=0
[ 3362.955398] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0xf0010 AUX <-
(ret= 1) 00
[ 3362.956028] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_probe [drm_display_helper]] dpu_dp_aux: 0x00102 AUX ->
(ret= 1) 00
[ 3362.956599] msm_dpu ae01000.display-controller: [drm:drm_dp_dpcd_read
[drm_display_helper]] dpu_dp_aux: 0xf0020 AUX -> (ret= 1) 00
[ 3362.957142] [drm:msm_dp_ctrl_setup_main_link [msm]] *ERROR* link
training of LTTPR(s) failed. ret=-110
[ 3362.957304] [drm:msm_dp_ctrl_train_pattern_set.isra.0 [msm]] sink:
pattern=0
[ 3362.958191] msm_dpu ae01000.display-controller:
[drm:drm_dp_dpcd_write [drm_display_helper]] dpu_dp_aux: 0x00102 AUX <-
(ret= 1) 00
[ 3362.976554] [drm:msm_dp_ctrl_config_ctrl [msm]]
DP_CONFIGURATION_CTRL=0x4277
[ 3362.976783] [drm:msm_dp_ctrl_on_stream [msm]] misc settings = 0x41
[ 3362.976877] [drm:msm_dp_panel_timing_cfg [msm]] width=3840 hporch= 80
48 32
[ 3362.976969] [drm:msm_dp_panel_timing_cfg [msm]] height=2560 vporch=
60 3 10
[ 3362.977067] [drm:msm_dp_panel_timing_cfg [msm]] wide_bus_en=1 reg=0x10
[ 3362.977152] [drm:msm_dp_ctrl_on_stream [msm]] mvid=0x12822, nvid=0x17bb0
[ 3362.977264] [drm:msm_dp_ctrl_on_stream [msm]] n_sym = 30, num_of_tus
= 480
[ 3362.994315] [drm:msm_dp_ctrl_on_stream [msm]] TU: valid_boundary_link: 30
[ 3362.994401] [drm:msm_dp_ctrl_on_stream [msm]] TU: delay_start_link: 20
[ 3362.994483] [drm:msm_dp_ctrl_on_stream [msm]] TU:
boundary_moderation_en: 1
[ 3362.994680] [drm:msm_dp_ctrl_on_stream [msm]] TU:
valid_lower_boundary_link: 29
[ 3362.994763] [drm:msm_dp_ctrl_on_stream [msm]] TU: upper_boundary_count: 1
[ 3362.994845] [drm:msm_dp_ctrl_on_stream [msm]] TU: lower_boundary_count: 3
[ 3362.994927] [drm:msm_dp_ctrl_on_stream [msm]] TU: tu_size_minus1: 39
[ 3362.995259] [drm:msm_dp_ctrl_isr [msm]] dp_video_ready
[ 3362.995423] [drm:msm_dp_ctrl_on_stream [msm]] mainlink READY
[ 3362.995579] msm_dpu ae01000.display-controller:
[drm:msm_dp_bridge_atomic_enable [msm]] type=10 Done
~val
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine
2026-03-17 23:15 ` Val Packett
@ 2026-03-18 1:03 ` Dmitry Baryshkov
2026-03-18 1:58 ` Val Packett
0 siblings, 1 reply; 17+ messages in thread
From: Dmitry Baryshkov @ 2026-03-18 1:03 UTC (permalink / raw)
To: Val Packett
Cc: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Kuogee Hsieh, Yongxing Mou, linux-arm-msm, dri-devel, freedreno,
linux-kernel
On Tue, Mar 17, 2026 at 08:15:54PM -0300, Val Packett wrote:
>
> On 3/16/26 12:23 AM, Dmitry Baryshkov wrote:
> > On Sat, Mar 14, 2026 at 10:10:26PM -0300, Val Packett wrote:
> > > On 3/14/26 9:51 PM, Val Packett wrote:
> > > > On 3/13/26 10:09 PM, Dmitry Baryshkov wrote:
> > > > > Currently, all HPD interrupt handling must go through the HPD state
> > > > > machine.
> > > > >
> > > > > This has caused many issues where the DRM framework assumes that DP is
> > > > > in one state while the state machine is stuck in another state.
> > > > >
> > > > > As discussed here [1], this series:
> > > > >
> > > > > - Removes the state machine
> > > > > - Moves link training to atomic_enable()
> > > > > - Changes the detect() behavior to return true if a display is
> > > > > physically
> > > > > plugged in (as opposed to if the DP link is ready).
> > > > > - Remove event queue and move internal HPD handling to hpd_notify()
> > > > >
> > > > > To correctly detect the displays which are plugged on boot on the boards
> > > > > which use dp-connector devices, this series depends on [2]. USB-C and
> > > > > eDP panels are handled natively.
> > > > >
> > > > > [1] https://patchwork.freedesktop.org/patch/656312/?series=142010&rev=2#comment_1201738
> > > > > [2] https://lore.kernel.org/all/20260314-dp-connector-hpd-v1-0-786044cedc17@oss.qualcomm.com/
> > > > Unfortunately this currently seems to mostly break link training with
> > > > USB-C, on x1e80100-dell-latitude-7455:
> > > >
> > > > [ 102.190083] [drm:msm_dp_ctrl_link_train_1_2 [msm]] *ERROR* link
> > > > training #2 on phy 1 failed. ret=-110
> > > > [ 102.192846] [drm:msm_dp_ctrl_setup_main_link [msm]] *ERROR* link
> > > > training of LTTPR(s) failed. ret=-110
> > > > [ 102.211095] [drm:msm_dp_bridge_atomic_enable [msm]] *ERROR* Failed
> > > > link training (rc=-104)
> > > > [ 102.211164] [drm:msm_dp_aux_isr [msm]] *ERROR* Unexpected DP AUX IRQ
> > > > 0x01000000 when not busy
> > > > [ 102.247168] [drm:msm_dp_ctrl_link_train_1_2 [msm]] *ERROR* link
> > > > training #2 on phy 1 failed. ret=-110
> > > > [ 102.252859] [drm:msm_dp_ctrl_setup_main_link [msm]] *ERROR* link
> > > > training of LTTPR(s) failed. ret=-110
> > > >
> > > > [..]
> > > Actually looks like that might've been due to having applied the [2]
> > > dp-connector series from above.
> > Interesting. The series only affects dp-connector. It can't affect
> > pmic-glink usecase.
> >
> > > Removed it and rebooted, now plugging and unplugging multiple times between
> > > the 2 ports works fine.
> > >
> > > Except unplug is still not reliable, the "ghost" monitor often remains after
> > > unplugging.
> > Does the patch at [3] fix the issue?
> >
> > [3] https://lore.kernel.org/linux-arm-msm/177362655076.7429.3868048981197120360.b4-ty@kernel.org/
>
> Yes!
>
> Overall works better than ever now, looks like I can unplug the cable with
> the laptop closed and then open it and it's all fine, and even play with
> dual-role / gadget mode USB and plug the alt-mode/dock cable back in and it
> doesn't crash.
Tested-by?
>
> Still, rare link training failures can happen, e.g.:
Thanks!
The link training is one of the items that I want to check next.
> > > Almost nothing is logged to dmesg, literally I've only seen this line once:
> > > [drm:msm_dp_panel_read_sink_caps [msm]] *ERROR* panel edid read failed
> > You might want to use drm.debug=0x100 to get DP-related messages.
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine
2026-03-18 1:03 ` Dmitry Baryshkov
@ 2026-03-18 1:58 ` Val Packett
0 siblings, 0 replies; 17+ messages in thread
From: Val Packett @ 2026-03-18 1:58 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Kuogee Hsieh, Yongxing Mou, linux-arm-msm, dri-devel, freedreno,
linux-kernel
On 3/17/26 10:03 PM, Dmitry Baryshkov wrote:
> On Tue, Mar 17, 2026 at 08:15:54PM -0300, Val Packett wrote:
>> On 3/16/26 12:23 AM, Dmitry Baryshkov wrote:
>>> On Sat, Mar 14, 2026 at 10:10:26PM -0300, Val Packett wrote:
>>>> On 3/14/26 9:51 PM, Val Packett wrote:
>>>>> On 3/13/26 10:09 PM, Dmitry Baryshkov wrote:
>>>>>> Currently, all HPD interrupt handling must go through the HPD state
>>>>>> machine.
>>>>>>
>>>>>> This has caused many issues where the DRM framework assumes that DP is
>>>>>> in one state while the state machine is stuck in another state.
>>>>>>
>>>>>> As discussed here [1], this series:
>>>>>>
>>>>>> - Removes the state machine
>>>>>> - Moves link training to atomic_enable()
>>>>>> - Changes the detect() behavior to return true if a display is
>>>>>> physically
>>>>>> plugged in (as opposed to if the DP link is ready).
>>>>>> - Remove event queue and move internal HPD handling to hpd_notify()
>>>>>>
>>>>>> To correctly detect the displays which are plugged on boot on the boards
>>>>>> which use dp-connector devices, this series depends on [2]. USB-C and
>>>>>> eDP panels are handled natively.
>>>>>>
>>>>>> [1] https://patchwork.freedesktop.org/patch/656312/?series=142010&rev=2#comment_1201738
>>>>>> [2] https://lore.kernel.org/all/20260314-dp-connector-hpd-v1-0-786044cedc17@oss.qualcomm.com/
>>>>> Unfortunately this currently seems to mostly break link training with
>>>>> USB-C, on x1e80100-dell-latitude-7455:
>>>>>
>>>>> [ 102.190083] [drm:msm_dp_ctrl_link_train_1_2 [msm]] *ERROR* link
>>>>> training #2 on phy 1 failed. ret=-110
>>>>> [ 102.192846] [drm:msm_dp_ctrl_setup_main_link [msm]] *ERROR* link
>>>>> training of LTTPR(s) failed. ret=-110
>>>>> [ 102.211095] [drm:msm_dp_bridge_atomic_enable [msm]] *ERROR* Failed
>>>>> link training (rc=-104)
>>>>> [ 102.211164] [drm:msm_dp_aux_isr [msm]] *ERROR* Unexpected DP AUX IRQ
>>>>> 0x01000000 when not busy
>>>>> [ 102.247168] [drm:msm_dp_ctrl_link_train_1_2 [msm]] *ERROR* link
>>>>> training #2 on phy 1 failed. ret=-110
>>>>> [ 102.252859] [drm:msm_dp_ctrl_setup_main_link [msm]] *ERROR* link
>>>>> training of LTTPR(s) failed. ret=-110
>>>>>
>>>>> [..]
>>>> Actually looks like that might've been due to having applied the [2]
>>>> dp-connector series from above.
>>> Interesting. The series only affects dp-connector. It can't affect
>>> pmic-glink usecase.
>>>
>>>> Removed it and rebooted, now plugging and unplugging multiple times between
>>>> the 2 ports works fine.
>>>>
>>>> Except unplug is still not reliable, the "ghost" monitor often remains after
>>>> unplugging.
>>> Does the patch at [3] fix the issue?
>>>
>>> [3] https://lore.kernel.org/linux-arm-msm/177362655076.7429.3868048981197120360.b4-ty@kernel.org/
>> Yes!
>>
>> Overall works better than ever now, looks like I can unplug the cable with
>> the laptop closed and then open it and it's all fine, and even play with
>> dual-role / gadget mode USB and plug the alt-mode/dock cable back in and it
>> doesn't crash.
> Tested-by?
Yeah, since I guess the link training is kinda orthogonal to this, sure!
Tested-by: Val Packett <val@packett.cool> # x1e80100-dell-latitude-7455
>> Still, rare link training failures can happen, e.g.:
> Thanks!
>
> The link training is one of the items that I want to check next.
>
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2026-03-18 1:58 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-14 1:09 [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 01/10] drm/msm/dp: fix HPD state status bit shift value Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 02/10] drm/msm/dp: Fix the ISR_* enum values Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 03/10] drm/msm/dp: Read DPCD and sink count in bridge detect() Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 04/10] drm/msm/dp: Move link training to atomic_enable() Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 05/10] drm/msm/dp: Drop EV_USER_NOTIFICATION Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 06/10] drm/msm/dp: drop event data Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 07/10] drm/msm/dp: rework HPD handling Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 08/10] drm/msm/dp: Add sink_count to debug logs Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 09/10] drm/msm/dp: turn link_ready into plugged Dmitry Baryshkov
2026-03-14 1:09 ` [PATCH v5 10/10] drm/msm/dp: clear EDID on display unplug Dmitry Baryshkov
2026-03-15 0:51 ` [PATCH v5 00/10] drm/msm/dp: Drop the HPD state machine Val Packett
2026-03-15 1:10 ` Val Packett
2026-03-16 3:23 ` Dmitry Baryshkov
2026-03-17 23:15 ` Val Packett
2026-03-18 1:03 ` Dmitry Baryshkov
2026-03-18 1:58 ` Val Packett
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox