All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/7] drm: Define a work struct for scheduling a uevent for modeset retry
@ 2016-10-26 23:25 Manasi Navare
  2016-10-26 23:25 ` [PATCH 2/7] drm: Add a new connector property for link status Manasi Navare
                   ` (7 more replies)
  0 siblings, 8 replies; 13+ messages in thread
From: Manasi Navare @ 2016-10-26 23:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter, dri-devel

This work struct will be used to schedule a uevent on a separate
thread. This will be scheduled after a link train failure during modeset
to indicate a modeset retry request. It will get executed after the
current modeset is complete and all locks are released. This was
required to avoid deadlock.

v2:
* Create a generic work func not i915 specific (Daniel Vetter)

Cc: dri-devel@lists.freedesktop.org
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>

Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 include/drm/drm_connector.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index ac9d7d8..fc9d475 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -682,6 +682,11 @@ struct drm_connector {
 	uint8_t num_h_tile, num_v_tile;
 	uint8_t tile_h_loc, tile_v_loc;
 	uint16_t tile_h_size, tile_v_size;
+
+	/* Work struct to schedule a uevent on link train failure for
+	 * DisplayPort.
+	 */
+	struct work_struct modeset_retry_work;
 };
 
 #define obj_to_connector(x) container_of(x, struct drm_connector, base)
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/7] drm: Add a new connector property for link status
  2016-10-26 23:25 [PATCH 1/7] drm: Define a work struct for scheduling a uevent for modeset retry Manasi Navare
@ 2016-10-26 23:25 ` Manasi Navare
  2016-10-26 23:25 ` [PATCH 3/7] drm/i915: Set link status property for DP connector Manasi Navare
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Manasi Navare @ 2016-10-26 23:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Daniel Vetter

A new default connector property is added for keeping
track of whether the link is good (link training passed) or
link is bad (link training  failed). If the link status property
is not good, then userspace should fire off a new modeset at the current
mode even if there have not been any changes in the mode list
or connector status.

v2:
* Make this a default connector property (Daniel Vetter)

Cc: dri-devel@lists.freedesktop.org
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/drm_connector.c | 17 +++++++++++++++++
 include/drm/drm_connector.h     |  1 -
 include/drm/drm_crtc.h          |  5 +++++
 include/uapi/drm/drm_mode.h     |  4 ++++
 4 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 2db7fb5..d4e852f 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
 	drm_object_attach_property(&connector->base,
 				      config->dpms_property, 0);
 
+	drm_object_attach_property(&connector->base,
+				   config->link_status_property,
+				   0);
+
 	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
 		drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
 	}
@@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
 };
 DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
 
+static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
+	{ DRM_MODE_LINK_STATUS_GOOD, "Good" },
+	{ DRM_MODE_LINK_STATUS_BAD, "Bad" },
+};
+DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
+
 /**
  * drm_display_info_set_bus_formats - set the supported bus formats
  * @info: display info to store bus formats in
@@ -622,6 +632,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
 		return -ENOMEM;
 	dev->mode_config.tile_property = prop;
 
+	prop = drm_property_create_enum(dev, 0, "link-status",
+					drm_link_status_enum_list,
+					ARRAY_SIZE(drm_link_status_enum_list));
+	if (!prop)
+		return -ENOMEM;
+	dev->mode_config.link_status_property = prop;
+
 	return 0;
 }
 
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index fc9d475..3bb420d 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -759,7 +759,6 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
 int drm_mode_create_scaling_mode_property(struct drm_device *dev);
 int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
 int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
-
 int drm_mode_connector_set_path_property(struct drm_connector *connector,
 					 const char *path);
 int drm_mode_connector_set_tile_property(struct drm_connector *connector);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index fa1aa21..b86ca19 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1151,6 +1151,11 @@ struct drm_mode_config {
 	 */
 	struct drm_property *tile_property;
 	/**
+	 * @link_status_property: Default connector property for link status
+	 * of a connector as a result of link training.
+	 */
+	struct drm_property *link_status_property;
+	/**
 	 * @plane_type_property: Default plane property to differentiate
 	 * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
 	 */
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 084b50a..f1b0afd 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -121,6 +121,10 @@
 #define DRM_MODE_DIRTY_ON       1
 #define DRM_MODE_DIRTY_ANNOTATE 2
 
+/* Link Status options */
+#define DRM_MODE_LINK_STATUS_GOOD	0
+#define DRM_MODE_LINK_STATUS_BAD	1
+
 struct drm_mode_modeinfo {
 	__u32 clock;
 	__u16 hdisplay;
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/7] drm/i915: Set link status property for DP connector
  2016-10-26 23:25 [PATCH 1/7] drm: Define a work struct for scheduling a uevent for modeset retry Manasi Navare
  2016-10-26 23:25 ` [PATCH 2/7] drm: Add a new connector property for link status Manasi Navare
@ 2016-10-26 23:25 ` Manasi Navare
  2016-10-28 12:03   ` Jani Nikula
  2016-10-26 23:25 ` [PATCH 4/7] drm/i915: Change the placement of some static functions in intel_dp.c Manasi Navare
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 13+ messages in thread
From: Manasi Navare @ 2016-10-26 23:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Daniel Vetter

This defines a helper function to set the property value.
This will be used to set the link status to Bad in case
of link training failures.

Cc: dri-devel@lists.freedesktop.org
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c  | 16 ++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h |  2 ++
 2 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 3c2293b..795897c 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4673,6 +4673,22 @@ static int intel_dp_get_modes(struct drm_connector *connector)
 	return 0;
 }
 
