[RFC 1/4] drm/i915/display/dp: Add DP fallback on LT

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Fallback mandates on DP link training failure. This patch just covers
the DP2.0 fallback sequence.

TODO: Need to implement the DP1.4 fallback.

Signed-off-by: Arun R Murthy <arun.r.murthy@xxxxxxxxx>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 92 ++++++++++++++++++++++---
 1 file changed, 82 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 10ec231acd98..82d354a6b0cd 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -104,6 +104,50 @@ static const u8 valid_dsc_bpp[] = {6, 8, 10, 12, 15};
  */
 static const u8 valid_dsc_slicecount[] = {1, 2, 4};
 
+/* DL Link Rates */
+#define UHBR20		2000000
+#define UHBR13P5	1350000
+#define UHBR10		1000000
+#define HBR3		810000
+#define HBR2		540000
+#define HBR		270000
+#define RBR		162000
+
+/* DP Lane Count */
+#define LANE_COUNT_4	4
+#define LANE_COUNT_2	2
+#define LANE_COUNT_1	1
+
+/* DP2.0 fallback values */
+struct dp_fallback {
+	u32 link_rate;
+	u8 lane_count;
+};
+
+struct dp_fallback dp2dot0_fallback[] = {
+	{UHBR20, LANE_COUNT_4},
+	{UHBR13P5, LANE_COUNT_4},
+	{UHBR20, LANE_COUNT_2},
+	{UHBR10, LANE_COUNT_4},
+	{UHBR13P5, LANE_COUNT_2},
+	{HBR3, LANE_COUNT_4},
+	{UHBR20, LANE_COUNT_1},
+	{UHBR10, LANE_COUNT_2},
+	{HBR2, LANE_COUNT_4},
+	{UHBR13P5, LANE_COUNT_1},
+	{HBR3, LANE_COUNT_2},
+	{UHBR10, LANE_COUNT_1},
+	{HBR2, LANE_COUNT_2},
+	{HBR, LANE_COUNT_4},
+	{HBR3, LANE_COUNT_1},
+	{RBR, LANE_COUNT_4},
+	{HBR2, LANE_COUNT_1},
+	{HBR, LANE_COUNT_2},
+	{RBR, LANE_COUNT_2},
+	{HBR, LANE_COUNT_1},
+	{RBR, LANE_COUNT_1},
+};
+
 /**
  * intel_dp_is_edp - is the given port attached to an eDP panel (either CPU or PCH)
  * @intel_dp: DP struct
@@ -299,6 +343,19 @@ static int intel_dp_common_len_rate_limit(const struct intel_dp *intel_dp,
 				       intel_dp->num_common_rates, max_rate);
 }
 
+static bool intel_dp_link_rate_supported(struct intel_dp *intel_dp, u32 link_rate)
+{
+	u8 i;
+
+	for (i = 0; i < ARRAY_SIZE(intel_dp->common_rates); i++) {
+		if (intel_dp->common_rates[i] == link_rate)
+			return true;
+		else
+			continue;
+	}
+	return false;
+}
+
 static int intel_dp_common_rate(struct intel_dp *intel_dp, int index)
 {
 	if (drm_WARN_ON(&dp_to_i915(intel_dp)->drm,
@@ -671,15 +728,6 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	int index;
 
-	/*
-	 * TODO: Enable fallback on MST links once MST link compute can handle
-	 * the fallback params.
-	 */
-	if (intel_dp->is_mst) {
-		drm_err(&i915->drm, "Link Training Unsuccessful\n");
-		return -1;
-	}
-
 	if (intel_dp_is_edp(intel_dp) && !intel_dp->use_max_params) {
 		drm_dbg_kms(&i915->drm,
 			    "Retrying Link training for eDP with max parameters\n");
@@ -687,6 +735,31 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
 		return 0;
 	}
 
+	/* DP fallback values */
+	if (intel_dp->dpcd[DP_MAIN_LINK_CHANNEL_CODING] & DP_CAP_ANSI_128B132B) {
+		for(index = 0; index < ARRAY_SIZE(dp2dot0_fallback); index++) {
+			if (link_rate == dp2dot0_fallback[index].link_rate &&
+				lane_count == dp2dot0_fallback[index].lane_count) {
+				for(index += 1; index < ARRAY_SIZE(dp2dot0_fallback); index++) {
+					if (intel_dp_link_rate_supported(intel_dp,
+							dp2dot0_fallback[index].link_rate)) {
+						intel_dp_set_link_params(intel_dp,
+								      dp2dot0_fallback[index].link_rate,
+								      dp2dot0_fallback[index].lane_count);
+						drm_dbg_kms(&i915->drm,
+							    "Retrying Link training with link rate %d and lane count %d\n",
+							    dp2dot0_fallback[index].link_rate,
+							    dp2dot0_fallback[index].lane_count);
+						return 0;
+					}
+				}
+			}
+		}
+		/* Report failure and fail link training */
+		drm_err(&i915->drm, "Link Training Unsuccessful\n");
+		return -1;
+	}
+
 	index = intel_dp_rate_index(intel_dp->common_rates,
 				    intel_dp->num_common_rates,
 				    link_rate);
@@ -716,7 +789,6 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
 		drm_err(&i915->drm, "Link Training Unsuccessful\n");
 		return -1;
 	}
-
 	return 0;
 }
 
-- 
2.25.1




[Index of Archives]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux