drm/msm/dp: skip checking LINK_STATUS_UPDATED bit
authorKuogee Hsieh <khsieh@codeaurora.org>
Tue, 3 Nov 2020 20:49:01 +0000 (12:49 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 30 Dec 2020 10:53:07 +0000 (11:53 +0100)
[ Upstream commit ea530388e64bd584645f2d89e40ca7dffade8eff ]

Some dongle will not clear LINK_STATUS_UPDATED bit after
DPCD read which cause link training failed. This patch
just read 6 bytes of DPCD link status from sink and return
without checking LINK_STATUS_UPDATED bit.
Only 8 bits are used to represent link rate at sinker DPCD.
The really link rate is 2.7Mb times the 8 bits value.
For example, 0x0A at DPCD is equal to 2.7Gb (10 * 2.7Mb).
This patch also convert 8 bits value of DPCD to really link
rate to fix worng link rate error during phy compliance test.

Fixes: 6625e2637d93 ("drm/msm/dp: DisplayPort PHY compliance tests fixup")
Signed-off-by: Kuogee Hsieh <khsieh@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@chromium.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/gpu/drm/msm/dp/dp_ctrl.c
drivers/gpu/drm/msm/dp/dp_link.c

index cee161c..c83a165 100644 (file)
@@ -1061,23 +1061,15 @@ static bool dp_ctrl_train_pattern_set(struct dp_ctrl_private *ctrl,
 static int dp_ctrl_read_link_status(struct dp_ctrl_private *ctrl,
                                    u8 *link_status)
 {
-       int len = 0;
-       u32 const offset = DP_LANE_ALIGN_STATUS_UPDATED - DP_LANE0_1_STATUS;
-       u32 link_status_read_max_retries = 100;
-
-       while (--link_status_read_max_retries) {
-               len = drm_dp_dpcd_read_link_status(ctrl->aux,
-                       link_status);
-               if (len != DP_LINK_STATUS_SIZE) {
-                       DRM_ERROR("DP link status read failed, err: %d\n", len);
-                       return len;
-               }
+       int ret = 0, len;
 
-               if (!(link_status[offset] & DP_LINK_STATUS_UPDATED))
-                       return 0;
+       len = drm_dp_dpcd_read_link_status(ctrl->aux, link_status);
+       if (len != DP_LINK_STATUS_SIZE) {
+               DRM_ERROR("DP link status read failed, err: %d\n", len);
+               ret = -EINVAL;
        }
 
-       return -ETIMEDOUT;
+       return ret;
 }
 
 static int dp_ctrl_link_train_1(struct dp_ctrl_private *ctrl,
index 49d7fad..be986da 100644 (file)
@@ -773,7 +773,8 @@ static int dp_link_process_link_training_request(struct dp_link_private *link)
                        link->request.test_lane_count);
 
        link->dp_link.link_params.num_lanes = link->request.test_lane_count;
-       link->dp_link.link_params.rate = link->request.test_link_rate;
+       link->dp_link.link_params.rate = 
+               drm_dp_bw_code_to_link_rate(link->request.test_link_rate);
 
        return 0;
 }
@@ -943,22 +944,20 @@ static u8 get_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r)
  */
 static int dp_link_process_link_status_update(struct dp_link_private *link)
 {
-       if (!(get_link_status(link->link_status,
-                               DP_LANE_ALIGN_STATUS_UPDATED) &
-                               DP_LINK_STATUS_UPDATED) ||
-                       (drm_dp_clock_recovery_ok(link->link_status,
-                                       link->dp_link.link_params.num_lanes) &&
-                       drm_dp_channel_eq_ok(link->link_status,
-                                       link->dp_link.link_params.num_lanes)))
-               return -EINVAL;
+       bool channel_eq_done = drm_dp_channel_eq_ok(link->link_status,
+                       link->dp_link.link_params.num_lanes);
 
-       DRM_DEBUG_DP("channel_eq_done = %d, clock_recovery_done = %d\n",
-                       drm_dp_clock_recovery_ok(link->link_status,
-                       link->dp_link.link_params.num_lanes),
-                       drm_dp_clock_recovery_ok(link->link_status,
-                       link->dp_link.link_params.num_lanes));
+       bool clock_recovery_done = drm_dp_clock_recovery_ok(link->link_status,
+                       link->dp_link.link_params.num_lanes);
 
-       return 0;
+       DRM_DEBUG_DP("channel_eq_done = %d, clock_recovery_done = %d\n",
+                        channel_eq_done, clock_recovery_done);
+
+       if (channel_eq_done && clock_recovery_done)
+               return -EINVAL;
+
+
+       return 0;
 }
 
 /**