+int
+intel_dp_set_link_status_property(struct drm_connector *connector,
+				  uint64_t val)
+{
+	struct drm_device *dev = connector->dev;
+	int ret = 0;
+
+	ret = drm_object_property_set_value(&connector->base,
+					    dev->mode_config.link_status_property,
+					    val);
+	if (ret)
+		return ret;
+
+	return ret;
+}
+
 static int
 intel_dp_connector_register(struct drm_connector *connector)
 {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 7dda79d..f6fe05a 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1397,6 +1397,8 @@ u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane,
 bool intel_dp_init(struct drm_device *dev, i915_reg_t output_reg, enum port port);
 bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 			     struct intel_connector *intel_connector);
+int intel_dp_set_link_status_property(struct drm_connector *connector,
+				      uint64_t val);
 void intel_dp_set_link_params(struct intel_dp *intel_dp,
 			      int link_rate, uint8_t lane_count,
 			      bool link_mst);
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 4/7] drm/i915: Change the placement of some static functions in intel_dp.c
  2016-10-26 23:25 [PATCH 1/7] drm: Define a work struct for scheduling a uevent for modeset retry Manasi Navare
  2016-10-26 23:25 ` [PATCH 2/7] drm: Add a new connector property for link status Manasi Navare
  2016-10-26 23:25 ` [PATCH 3/7] drm/i915: Set link status property for DP connector Manasi Navare
@ 2016-10-26 23:25 ` Manasi Navare
  2016-10-28 12:11   ` Jani Nikula
  2016-10-26 23:25 ` [PATCH 5/7] drm/i915; Add a function to return index of link rate Manasi Navare
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 13+ messages in thread
From: Manasi Navare @ 2016-10-26 23:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter

From: "Navare, Manasi D" <manasi.d.navare@intel.com>

These static helper functions are required to be used during
fallback link rate implemnetation so they need to be placed at the top
of the file.

v3:
* Add cleanup to other patch (Mika Kahola)
v2:
* Dont move around functions declared in intel_drv.h (Rodrigo Vivi)

Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 150 ++++++++++++++++++++--------------------
 1 file changed, 75 insertions(+), 75 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 795897c..aecfd22 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -213,6 +213,81 @@ static u8 intel_dp_max_lane_count(struct intel_dp *intel_dp)
 	return max_dotclk;
 }
 
+static int
+intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
+{
+	if (intel_dp->num_sink_rates) {
+		*sink_rates = intel_dp->sink_rates;
+		return intel_dp->num_sink_rates;
+	}
+
+	*sink_rates = default_rates;
+
+	return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
+}
+
+static int
+intel_dp_source_rates(struct intel_dp *intel_dp, const int **source_rates)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
+	int size;
+
+	if (IS_BROXTON(dev_priv)) {
+		*source_rates = bxt_rates;
+		size = ARRAY_SIZE(bxt_rates);
+	} else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
+		*source_rates = skl_rates;
+		size = ARRAY_SIZE(skl_rates);
+	} else {
+		*source_rates = default_rates;
+		size = ARRAY_SIZE(default_rates);
+	}
+
+	/* This depends on the fact that 5.4 is last value in the array */
+	if (!intel_dp_source_supports_hbr2(intel_dp))
+		size--;
+
+	return size;
+}
+
+static int intersect_rates(const int *source_rates, int source_len,
+			   const int *sink_rates, int sink_len,
+			   int *common_rates)
+{
+	int i = 0, j = 0, k = 0;
+
+	while (i < source_len && j < sink_len) {
+		if (source_rates[i] == sink_rates[j]) {
+			if (WARN_ON(k >= DP_MAX_SUPPORTED_RATES))
+				return k;
+			common_rates[k] = source_rates[i];
+			++k;
+			++i;
+			++j;
+		} else if (source_rates[i] < sink_rates[j]) {
+			++i;
+		} else {
+			++j;
+		}
+	}
+	return k;
+}
+
+static int intel_dp_common_rates(struct intel_dp *intel_dp,
+				 int *common_rates)
+{
+	const int *source_rates, *sink_rates;
+	int source_len, sink_len;
+
+	sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
+	source_len = intel_dp_source_rates(intel_dp, &source_rates);
+
+	return intersect_rates(source_rates, source_len,
+			       sink_rates, sink_len,
+			       common_rates);
+}
+
 static enum drm_mode_status
 intel_dp_mode_valid(struct drm_connector *connector,
 		    struct drm_display_mode *mode)
@@ -1291,19 +1366,6 @@ static void intel_aux_reg_init(struct intel_dp *intel_dp)
 	intel_dp->aux.transfer = intel_dp_aux_transfer;
 }
 
-static int
-intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
-{
-	if (intel_dp->num_sink_rates) {
-		*sink_rates = intel_dp->sink_rates;
-		return intel_dp->num_sink_rates;
-	}
-
-	*sink_rates = default_rates;
-
-	return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
-}
-
 bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
@@ -1316,31 +1378,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
 		return false;
 }
 
-static int
-intel_dp_source_rates(struct intel_dp *intel_dp, const int **source_rates)
-{
-	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
-	int size;
-
-	if (IS_BROXTON(dev_priv)) {
-		*source_rates = bxt_rates;
-		size = ARRAY_SIZE(bxt_rates);
-	} else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
-		*source_rates = skl_rates;
-		size = ARRAY_SIZE(skl_rates);
-	} else {
-		*source_rates = default_rates;
-		size = ARRAY_SIZE(default_rates);
-	}
-
-	/* This depends on the fact that 5.4 is last value in the array */
-	if (!intel_dp_source_supports_hbr2(intel_dp))
-		size--;
-
-	return size;
-}
-
 static void
 intel_dp_set_clock(struct intel_encoder *encoder,
 		   struct intel_crtc_state *pipe_config)
@@ -1375,43 +1412,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
 	}
 }
 
-static int intersect_rates(const int *source_rates, int source_len,
-			   const int *sink_rates, int sink_len,
-			   int *common_rates)
-{
-	int i = 0, j = 0, k = 0;
-
-	while (i < source_len && j < sink_len) {
-		if (source_rates[i] == sink_rates[j]) {
-			if (WARN_ON(k >= DP_MAX_SUPPORTED_RATES))
-				return k;
-			common_rates[k] = source_rates[i];
-			++k;
-			++i;
-			++j;
-		} else if (source_rates[i] < sink_rates[j]) {
-			++i;
-		} else {
-			++j;
-		}
-	}
-	return k;
-}
-
-static int intel_dp_common_rates(struct intel_dp *intel_dp,
-				 int *common_rates)
-{
-	const int *source_rates, *sink_rates;
-	int source_len, sink_len;
-
-	sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
-	source_len = intel_dp_source_rates(intel_dp, &source_rates);
-
-	return intersect_rates(source_rates, source_len,
-			       sink_rates, sink_len,
-			       common_rates);
-}
-
 static void snprintf_int_array(char *str, size_t len,
 			       const int *array, int nelem)
 {
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 5/7] drm/i915; Add a function to return index of link rate
  2016-10-26 23:25 [PATCH 1/7] drm: Define a work struct for scheduling a uevent for modeset retry Manasi Navare
                   ` (2 preceding siblings ...)
  2016-10-26 23:25 ` [PATCH 4/7] drm/i915: Change the placement of some static functions in intel_dp.c Manasi Navare
@ 2016-10-26 23:25 ` Manasi Navare
  2016-10-28 12:14   ` Jani Nikula
  2016-10-26 23:25 ` [PATCH 6/7] drm/i915: Find fallback link rate/lane count Manasi Navare
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 13+ messages in thread
From: Manasi Navare @ 2016-10-26 23:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter

