The 128b/132b channel coding link training uses more straightforward TX
FFE preset values.

v2: Fix UHBR rate checks, use intel_dp_is_uhbr() helper

Signed-off-by: Jani Nikula <jani.nik...@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c      | 13 ++-
 .../drm/i915/display/intel_dp_link_training.c | 86 +++++++++++++------
 2 files changed, 70 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index d2b96b2efdfe..5805bdd6e1f2 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1398,11 +1398,16 @@ static int translate_signal_level(struct intel_dp 
*intel_dp,
 static int intel_ddi_dp_level(struct intel_dp *intel_dp,
                              const struct intel_crtc_state *crtc_state)
 {
-       u8 train_set = intel_dp->train_set[0];
-       u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
-                                       DP_TRAIN_PRE_EMPHASIS_MASK);
+       if (intel_dp_is_uhbr(crtc_state)) {
+               /* FIXME: We'll want independent presets for each lane. */
+               return intel_dp->train_set[0] & DP_TX_FFE_PRESET_VALUE_MASK;
+       } else {
+               u8 train_set = intel_dp->train_set[0];
+               u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
+                                               DP_TRAIN_PRE_EMPHASIS_MASK);
 
-       return translate_signal_level(intel_dp, signal_levels);
+               return translate_signal_level(intel_dp, signal_levels);
+       }
 }
 
 static void
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c 
b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index 4f116cd32846..c10f165d1aa2 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -301,6 +301,24 @@ static u8 intel_dp_phy_preemph_max(struct intel_dp 
*intel_dp,
        return preemph_max;
 }
 
+static void intel_dp_128b132b_adjust_train(struct intel_dp *intel_dp,
+                                          const struct intel_crtc_state 
*crtc_state,
+                                          const u8 
link_status[DP_LINK_STATUS_SIZE])
+{
+       int lane;
+       u8 tx_ffe = 0;
+
+       /*
+        * FIXME: We'll want independent presets for each lane. See also
+        * intel_ddi_dp_level() and intel_snps_phy_ddi_vswing_sequence().
+        */
+       for (lane = 0; lane < crtc_state->lane_count; lane++)
+               tx_ffe = max(tx_ffe, 
drm_dp_get_adjust_tx_ffe_preset(link_status, lane));
+
+       for (lane = 0; lane < crtc_state->lane_count; lane++)
+               intel_dp->train_set[lane] = tx_ffe;
+}
+
 void
 intel_dp_get_adjust_train(struct intel_dp *intel_dp,
                          const struct intel_crtc_state *crtc_state,
@@ -313,6 +331,11 @@ intel_dp_get_adjust_train(struct intel_dp *intel_dp,
        u8 voltage_max;
        u8 preemph_max;
 
+       if (intel_dp_is_uhbr(crtc_state)) {
+               intel_dp_128b132b_adjust_train(intel_dp, crtc_state, 
link_status);
+               return;
+       }
+
        for (lane = 0; lane < crtc_state->lane_count; lane++) {
                v = max(v, drm_dp_get_adjust_request_voltage(link_status, 
lane));
                p = max(p, drm_dp_get_adjust_request_pre_emphasis(link_status, 
lane));
@@ -402,14 +425,21 @@ void intel_dp_set_signal_levels(struct intel_dp *intel_dp,
        u8 train_set = intel_dp->train_set[0];
        char phy_name[10];
 
-       drm_dbg_kms(&dev_priv->drm, "Using vswing level %d%s, pre-emphasis 
level %d%s, at %s\n",
-                   train_set & DP_TRAIN_VOLTAGE_SWING_MASK,
-                   train_set & DP_TRAIN_MAX_SWING_REACHED ? " (max)" : "",
-                   (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >>
-                   DP_TRAIN_PRE_EMPHASIS_SHIFT,
-                   train_set & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED ?
-                   " (max)" : "",
-                   intel_dp_phy_name(dp_phy, phy_name, sizeof(phy_name)));
+       if (intel_dp_is_uhbr(crtc_state)) {
+               /* FIXME: We'll want independent presets for each lane. */
+               drm_dbg_kms(&dev_priv->drm, "%s: Using 128b/132b TX FFE preset 
%u\n",
+                           intel_dp_phy_name(dp_phy, phy_name, 
sizeof(phy_name)),
+                           train_set & DP_TX_FFE_PRESET_VALUE_MASK);
+       } else {
+               drm_dbg_kms(&dev_priv->drm, "%s: Using 8b/10b vswing level 
%d%s, pre-emphasis level %d%s\n",
+                           intel_dp_phy_name(dp_phy, phy_name, 
sizeof(phy_name)),
+                           train_set & DP_TRAIN_VOLTAGE_SWING_MASK,
+                           train_set & DP_TRAIN_MAX_SWING_REACHED ? " (max)" : 
"",
+                           (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >>
+                           DP_TRAIN_PRE_EMPHASIS_SHIFT,
+                           train_set & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED ?
+                           " (max)" : "");
+       }
 
        if (intel_dp_phy_is_downstream_of_source(intel_dp, dp_phy))
                intel_dp->set_signal_levels(intel_dp, crtc_state);
@@ -565,18 +595,21 @@ intel_dp_link_training_clock_recovery(struct intel_dp 
*intel_dp,
                        return true;
                }
 
-               if (voltage_tries == 5) {
-                       drm_dbg_kms(&i915->drm,
-                                   "Same voltage tried 5 times\n");
-                       return false;
-               }
+               /* FIXME: 128b/132b needs better abstractions here. */
+               if (!intel_dp_is_uhbr(crtc_state)) {
+                       if (voltage_tries == 5) {
+                               drm_dbg_kms(&i915->drm,
+                                           "Same voltage tried 5 times\n");
+                               return false;
+                       }
 
-               if (max_vswing_reached) {
-                       drm_dbg_kms(&i915->drm, "Max Voltage Swing reached\n");
-                       return false;
-               }
+                       if (max_vswing_reached) {
+                               drm_dbg_kms(&i915->drm, "Max Voltage Swing 
reached\n");
+                               return false;
+                       }
 
-               voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+                       voltage = intel_dp->train_set[0] & 
DP_TRAIN_VOLTAGE_SWING_MASK;
+               }
 
                /* Update training set as requested by target */
                intel_dp_get_adjust_train(intel_dp, crtc_state, dp_phy,
@@ -587,14 +620,17 @@ intel_dp_link_training_clock_recovery(struct intel_dp 
*intel_dp,
                        return false;
                }
 
-               if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) ==
-                   voltage)
-                       ++voltage_tries;
-               else
-                       voltage_tries = 1;
+               /* FIXME: 128b/132b needs better abstractions here. */
+               if (!intel_dp_is_uhbr(crtc_state)) {
+                       if ((intel_dp->train_set[0] & 
DP_TRAIN_VOLTAGE_SWING_MASK) ==
+                           voltage)
+                               ++voltage_tries;
+                       else
+                               voltage_tries = 1;
 
-               if (intel_dp_link_max_vswing_reached(intel_dp, crtc_state))
-                       max_vswing_reached = true;
+                       if (intel_dp_link_max_vswing_reached(intel_dp, 
crtc_state))
+                               max_vswing_reached = true;
+               }
 
        }
        drm_err(&i915->drm,
-- 
2.30.2

Reply via email to