Blob Blame History Raw
From 888ebb7bbcccb5aef3acac272fdbac966eaaab77 Mon Sep 17 00:00:00 2001
From: Jani Nikula <jani.nikula@intel.com>
Date: Thu, 7 Oct 2021 13:57:27 +0300
Subject: drm/i915/dp: take LTTPR into account in 128b/132b rates
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Git-commit: c474420ba412280bc49888c3ce224f0c650c0dcb
Patch-mainline: v5.16-rc1
References: jsc#PED-1166 jsc#PED-1168 jsc#PED-1170 jsc#PED-1218 jsc#PED-1220 jsc#PED-1222 jsc#PED-1223 jsc#PED-1225

Limit the supported UHBR rates based on the repeater support, if there
are repeaters.

This should be done in DP helper level, but that requires an overhaul of
the LTTPR handling, as the max rate is not enough to represent how
128b/132b rates may be masked along the way.

Curiously, the spec says:

* Shall be cleared to 00h when operating in 8b/10b Link Layer.

* Each LTTPR on the way back to the DPTX shall clear the bits that do
  not correspond to the LTTPR's current bit rate.

It's rather vague if we can reliably use the field at this time due to
the wording "operating" and "current". But it would seem bizarre to have
to wait until trying to operate a 128b/132b link layer at a certain bit
rate to figure this out.

Cc: Ville Syrj채l채 <ville.syrjala@linux.intel.com>
Reviewed-by: Ville Syrj채l채 <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211007105727.18439-1-jani.nikula@intel.com
Acked-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 2d0ca857b92a..2f7e0229dd68 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -140,6 +140,9 @@ static void intel_dp_set_sink_rates(struct intel_dp *intel_dp)
 		return;
 	}
 
+	/*
+	 * Sink rates for 8b/10b.
+	 */
 	max_rate = drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE]);
 	max_lttpr_rate = drm_dp_lttpr_max_link_rate(intel_dp->lttpr_common_caps);
 	if (max_lttpr_rate)
@@ -163,6 +166,21 @@ static void intel_dp_set_sink_rates(struct intel_dp *intel_dp)
 		drm_dp_dpcd_readb(&intel_dp->aux,
 				  DP_128B132B_SUPPORTED_LINK_RATES, &uhbr_rates);
 
+		if (drm_dp_lttpr_count(intel_dp->lttpr_common_caps)) {
+			/* We have a repeater */
+			if (intel_dp->lttpr_common_caps[0] >= 0x20 &&
+			    intel_dp->lttpr_common_caps[DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER -
+							DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV] &
+			    DP_PHY_REPEATER_128B132B_SUPPORTED) {
+				/* Repeater supports 128b/132b, valid UHBR rates */
+				uhbr_rates &= intel_dp->lttpr_common_caps[DP_PHY_REPEATER_128B132B_RATES -
+									  DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
+			} else {
+				/* Does not support 128b/132b */
+				uhbr_rates = 0;
+			}
+		}
+
 		if (uhbr_rates & DP_UHBR10)
 			intel_dp->sink_rates[i++] = 1000000;
 		if (uhbr_rates & DP_UHBR13_5)
-- 
2.38.1