This is required to return the index of link rate into
common_rates array. This gets used to retry the link
training at lower link rate.

Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index aecfd22..39116c8 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -288,6 +288,21 @@ static int intel_dp_common_rates(struct intel_dp *intel_dp,
 			       common_rates);
 }
 
+static int intel_dp_link_rate_index(struct intel_dp *intel_dp,
+				    int *common_rates, int link_rate)
+{
+	int common_len;
+	int index;
+
+	common_len = intel_dp_common_rates(intel_dp, common_rates);
+	for (index = 0; index < common_len; index++) {
+		if (link_rate == common_rates[common_len - index - 1])
+			return common_len - index - 1;
+	}
+
+	return -1;
+}
+
 static enum drm_mode_status
 intel_dp_mode_valid(struct drm_connector *connector,
 		    struct drm_display_mode *mode)
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 6/7] drm/i915: Find fallback link rate/lane count
  2016-10-26 23:25 [PATCH 1/7] drm: Define a work struct for scheduling a uevent for modeset retry Manasi Navare
                   ` (3 preceding siblings ...)
  2016-10-26 23:25 ` [PATCH 5/7] drm/i915; Add a function to return index of link rate Manasi Navare
@ 2016-10-26 23:25 ` Manasi Navare
  2016-10-26 23:25 ` [PATCH 7/7] drm/i915: Link Rate fallback on Link training failure Manasi Navare
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Manasi Navare @ 2016-10-26 23:25 UTC (permalink / raw)
  To: intel-gfx

If link training fails, then we need to fallback to lower
link rate first and if link training fails at RBR, then
fallback to lower lane count.

Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c  | 28 ++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h |  6 ++++++
 2 files changed, 34 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 39116c8..369b5ce 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -303,6 +303,34 @@ static int intel_dp_link_rate_index(struct intel_dp *intel_dp,
 	return -1;
 }
 
+void intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
+					     int link_rate, uint8_t lane_count)
+{
+	int common_rates[DP_MAX_SUPPORTED_RATES] = {};
+	int common_len;
+	int link_rate_index = -1;
+
+	if (!intel_dp->link_train_failed)
+		return;
+
+	common_len = intel_dp_common_rates(intel_dp, common_rates);
+	link_rate_index = intel_dp_link_rate_index(intel_dp,
+						   common_rates,
+						   link_rate);
+	if (link_rate_index > 0) {
+		intel_dp->fallback_link_rate_index = link_rate_index - 1;
+		intel_dp->fallback_link_rate = common_rates[intel_dp->fallback_link_rate_index];
+		intel_dp->fallback_lane_count = intel_dp_max_lane_count(intel_dp);
+	} else if (lane_count > 1) {
+		intel_dp->fallback_link_rate_index = common_len -1;
+		intel_dp->fallback_link_rate = common_rates[intel_dp->fallback_link_rate_index];
+		intel_dp->fallback_lane_count = lane_count - 1;
+	} else {
+		DRM_ERROR ("Link Training Unsuccessful\n");
+		intel_dp->link_train_failed = false;
+	}
+}
+
 static enum drm_mode_status
 intel_dp_mode_valid(struct drm_connector *connector,
 		    struct drm_display_mode *mode)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index f6fe05a..c6789ee 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -890,6 +890,10 @@ struct intel_dp {
 	uint32_t DP;
 	int link_rate;
 	uint8_t lane_count;
+	int fallback_link_rate;
+	uint8_t fallback_lane_count;
+	int fallback_link_rate_index;
+	bool link_train_failed;
 	uint8_t sink_count;
 	bool link_mst;
 	bool has_audio;
@@ -1402,6 +1406,8 @@ int intel_dp_set_link_status_property(struct drm_connector *connector,
 void intel_dp_set_link_params(struct intel_dp *intel_dp,
 			      int link_rate, uint8_t lane_count,
 			      bool link_mst);
+void intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
+					     int link_rate, uint8_t lane_count);
 void intel_dp_start_link_train(struct intel_dp *intel_dp);
 void intel_dp_stop_link_train(struct intel_dp *intel_dp);
 void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 7/7] drm/i915: Link Rate fallback on Link training failure
  2016-10-26 23:25 [PATCH 1/7] drm: Define a work struct for scheduling a uevent for modeset retry Manasi Navare
                   ` (4 preceding siblings ...)
  2016-10-26 23:25 ` [PATCH 6/7] drm/i915: Find fallback link rate/lane count Manasi Navare
