[PATCH 2/3] drm/msm/dp: don't log an expected link-training fallback as errors

From: Jean-Francois Bobier

Date: Mon Oct 05 2026 - 11:24:04 EST


msm_dp_ctrl_on_link() implements DP link fallback: it retries
msm_dp_ctrl_setup_main_link() up to five times, stepping the link rate
down HBR3 -> HBR2 -> HBR -> RBR and then reducing the lane count, and
breaks as soon as training succeeds. Every step of that search is
therefore expected to fail before the one that works.

Each failed attempt currently logs at error level, from four places:

max v_level reached
link training #1 on phy %d failed. ret=%d
link training #2 on phy %d failed. ret=%d
link training on sink failed. ret=%d

A monitor that settles on two lanes after three attempts prints nine
error lines on a completely successful attach -- which is how a cable
that merely has two bad lanes looks identical in the log to a sink that
never trains at all.

Nothing is lost by demoting them. When the retry loop really does
exhaust itself, msm_dp_ctrl_on_link() returns the error and
msm_dp_display_process_hpd_high() already reports it once, at error
level, as "Failed link training (rc=%d)" -- which is the correct place,
because it is the only one that knows the search is over.

Demote the per-attempt messages to drm_dbg_dp() so they remain available
with drm.debug, and keep the final verdict where it is.

Also demote the unsolicited AUX interrupt message. msm_dp_aux_isr()
returns IRQ_NONE when no AUX transaction is outstanding, which is the
whole of the correct response for an interrupt that is not ours -- the
AUX block shares its interrupt and sinks raise AUX status asynchronously
around hotplug, so this fires twice on a normal DisplayPort attach.

Signed-off-by: Jean-Francois Bobier <jean-francois.bobier@xxxxxxxxxxx>
---
drivers/gpu/drm/msm/dp/dp_aux.c | 9 ++++++++-
drivers/gpu/drm/msm/dp/dp_ctrl.c | 15 ++++++++++-----
2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c
index 3825a2fb4..2c0bc719a 100644
--- a/drivers/gpu/drm/msm/dp/dp_aux.c
+++ b/drivers/gpu/drm/msm/dp/dp_aux.c
@@ -458,7 +458,14 @@ irqreturn_t msm_dp_aux_isr(struct drm_dp_aux *msm_dp_aux, u32 isr)
aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);

if (!aux->cmd_busy) {
- DRM_ERROR("Unexpected DP AUX IRQ %#010x when not busy\n", isr);
+ /*
+ * Not ours: the AUX block shares its interrupt, and sinks
+ * raise AUX status asynchronously around hotplug. Returning
+ * IRQ_NONE is the whole of the correct response, so this is
+ * a trace point and not a fault.
+ */
+ drm_dbg_dp(msm_dp_aux->drm_dev,
+ "Unexpected DP AUX IRQ %#010x when not busy\n", isr);
return IRQ_NONE;
}

diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index d6219d87d..ccc6cf63d 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -1534,7 +1534,8 @@ static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,

if (ctrl->link->phy_params.v_level >=
DP_TRAIN_LEVEL_MAX) {
- DRM_ERROR_RATELIMITED("max v_level reached\n");
+ drm_dbg_dp(ctrl->drm_dev,
+ "max v_level reached, retrying at a lower rate or lane count\n");
return -EAGAIN;
}

@@ -1681,14 +1682,16 @@ static int msm_dp_ctrl_link_train_1_2(struct msm_dp_ctrl_private *ctrl,

ret = msm_dp_ctrl_link_train_1(ctrl, panel, training_step, dp_phy);
if (ret) {
- DRM_ERROR("link training #1 on phy %d failed. ret=%d\n", dp_phy, ret);
+ drm_dbg_dp(ctrl->drm_dev,
+ "link training #1 on phy %d failed. ret=%d\n", dp_phy, ret);
return ret;
}
drm_dbg_dp(ctrl->drm_dev, "link training #1 on phy %d successful\n", dp_phy);

ret = msm_dp_ctrl_link_train_2(ctrl, panel, training_step, dp_phy);
if (ret) {
- DRM_ERROR("link training #2 on phy %d failed. ret=%d\n", dp_phy, ret);
+ drm_dbg_dp(ctrl->drm_dev,
+ "link training #2 on phy %d failed. ret=%d\n", dp_phy, ret);
return ret;
}
drm_dbg_dp(ctrl->drm_dev, "link training #2 on phy %d successful\n", dp_phy);
@@ -1739,13 +1742,15 @@ static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl,
}

if (ret) {
- DRM_ERROR("link training of LTTPR(s) failed. ret=%d\n", ret);
+ drm_dbg_dp(ctrl->drm_dev,
+ "link training of LTTPR(s) failed. ret=%d\n", ret);
goto end;
}

ret = msm_dp_ctrl_link_train_1_2(ctrl, panel, training_step, DP_PHY_DPRX);
if (ret) {
- DRM_ERROR("link training on sink failed. ret=%d\n", ret);
+ drm_dbg_dp(ctrl->drm_dev,
+ "link training on sink failed. ret=%d\n", ret);
goto end;
}

--
2.55.0