From: Jesse Casco <jesse.casco@gmail.com>
To: robin.clark@oss.qualcomm.com, lumag@kernel.org
Cc: abhinav.kumar@linux.dev, jesszhan0024@gmail.com, sean@poorly.run,
marijn.suijten@somainline.org, airlied@gmail.com,
simona@ffwll.ch, linux-arm-msm@vger.kernel.org,
dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org,
linux-kernel@vger.kernel.org
Subject: [PATCH] drm/msm/dp: don't fall back to a link that can't carry the eDP mode
Date: Sat, 14 Nov 2026 19:00:21 -0500 [thread overview]
Message-ID: <20261115000021.78869-1-jesse.casco@gmail.com> (raw)
When channel equalisation fails after clock recovery succeeded,
msm_dp_ctrl_on_link() halves the lane count and trains again. Nothing
checks that the reduced link can still carry the current mode.
On the ASUS Zenbook A16, channel equalisation at 4 lanes x HBR2 fails
on some DPMS wakes. The 2-lane retry trains but can't carry the mode
(17.03 Gbps needed, 8.64 Gbps available), so the panel stays dark
while userspace sees the output as on.
For eDP, check the reduced link against the mode with the same
bandwidth check as msm_dp_display_mode_valid(), and retry at the
previous parameters when it falls short. External DisplayPort keeps
the existing fallback.
Tested with 100 DPMS off/on cycles before and after: channel
equalisation failed on 6-7% of wakes either way. Without this patch
each failure left the panel dark; with it, each one recovered on the
first retry at 4 lanes.
Signed-off-by: Jesse Casco <jesse.casco@gmail.com>
---
drivers/gpu/drm/msm/dp/dp_ctrl.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index abd3dcd..261645c 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -1587,6 +1587,16 @@ static int msm_dp_ctrl_link_rate_down_shift(struct msm_dp_ctrl_private *ctrl)
return ret;
}
+static bool msm_dp_ctrl_link_fits_mode(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *panel,
+ unsigned long pixel_rate)
+{
+ const struct msm_dp_link_info *params = &ctrl->link->link_params;
+
+ return (u64)pixel_rate * panel->msm_dp_mode.bpp <=
+ (u64)params->num_lanes * params->rate * 8;
+}
+
static int msm_dp_ctrl_link_lane_down_shift(struct msm_dp_ctrl_private *ctrl,
struct msm_dp_panel *panel)
{
@@ -2383,6 +2393,9 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl,
struct msm_dp_ctrl_private *ctrl;
u32 rate;
int link_train_max_retries = 5;
+ bool is_edp = panel->connector &&
+ panel->connector->connector_type == DRM_MODE_CONNECTOR_eDP;
+ struct msm_dp_link_info prev_params;
u32 const phy_cts_pixel_clk_khz = 148500;
u8 link_status[DP_LINK_STATUS_SIZE];
unsigned int training_step;
@@ -2420,6 +2433,7 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl,
return rc;
while (--link_train_max_retries) {
+ prev_params = ctrl->link->link_params;
training_step = DP_TRAINING_NONE;
rc = msm_dp_ctrl_setup_main_link(ctrl, panel, &training_step);
if (rc == 0) {
@@ -2472,6 +2486,18 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl,
msm_dp_ctrl_clear_training_pattern(ctrl, panel, DP_PHY_DPRX);
}
+ /*
+ * An eDP panel has one fixed mode. A lower rate or lane count that
+ * cannot carry it trains, but leaves the panel dark: retry at the
+ * previous parameters instead.
+ */
+ if (is_edp && !msm_dp_ctrl_link_fits_mode(ctrl, panel, pixel_rate)) {
+ ctrl->link->link_params = prev_params;
+ drm_dbg_dp(ctrl->drm_dev,
+ "eDP mode needs rate=%d lanes=%d, retrying\n",
+ prev_params.rate, prev_params.num_lanes);
+ }
+
rc = msm_dp_ctrl_reinitialize_mainlink(ctrl, panel);
if (rc) {
DRM_ERROR("Failed to reinitialize mainlink. rc=%d\n", rc);
--
2.56.0
reply other threads:[~2026-11-15 0:00 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261115000021.78869-1-jesse.casco@gmail.com \
--to=jesse.casco@gmail.com \
--cc=abhinav.kumar@linux.dev \
--cc=airlied@gmail.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=freedreno@lists.freedesktop.org \
--cc=jesszhan0024@gmail.com \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lumag@kernel.org \
--cc=marijn.suijten@somainline.org \
--cc=robin.clark@oss.qualcomm.com \
--cc=sean@poorly.run \
--cc=simona@ffwll.ch \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®