@ 2016-10-26 23:25 ` Manasi Navare
  2016-10-26 23:55 ` ✗ Fi.CI.BAT: failure for series starting with [1/7] drm: Define a work struct for scheduling a uevent for modeset retry Patchwork
  2016-10-28 12:01 ` [PATCH 1/7] " Jani Nikula
  7 siblings, 0 replies; 13+ messages in thread
From: Manasi Navare @ 2016-10-26 23:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter

If link training at a link rate optimal for a particular
mode fails during modeset's atomic commit phase, then we
let the modeset complete and then retry. We save the link rate
value at which link training failed and use a lower link rate
to prune the modes. It will redo the modeset on the current mode
at lower link rate or if the current mode gets pruned due to lower
link constraints then, it will send a hotplug uevent for userspace
to handle it.

This is also required to pass DP CTS tests 4.3.1.3, 4.3.1.4,
4.3.1.6.

Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c              | 22 ++++++++++++-
 drivers/gpu/drm/i915/intel_dp.c               | 47 +++++++++++++++++++++++++--
 drivers/gpu/drm/i915/intel_dp_link_training.c | 12 +++++--
 drivers/gpu/drm/i915/intel_drv.h              |  2 +-
 4 files changed, 75 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index fb18d69..11eae06 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1712,6 +1712,8 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum port port = intel_ddi_get_encoder_port(encoder);
+	struct intel_connector *intel_connector = intel_dp->attached_connector;
+	struct drm_connector *connector = &intel_connector->base;
 
 	intel_dp_set_link_params(intel_dp, link_rate, lane_count,
 				 link_mst);
@@ -1722,7 +1724,25 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
 	intel_prepare_dp_ddi_buffers(encoder);
 	intel_ddi_init_dp_buf_reg(encoder);
 	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
-	intel_dp_start_link_train(intel_dp);
+	if (!intel_dp_start_link_train(intel_dp)) {
+		DRM_DEBUG_KMS("Link Training failed at link rate = %d, lane count = %d",
+			      link_rate, lane_count);
+		intel_dp->link_train_failed = true;
+		intel_dp_get_link_train_fallback_values(intel_dp, link_rate,
+							lane_count);
+		/* Schedule a Hotplug Uevent to userspace to start modeset */
+		schedule_work(&connector->modeset_retry_work);
+	} else {
+		DRM_DEBUG_KMS("Link Training Passed at Link Rate = %d, Lane count = %d",
+			      link_rate, lane_count);
+		intel_dp->link_train_failed = false;
+		intel_dp->fallback_link_rate_index = -1;
+		intel_dp->fallback_link_rate = 0;
+		intel_dp->fallback_lane_count = 0;
+		intel_dp_set_link_status_property(connector,
+						  DRM_MODE_LINK_STATUS_GOOD);
+	}
+
 	if (port != PORT_A || INTEL_GEN(dev_priv) >= 9)
 		intel_dp_stop_link_train(intel_dp);
 }
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 369b5ce..7d5b1a7 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -354,8 +354,14 @@ void intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
 		target_clock = fixed_mode->clock;
 	}
 
-	max_link_clock = intel_dp_max_link_rate(intel_dp);
-	max_lanes = intel_dp_max_lane_count(intel_dp);
+	/* Prune the modes using the fallback link rate/lane count */
+	if (intel_dp->link_train_failed) {
+		max_link_clock = intel_dp->fallback_link_rate;
+		max_lanes = intel_dp->fallback_lane_count;
+	} else {
+		max_link_clock = intel_dp_max_link_rate(intel_dp);
+		max_lanes = intel_dp_max_lane_count(intel_dp);
+	}
 
 	max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
 	mode_rate = intel_dp_link_required(target_clock, 18);
@@ -1645,6 +1651,12 @@ static int intel_dp_compute_bpp(struct intel_dp *intel_dp,
 	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
 		return false;
 
+	/* Fall back to lower link rate in case of failure in previous modeset */
+	if (intel_dp->link_train_failed) {
+		min_lane_count = max_lane_count = intel_dp->fallback_lane_count;
+		min_clock = max_clock = intel_dp->fallback_link_rate_index;
+	}
+
 	DRM_DEBUG_KMS("DP link computation with max lane count %i "
 		      "max bw %d pixel clock %iKHz\n",
 		      max_lane_count, common_rates[max_clock],
@@ -4548,7 +4560,7 @@ static bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
 	}
 
 	/* If full detect is not performed yet, do a full detect */
-	if (!intel_dp->detect_done)
+	if (!intel_dp->detect_done && !intel_dp->link_train_failed)
 		status = intel_dp_long_pulse(intel_dp->attached_connector);
 
 	intel_dp->detect_done = false;
@@ -5730,6 +5742,31 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 	return false;
 }
 
+static void intel_dp_modeset_retry_work_fn(struct work_struct *work)
+{
+	struct drm_connector *connector;
+	struct drm_display_mode *mode;
+	bool verbose_prune = true;
+
+	connector = container_of(work, typeof(*connector),
+				 modeset_retry_work);
+
+	/* Grab the locks before changing connector property*/
+	mutex_lock(&connector->dev->mode_config.mutex);
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
+		      connector->name);
+	list_for_each_entry(mode, &connector->modes, head) {
+		mode->status = intel_dp_mode_valid(connector,
+						   mode);
+	}
+	drm_mode_prune_invalid(connector->dev, &connector->modes, verbose_prune);
+	intel_dp_set_link_status_property(connector, DRM_MODE_LINK_STATUS_BAD);
+	mutex_unlock(&connector->dev->mode_config.mutex);
+
+	/* Send Hotplug uevent so userspace can reprobe */
+	drm_kms_helper_hotplug_event(connector->dev);
+}
+
 bool
 intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 			struct intel_connector *intel_connector)
@@ -5742,6 +5779,10 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 	enum port port = intel_dig_port->port;
 	int type;
 
+	/* Initialize the work for modeset in case of link train failure */
+	INIT_WORK(&connector->modeset_retry_work,
+		  intel_dp_modeset_retry_work_fn);
+
 	if (WARN(intel_dig_port->max_lanes < 1,
 		 "Not enough lanes (%d) for DP on port %c\n",
 		 intel_dig_port->max_lanes, port_name(port)))
diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index 0048b52..10f81ab 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -310,9 +310,15 @@ void intel_dp_stop_link_train(struct intel_dp *intel_dp)
 				DP_TRAINING_PATTERN_DISABLE);
 }
 
-void
+bool
 intel_dp_start_link_train(struct intel_dp *intel_dp)
 {
-	intel_dp_link_training_clock_recovery(intel_dp);
-	intel_dp_link_training_channel_equalization(intel_dp);
+	bool ret;
+
+	if (intel_dp_link_training_clock_recovery(intel_dp)) {
+		ret = intel_dp_link_training_channel_equalization(intel_dp);
+		if (ret)
+			return true;
+	}
+	return false;
 }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c6789ee..b645cd2 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1408,7 +1408,7 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp,
 			      bool link_mst);
 void intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
 					     int link_rate, uint8_t lane_count);
-void intel_dp_start_link_train(struct intel_dp *intel_dp);
+bool intel_dp_start_link_train(struct intel_dp *intel_dp);
 void intel_dp_stop_link_train(struct intel_dp *intel_dp);
 void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
 void intel_dp_encoder_reset(struct drm_encoder *encoder);
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* ✗ Fi.CI.BAT: failure for series starting with [1/7] drm: Define a work struct for scheduling a uevent for modeset retry
  2016-10-26 23:25 [PATCH 1/7] drm: Define a work struct for scheduling a uevent for modeset retry Manasi Navare
                   ` (5 preceding siblings ...)
  2016-10-26 23:25 ` [PATCH 7/7] drm/i915: Link Rate fallback on Link training failure Manasi Navare
@ 2016-10-26 23:55 ` Patchwork
  2016-10-28 12:01 ` [PATCH 1/7] " Jani Nikula
  7 siblings, 0 replies; 13+ messages in thread
From: Patchwork @ 2016-10-26 23:55 UTC (permalink / raw)
  To: Navare, Manasi D; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/7] drm: Define a work struct for scheduling a uevent for modeset retry
URL   : https://patchwork.freedesktop.org/series/14442/
State : failure

== Summary ==

Series 14442v1 Series without cover letter
https://patchwork.freedesktop.org/api/1.0/series/14442/revisions/1/mbox/

Test kms_pipe_crc_basic:
        Subgroup hang-read-crc-pipe-a:
                pass       -> TIMEOUT    (fi-snb-2520m)
        Subgroup hang-read-crc-pipe-b:
                pass       -> INCOMPLETE (fi-snb-2520m)

fi-bdw-5557u     total:246  pass:231  dwarn:0   dfail:0   fail:0   skip:15 
fi-bsw-n3050     total:246  pass:204  dwarn:0   dfail:0   fail:0   skip:42 
fi-bxt-t5700     total:246  pass:216  dwarn:0   dfail:0   fail:0   skip:30 
fi-byt-j1900     total:246  pass:215  dwarn:0   dfail:0   fail:0   skip:31 
fi-byt-n2820     total:246  pass:211  dwarn:0   dfail:0   fail:0   skip:35 
fi-hsw-4770      total:246  pass:224  dwarn:0   dfail:0   fail:0   skip:22 
fi-hsw-4770r     total:246  pass:223  dwarn:0   dfail:0   fail:0   skip:23 
fi-ilk-650       total:246  pass:185  dwarn:0   dfail:0   fail:0   skip:61 
fi-ivb-3520m     total:246  pass:220  dwarn:0   dfail:0   fail:0   skip:26 
fi-ivb-3770      total:246  pass:220  dwarn:0   dfail:0   fail:0   skip:26 
fi-kbl-7200u     total:246  pass:222  dwarn:0   dfail:0   fail:0   skip:24 
fi-skl-6260u     total:246  pass:232  dwarn:0   dfail:0   fail:0   skip:14 
fi-skl-6700hq    total:246  pass:223  dwarn:0   dfail:0   fail:0   skip:23 
fi-skl-6700k     total:246  pass:222  dwarn:1   dfail:0   fail:0   skip:23 
fi-skl-6770hq    total:246  pass:232  dwarn:0   dfail:0   fail:0   skip:14 
fi-snb-2520m     total:194  pass:164  dwarn:0   dfail:0   fail:0   skip:28 
fi-snb-2600      total:246  pass:208  dwarn:0   dfail:0   fail:0   skip:38 

5854c608e6354948f1f5e6be53132c897d0d4902 drm-intel-nightly: 2016y-10m-26d-21h-22m-02s UTC integration manifest
2953a14 drm/i915: Find fallback link rate/lane count
e208699 drm/i915; Add a function to return index of link rate
119f0ef drm/i915: Change the placement of some static functions in intel_dp.c
5e242c3b drm/i915: Set link status property for DP connector
63e66a6 drm: Add a new connector property for link status
41f2ca3 drm: Define a work struct for scheduling a uevent for modeset retry

Full results at https://intel-gfx-ci.01.org/CI/Patchwork_2834/

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_2834/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/7] drm: Define a work struct for scheduling a uevent for modeset retry
  2016-10-26 23:25 [PATCH 1/7] drm: Define a work struct for scheduling a uevent for modeset retry Manasi Navare
                   ` (6 preceding siblings ...)
  2016-10-26 23:55 ` ✗ Fi.CI.BAT: failure for series starting with [1/7] drm: Define a work struct for scheduling a uevent for modeset retry Patchwork
@ 2016-10-28 12:01 ` Jani Nikula
  2016-10-28 12:16   ` Jani Nikula
  7 siblings, 1 reply; 13+ messages in thread
From: Jani Nikula @ 2016-10-28 12:01 UTC (permalink / raw)
  To: Manasi Navare, intel-gfx; +Cc: Daniel Vetter, dri-devel

On Thu, 27 Oct 2016, Manasi Navare <manasi.d.navare@intel.com> wrote:
> This work struct will be used to schedule a uevent on a separate
> thread. This will be scheduled after a link train failure during modeset
> to indicate a modeset retry request. It will get executed after the
> current modeset is complete and all locks are released. This was
> required to avoid deadlock.
>
> v2:
> * Create a generic work func not i915 specific (Daniel Vetter)
>
> Cc: dri-devel@lists.freedesktop.org
> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> Cc: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  include/drm/drm_connector.h | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index ac9d7d8..fc9d475 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -682,6 +682,11 @@ struct drm_connector {
>  	uint8_t num_h_tile, num_v_tile;
>  	uint8_t tile_h_loc, tile_v_loc;
>  	uint16_t tile_h_size, tile_v_size;
> +
> +	/* Work struct to schedule a uevent on link train failure for
> +	 * DisplayPort.
> +	 */
> +	struct work_struct modeset_retry_work;

I think at least for now we should keep this in intel_connector. All the
code using this will be in i915.

BR,
Jani.

>  };
>  
>  #define obj_to_connector(x) container_of(x, struct drm_connector, base)

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 3/7] drm/i915: Set link status property for DP connector
  2016-10-26 23:25 ` [PATCH 3/7] drm/i915: Set link status property for DP connector Manasi Navare
