From 403ae7fd2a50c584775376e6a7d308a51b6eaa8e Mon Sep 17 00:00:00 2001 From: Wyon Bi Date: Wed, 30 Jun 2021 11:44:02 +0800 Subject: [PATCH] drm/rockchip: cdn_dp: Fix link retrain condition Validate the cached values of link parameters before attempting to retrain. Change-Id: Idf4f8a7c2d85109e05dc7e387f46ddeb55cd0a01 Signed-off-by: Wyon Bi --- drivers/gpu/drm/rockchip/cdn-dp-core.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c index 38f2e68cd349..f09fcf89248b 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c @@ -1061,6 +1061,24 @@ out: return ret; } +static bool cdn_dp_needs_link_retrain(struct cdn_dp_device *dp) +{ + u8 link_status[DP_LINK_STATUS_SIZE]; + + /* + * Validate the cached values of link parameters before attempting to + * retrain. + */ + if (!dp->link.rate || !dp->link.num_lanes) + return false; + + if (drm_dp_dpcd_read_link_status(&dp->aux, link_status) < 0) + return false; + + /* Retrain if Channel EQ or CR not ok */ + return !drm_dp_channel_eq_ok(link_status, dp->link.num_lanes); +} + static void cdn_dp_pd_event_work(struct work_struct *work) { struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device, @@ -1101,7 +1119,7 @@ static void cdn_dp_pd_event_work(struct work_struct *work) dp->connected = false; /* Enabled and connected with a sink, re-train if requested */ - } else if (!cdn_dp_check_link_status(dp)) { + } else if (cdn_dp_needs_link_retrain(dp)) { unsigned int rate = dp->link.rate; unsigned int lanes = dp->link.num_lanes; struct drm_display_mode *mode = &dp->mode;