The DP 2.0 errata redefines link training. There are some new status
bits, and some of the old ones need to be checked independently. Add
helpers to do this.

Cc: Uma Shankar <uma.shan...@intel.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nik...@intel.com>
---
 drivers/gpu/drm/dp/drm_dp.c    | 63 ++++++++++++++++++++++++++++++++++
 include/drm/dp/drm_dp_helper.h | 19 +++++++---
 2 files changed, 77 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/dp/drm_dp.c b/drivers/gpu/drm/dp/drm_dp.c
index 52c6da510142..a20b0f8f24b8 100644
--- a/drivers/gpu/drm/dp/drm_dp.c
+++ b/drivers/gpu/drm/dp/drm_dp.c
@@ -144,6 +144,69 @@ u8 drm_dp_get_adjust_tx_ffe_preset(const u8 
link_status[DP_LINK_STATUS_SIZE],
 }
 EXPORT_SYMBOL(drm_dp_get_adjust_tx_ffe_preset);
 
+/* DP 2.0 errata for 128b/132b */
+bool drm_dp_128b132b_lane_channel_eq_done(const u8 
link_status[DP_LINK_STATUS_SIZE],
+                                         int lane_count)
+{
+       u8 lane_align, lane_status;
+       int lane;
+
+       lane_align = dp_link_status(link_status, DP_LANE_ALIGN_STATUS_UPDATED);
+       if (!(lane_align & DP_INTERLANE_ALIGN_DONE))
+               return false;
+
+       for (lane = 0; lane < lane_count; lane++) {
+               lane_status = dp_get_lane_status(link_status, lane);
+               if (!(lane_status & DP_LANE_CHANNEL_EQ_DONE))
+                       return false;
+       }
+       return true;
+}
+EXPORT_SYMBOL(drm_dp_128b132b_lane_channel_eq_done);
+
+/* DP 2.0 errata for 128b/132b */
+bool drm_dp_128b132b_lane_symbol_locked(const u8 
link_status[DP_LINK_STATUS_SIZE],
+                                       int lane_count)
+{
+       u8 lane_status;
+       int lane;
+
+       for (lane = 0; lane < lane_count; lane++) {
+               lane_status = dp_get_lane_status(link_status, lane);
+               if (!(lane_status & DP_LANE_SYMBOL_LOCKED))
+                       return false;
+       }
+       return true;
+}
+EXPORT_SYMBOL(drm_dp_128b132b_lane_symbol_locked);
+
+/* DP 2.0 errata for 128b/132b */
+bool drm_dp_128b132b_eq_interlane_align_done(const u8 
link_status[DP_LINK_STATUS_SIZE])
+{
+       u8 status = dp_link_status(link_status, DP_LANE_ALIGN_STATUS_UPDATED);
+
+       return status & DP_128B132B_DPRX_EQ_INTERLANE_ALIGN_DONE;
+}
+EXPORT_SYMBOL(drm_dp_128b132b_eq_interlane_align_done);
+
+/* DP 2.0 errata for 128b/132b */
+bool drm_dp_128b132b_cds_interlane_align_done(const u8 
link_status[DP_LINK_STATUS_SIZE])
+{
+       u8 status = dp_link_status(link_status, DP_LANE_ALIGN_STATUS_UPDATED);
+
+       return status & DP_128B132B_DPRX_CDS_INTERLANE_ALIGN_DONE;
+}
+EXPORT_SYMBOL(drm_dp_128b132b_cds_interlane_align_done);
+
+/* DP 2.0 errata for 128b/132b */
+bool drm_dp_128b132b_link_training_failed(const u8 
link_status[DP_LINK_STATUS_SIZE])
+{
+       u8 status = dp_link_status(link_status, DP_LANE_ALIGN_STATUS_UPDATED);
+
+       return status & DP_128B132B_LT_FAILED;
+}
+EXPORT_SYMBOL(drm_dp_128b132b_link_training_failed);
+
 u8 drm_dp_get_adjust_request_post_cursor(const u8 
link_status[DP_LINK_STATUS_SIZE],
                                         unsigned int lane)
 {
diff --git a/include/drm/dp/drm_dp_helper.h b/include/drm/dp/drm_dp_helper.h
index aa73dfc817ff..c499d735b992 100644
--- a/include/drm/dp/drm_dp_helper.h
+++ b/include/drm/dp/drm_dp_helper.h
@@ -738,11 +738,13 @@ struct drm_panel;
                            DP_LANE_CHANNEL_EQ_DONE |   \
                            DP_LANE_SYMBOL_LOCKED)
 
-#define DP_LANE_ALIGN_STATUS_UPDATED       0x204
-
-#define DP_INTERLANE_ALIGN_DONE                    (1 << 0)
-#define DP_DOWNSTREAM_PORT_STATUS_CHANGED   (1 << 6)
-#define DP_LINK_STATUS_UPDATED             (1 << 7)
+#define DP_LANE_ALIGN_STATUS_UPDATED                    0x204
+#define  DP_INTERLANE_ALIGN_DONE                        (1 << 0)
+#define  DP_128B132B_DPRX_EQ_INTERLANE_ALIGN_DONE       (1 << 2) /* 2.0 E11 */
+#define  DP_128B132B_DPRX_CDS_INTERLANE_ALIGN_DONE      (1 << 3) /* 2.0 E11 */
+#define  DP_128B132B_LT_FAILED                          (1 << 4) /* 2.0 E11 */
+#define  DP_DOWNSTREAM_PORT_STATUS_CHANGED              (1 << 6)
+#define  DP_LINK_STATUS_UPDATED                         (1 << 7)
 
 #define DP_SINK_STATUS                     0x205
 # define DP_RECEIVE_PORT_0_STATUS          (1 << 0)
@@ -1551,6 +1553,13 @@ void drm_dp_lttpr_link_train_channel_eq_delay(const 
struct drm_dp_aux *aux,
                                              const u8 
caps[DP_LTTPR_PHY_CAP_SIZE]);
 
 int drm_dp_128b132b_read_aux_rd_interval(struct drm_dp_aux *aux);
+bool drm_dp_128b132b_lane_channel_eq_done(const u8 
link_status[DP_LINK_STATUS_SIZE],
+                                         int lane_count);
+bool drm_dp_128b132b_lane_symbol_locked(const u8 
link_status[DP_LINK_STATUS_SIZE],
+                                       int lane_count);
+bool drm_dp_128b132b_eq_interlane_align_done(const u8 
link_status[DP_LINK_STATUS_SIZE]);
+bool drm_dp_128b132b_cds_interlane_align_done(const u8 
link_status[DP_LINK_STATUS_SIZE]);
+bool drm_dp_128b132b_link_training_failed(const u8 
link_status[DP_LINK_STATUS_SIZE]);
 
 u8 drm_dp_link_rate_to_bw_code(int link_rate);
 int drm_dp_bw_code_to_link_rate(u8 link_bw);
-- 
2.30.2

Reply via email to