@ 2016-10-28 12:03   ` Jani Nikula
  0 siblings, 0 replies; 13+ messages in thread
From: Jani Nikula @ 2016-10-28 12:03 UTC (permalink / raw)
  To: intel-gfx; +Cc: Manasi Navare, Daniel Vetter, dri-devel

On Thu, 27 Oct 2016, Manasi Navare <manasi.d.navare@intel.com> wrote:
> This defines a helper function to set the property value.
> This will be used to set the link status to Bad in case
> of link training failures.
>
> Cc: dri-devel@lists.freedesktop.org
> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> Cc: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dp.c  | 16 ++++++++++++++++
>  drivers/gpu/drm/i915/intel_drv.h |  2 ++
>  2 files changed, 18 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 3c2293b..795897c 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -4673,6 +4673,22 @@ static int intel_dp_get_modes(struct drm_connector *connector)
>  	return 0;
>  }
>  
> +int
> +intel_dp_set_link_status_property(struct drm_connector *connector,
> +				  uint64_t val)
> +{
> +	struct drm_device *dev = connector->dev;
> +	int ret = 0;
> +
> +	ret = drm_object_property_set_value(&connector->base,
> +					    dev->mode_config.link_status_property,
> +					    val);
> +	if (ret)
> +		return ret;
> +
> +	return ret;

That's a difficult way to say

	return drm_object_property_set_value(...);

> +}
> +
>  static int
>  intel_dp_connector_register(struct drm_connector *connector)
>  {
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 7dda79d..f6fe05a 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1397,6 +1397,8 @@ u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane,
>  bool intel_dp_init(struct drm_device *dev, i915_reg_t output_reg, enum port port);
>  bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
>  			     struct intel_connector *intel_connector);
> +int intel_dp_set_link_status_property(struct drm_connector *connector,
> +				      uint64_t val);
>  void intel_dp_set_link_params(struct intel_dp *intel_dp,
>  			      int link_rate, uint8_t lane_count,
>  			      bool link_mst);

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 4/7] drm/i915: Change the placement of some static functions in intel_dp.c
  2016-10-26 23:25 ` [PATCH 4/7] drm/i915: Change the placement of some static functions in intel_dp.c Manasi Navare
@ 2016-10-28 12:11   ` Jani Nikula
  0 siblings, 0 replies; 13+ messages in thread
From: Jani Nikula @ 2016-10-28 12:11 UTC (permalink / raw)
  To: Manasi Navare, intel-gfx; +Cc: Daniel Vetter

On Thu, 27 Oct 2016, Manasi Navare <manasi.d.navare@intel.com> wrote:
> From: "Navare, Manasi D" <manasi.d.navare@intel.com>
>
> These static helper functions are required to be used during
> fallback link rate implemnetation so they need to be placed at the top
> of the file.
>
> v3:
> * Add cleanup to other patch (Mika Kahola)
> v2:
> * Dont move around functions declared in intel_drv.h (Rodrigo Vivi)
>
> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> Cc: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> Reviewed-by: Mika Kahola <mika.kahola@intel.com>

Pushed this one so we don't have to keep carrying it around. Thanks for
the patch and review.

BR,
Jani.

> ---
>  drivers/gpu/drm/i915/intel_dp.c | 150 ++++++++++++++++++++--------------------
>  1 file changed, 75 insertions(+), 75 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 795897c..aecfd22 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -213,6 +213,81 @@ static u8 intel_dp_max_lane_count(struct intel_dp *intel_dp)
>  	return max_dotclk;
>  }
>  
> +static int
> +intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
> +{
> +	if (intel_dp->num_sink_rates) {
> +		*sink_rates = intel_dp->sink_rates;
> +		return intel_dp->num_sink_rates;
> +	}
> +
> +	*sink_rates = default_rates;
> +
> +	return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
> +}
> +
> +static int
> +intel_dp_source_rates(struct intel_dp *intel_dp, const int **source_rates)
> +{
> +	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> +	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
> +	int size;
> +
> +	if (IS_BROXTON(dev_priv)) {
> +		*source_rates = bxt_rates;
> +		size = ARRAY_SIZE(bxt_rates);
> +	} else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
> +		*source_rates = skl_rates;
> +		size = ARRAY_SIZE(skl_rates);
> +	} else {
> +		*source_rates = default_rates;
> +		size = ARRAY_SIZE(default_rates);
> +	}
> +
> +	/* This depends on the fact that 5.4 is last value in the array */
> +	if (!intel_dp_source_supports_hbr2(intel_dp))
> +		size--;
> +
> +	return size;
> +}
> +
> +static int intersect_rates(const int *source_rates, int source_len,
> +			   const int *sink_rates, int sink_len,
> +			   int *common_rates)
> +{
> +	int i = 0, j = 0, k = 0;
> +
> +	while (i < source_len && j < sink_len) {
> +		if (source_rates[i] == sink_rates[j]) {
> +			if (WARN_ON(k >= DP_MAX_SUPPORTED_RATES))
> +				return k;
> +			common_rates[k] = source_rates[i];
> +			++k;
> +			++i;
> +			++j;
> +		} else if (source_rates[i] < sink_rates[j]) {
> +			++i;
> +		} else {
> +			++j;
> +		}
> +	}
> +	return k;
> +}
> +
> +static int intel_dp_common_rates(struct intel_dp *intel_dp,
> +				 int *common_rates)
> +{
> +	const int *source_rates, *sink_rates;
> +	int source_len, sink_len;
> +
> +	sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
> +	source_len = intel_dp_source_rates(intel_dp, &source_rates);
> +
> +	return intersect_rates(source_rates, source_len,
> +			       sink_rates, sink_len,
> +			       common_rates);
> +}
> +
>  static enum drm_mode_status
>  intel_dp_mode_valid(struct drm_connector *connector,
>  		    struct drm_display_mode *mode)
> @@ -1291,19 +1366,6 @@ static void intel_aux_reg_init(struct intel_dp *intel_dp)
>  	intel_dp->aux.transfer = intel_dp_aux_transfer;
>  }
>  
> -static int
> -intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
> -{
> -	if (intel_dp->num_sink_rates) {
> -		*sink_rates = intel_dp->sink_rates;
> -		return intel_dp->num_sink_rates;
> -	}
> -
> -	*sink_rates = default_rates;
> -
> -	return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
> -}
> -
>  bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
>  {
>  	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> @@ -1316,31 +1378,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
>  		return false;
>  }
>  
> -static int
> -intel_dp_source_rates(struct intel_dp *intel_dp, const int **source_rates)
> -{
> -	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> -	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
> -	int size;
> -
> -	if (IS_BROXTON(dev_priv)) {
> -		*source_rates = bxt_rates;
> -		size = ARRAY_SIZE(bxt_rates);
> -	} else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
> -		*source_rates = skl_rates;
> -		size = ARRAY_SIZE(skl_rates);
> -	} else {
> -		*source_rates = default_rates;
> -		size = ARRAY_SIZE(default_rates);
> -	}
> -
> -	/* This depends on the fact that 5.4 is last value in the array */
> -	if (!intel_dp_source_supports_hbr2(intel_dp))
> -		size--;
> -
> -	return size;
> -}
> -
>  static void
>  intel_dp_set_clock(struct intel_encoder *encoder,
>  		   struct intel_crtc_state *pipe_config)
> @@ -1375,43 +1412,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
>  	}
>  }
>  
> -static int intersect_rates(const int *source_rates, int source_len,
> -			   const int *sink_rates, int sink_len,
> -			   int *common_rates)
> -{
> -	int i = 0, j = 0, k = 0;
> -
> -	while (i < source_len && j < sink_len) {
> -		if (source_rates[i] == sink_rates[j]) {
> -			if (WARN_ON(k >= DP_MAX_SUPPORTED_RATES))
> -				return k;
> -			common_rates[k] = source_rates[i];
> -			++k;
> -			++i;
> -			++j;
> -		} else if (source_rates[i] < sink_rates[j]) {
> -			++i;
> -		} else {
> -			++j;
> -		}
> -	}
> -	return k;
> -}
> -
> -static int intel_dp_common_rates(struct intel_dp *intel_dp,
> -				 int *common_rates)
> -{
> -	const int *source_rates, *sink_rates;
> -	int source_len, sink_len;
> -
> -	sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
> -	source_len = intel_dp_source_rates(intel_dp, &source_rates);
> -
> -	return intersect_rates(source_rates, source_len,
> -			       sink_rates, sink_len,
> -			       common_rates);
> -}
> -
>  static void snprintf_int_array(char *str, size_t len,
>  			       const int *array, int nelem)
>  {

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 5/7] drm/i915; Add a function to return index of link rate
  2016-10-26 23:25 ` [PATCH 5/7] drm/i915; Add a function to return index of link rate Manasi Navare
@ 2016-10-28 12:14   ` Jani Nikula
  0 siblings, 0 replies; 13+ messages in thread
From: Jani Nikula @ 2016-10-28 12:14 UTC (permalink / raw)
  To: Manasi Navare, intel-gfx; +Cc: Daniel Vetter

On Thu, 27 Oct 2016, Manasi Navare <manasi.d.navare@intel.com> wrote:
> This is required to return the index of link rate into
> common_rates array. This gets used to retry the link
> training at lower link rate.
>
> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> Cc: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>

Please squash this with the following patch that uses it. No need to
have it separately.

BR,
Jani.

> ---
>  drivers/gpu/drm/i915/intel_dp.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index aecfd22..39116c8 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -288,6 +288,21 @@ static int intel_dp_common_rates(struct intel_dp *intel_dp,
>  			       common_rates);
>  }
>  
> +static int intel_dp_link_rate_index(struct intel_dp *intel_dp,
> +				    int *common_rates, int link_rate)
> +{
> +	int common_len;
> +	int index;
> +
> +	common_len = intel_dp_common_rates(intel_dp, common_rates);
> +	for (index = 0; index < common_len; index++) {
> +		if (link_rate == common_rates[common_len - index - 1])
> +			return common_len - index - 1;
> +	}
> +
> +	return -1;
> +}
> +
>  static enum drm_mode_status
>  intel_dp_mode_valid(struct drm_connector *connector,
>  		    struct drm_display_mode *mode)

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/7] drm: Define a work struct for scheduling a uevent for modeset retry
  2016-10-28 12:01 ` [PATCH 1/7] " Jani Nikula
@ 2016-10-28 12:16   ` Jani Nikula
  0 siblings, 0 replies; 13+ messages in thread
From: Jani Nikula @ 2016-10-28 12:16 UTC (permalink / raw)
  To: Manasi Navare, intel-gfx; +Cc: Daniel Vetter, dri-devel

On Fri, 28 Oct 2016, Jani Nikula <jani.nikula@linux.intel.com> wrote:
> On Thu, 27 Oct 2016, Manasi Navare <manasi.d.navare@intel.com> wrote:
>> This work struct will be used to schedule a uevent on a separate
>> thread. This will be scheduled after a link train failure during modeset
>> to indicate a modeset retry request. It will get executed after the
>> current modeset is complete and all locks are released. This was
>> required to avoid deadlock.
>>
>> v2:
>> * Create a generic work func not i915 specific (Daniel Vetter)
>>
>> Cc: dri-devel@lists.freedesktop.org
>> Cc: Jani Nikula <jani.nikula@linux.intel.com>
>> Cc: Daniel Vetter <daniel.vetter@intel.com>
>> Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
>>
>> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
>> ---
>>  include/drm/drm_connector.h | 5 +++++
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
>> index ac9d7d8..fc9d475 100644
>> --- a/include/drm/drm_connector.h
>> +++ b/include/drm/drm_connector.h
>> @@ -682,6 +682,11 @@ struct drm_connector {
>>  	uint8_t num_h_tile, num_v_tile;
>>  	uint8_t tile_h_loc, tile_v_loc;
>>  	uint16_t tile_h_size, tile_v_size;
>> +
>> +	/* Work struct to schedule a uevent on link train failure for
>> +	 * DisplayPort.
>> +	 */
>> +	struct work_struct modeset_retry_work;
>
> I think at least for now we should keep this in intel_connector. All the
> code using this will be in i915.

Oh, and you can just squash that in the first patch that uses it,
i.e. patch 7/7 in this series.


>
> BR,
> Jani.
>
>>  };
>>  
>>  #define obj_to_connector(x) container_of(x, struct drm_connector, base)

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2016-10-28 12:16 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-26 23:25 [PATCH 1/7] drm: Define a work struct for scheduling a uevent for modeset retry Manasi Navare
2016-10-26 23:25 ` [PATCH 2/7] drm: Add a new connector property for link status Manasi Navare
2016-10-26 23:25 ` [PATCH 3/7] drm/i915: Set link status property for DP connector Manasi Navare
2016-10-28 12:03   ` Jani Nikula
2016-10-26 23:25 ` [PATCH 4/7] drm/i915: Change the placement of some static functions in intel_dp.c Manasi Navare
2016-10-28 12:11   ` Jani Nikula
2016-10-26 23:25 ` [PATCH 5/7] drm/i915; Add a function to return index of link rate Manasi Navare
2016-10-28 12:14   ` Jani Nikula
2016-10-26 23:25 ` [PATCH 6/7] drm/i915: Find fallback link rate/lane count Manasi Navare
2016-10-26 23:25 ` [PATCH 7/7] drm/i915: Link Rate fallback on Link training failure Manasi Navare
2016-10-26 23:55 ` ✗ Fi.CI.BAT: failure for series starting with [1/7] drm: Define a work struct for scheduling a uevent for modeset retry Patchwork
2016-10-28 12:01 ` [PATCH 1/7] " Jani Nikula
2016-10-28 12:16   ` Jani Nikula

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.