igt-dev.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH i-g-t 3/6] lib/igt_kms: add helpers for connector type
  2025-10-15 10:17 [PATCH i-g-t 0/6] extend link training test cases for eDP connector Kunal Joshi
@ 2025-10-15 10:17 ` Kunal Joshi
  2025-10-27  5:51   ` B, Jeevan
  0 siblings, 1 reply; 9+ messages in thread
From: Kunal Joshi @ 2025-10-15 10:17 UTC (permalink / raw)
  To: igt-dev; +Cc: Kunal Joshi

Introduce helpers for checking output
connector type, reuse same mechanism for
output_is_internal_panel.

Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com>
---
 lib/igt_kms.c                  | 74 ++++++++++++++++++++++++++++------
 lib/igt_kms.h                  |  9 ++++-
 tests/intel/kms_dsc_helper.c   |  2 +-
 tests/intel/kms_pm_backlight.c |  2 +-
 tests/kms_atomic_transition.c  |  4 +-
 tests/kms_hdr.c                |  2 +-
 6 files changed, 74 insertions(+), 19 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index eab4cb92f..f29778f2d 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -3479,22 +3479,70 @@ igt_plane_t *igt_pipe_get_plane_type_index(igt_pipe_t *pipe, int plane_type,
 }
 
 /**
- * output_is_internal_panel:
+ * igt_output_type_in_mask - test connector type membership
+ * @output: output (may be NULL)
+ * @mask: bitmask where bit N corresponds to DRM_MODE_CONNECTOR_* value N
+ *
+ * Returns: true if @output has a connector and its connector_type bit is set
+ * in @mask. Safe for DRM_MODE_CONNECTOR_Unknown (0). If @output or its
+ * connector is NULL, returns false.
+ */
+bool igt_output_type_in_mask(igt_output_t *output, uint64_t mask)
+{
+	unsigned int type;
+
+	if (!output || !output->config.connector)
+		return false;
+
+	type = output->config.connector->connector_type;
+
+	return (mask & CONNECTOR_TYPE_BIT(type)) != 0;
+}
+
+/**
+ * igt_output_is_dp_family - classify DP/eDP as DP family
+ * @output: output
+ *
+ * Returns: true if @output is DisplayPort or eDP.
+ */
+bool igt_output_is_dp_family(igt_output_t *output)
+{
+	uint64_t mask =
+		CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_DisplayPort) |
+		CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_eDP);
+
+	return igt_output_type_in_mask(output, mask);
+}
+
+/**
+ * igt_output_is_hdmi - classify HDMI connectors
+ * @output: output
+ *
+ * Returns: true if @output is HDMI (A or B).
+ */
+bool igt_output_is_hdmi(igt_output_t *output)
+{
+	uint64_t mask =
+		CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_HDMIA) |
+		CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_HDMIB);
+
+	return igt_output_type_in_mask(output, mask);
+}
+
+/**
+ * igt_output_is_internal_panel:
  * @output: Target output
  *
  * Returns: True if the given @output type is internal else False.
  */
-bool output_is_internal_panel(igt_output_t *output)
+bool igt_output_is_internal_panel(igt_output_t *output)
 {
-	switch (output->config.connector->connector_type) {
-	case DRM_MODE_CONNECTOR_LVDS:
-	case DRM_MODE_CONNECTOR_eDP:
-	case DRM_MODE_CONNECTOR_DSI:
-	case DRM_MODE_CONNECTOR_DPI:
-		return true;
-	default:
-		return false;
-	}
+	uint64_t mask = CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_LVDS) |
+			CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_eDP)  |
+			CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_DSI)  |
+			CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_DPI);
+
+	return igt_output_type_in_mask(output, mask);
 }
 
 igt_output_t **__igt_pipe_populate_outputs(igt_display_t *display, igt_output_t **chosen_outputs)
@@ -3521,7 +3569,7 @@ igt_output_t **__igt_pipe_populate_outputs(igt_display_t *display, igt_output_t
 			uint32_t pipe_mask = output->config.valid_crtc_idx_mask & full_pipe_mask;
 			bool found = false;
 
-			if (output_is_internal_panel(output)) {
+			if (igt_output_is_internal_panel(output)) {
 				/*
 				 * Internal panel should be assigned to pipe A
 				 * if possible, so make sure they're enumerated
@@ -3549,7 +3597,7 @@ igt_output_t **__igt_pipe_populate_outputs(igt_display_t *display, igt_output_t
 					    * Overwrite internal panel if not assigned,
 					    * external outputs are faster to do modesets
 					    */
-					   output_is_internal_panel(chosen_outputs[j]))
+					   igt_output_is_internal_panel(chosen_outputs[j]))
 					chosen_outputs[j] = output;
 			}
 
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 7121ab985..c8d394ea9 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -569,7 +569,14 @@ igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
 int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
 igt_plane_t *igt_pipe_get_plane_type_index(igt_pipe_t *pipe, int plane_type,
 					   int index);
-bool output_is_internal_panel(igt_output_t *output);
+#ifndef CONNECTOR_TYPE_BIT
+#define CONNECTOR_TYPE_BIT(e) (1ULL << (e))
+#endif
+
+bool igt_output_type_in_mask(igt_output_t *output, uint64_t mask);
+bool igt_output_is_dp_family(igt_output_t *output);
+bool igt_output_is_hdmi(igt_output_t *output);
+bool igt_output_is_internal_panel(igt_output_t *output);
 igt_output_t *igt_get_single_output_for_pipe(igt_display_t *display, enum pipe pipe);
 
 void igt_pipe_request_out_fence(igt_pipe_t *pipe);
diff --git a/tests/intel/kms_dsc_helper.c b/tests/intel/kms_dsc_helper.c
index cea4304e4..4f23c39af 100644
--- a/tests/intel/kms_dsc_helper.c
+++ b/tests/intel/kms_dsc_helper.c
@@ -74,7 +74,7 @@ bool is_dsc_supported_by_sink(int drmfd, igt_output_t *output)
 		return false;
 	}
 
-	if (!output_is_internal_panel(output) &&
+	if (!igt_output_is_internal_panel(output) &&
 	    !igt_is_fec_supported(drmfd, output->name)) {
 		igt_info("DSC cannot be enabled without FEC on %s\n",
 			  output->name);
diff --git a/tests/intel/kms_pm_backlight.c b/tests/intel/kms_pm_backlight.c
index a0ecf2b0e..27c31d695 100644
--- a/tests/intel/kms_pm_backlight.c
+++ b/tests/intel/kms_pm_backlight.c
@@ -239,7 +239,7 @@ igt_main
 		igt_display_require(&display, drm_open_driver(DRIVER_INTEL | DRIVER_XE));
 
 		for_each_connected_output(&display, output) {
-			if (!output_is_internal_panel(output))
+			if (!igt_output_is_internal_panel(output))
 				continue;
 
 			if (found)
diff --git a/tests/kms_atomic_transition.c b/tests/kms_atomic_transition.c
index a13830965..8e0ed9d08 100644
--- a/tests/kms_atomic_transition.c
+++ b/tests/kms_atomic_transition.c
@@ -1224,11 +1224,11 @@ igt_main_args("", long_opts, help_str, opt_handler, &data)
 				 * panels with long power cycle delays.
 				 */
 				if ((transition_tests[i].type == TRANSITION_MODESET) &&
-				    output_is_internal_panel(output))
+				    igt_output_is_internal_panel(output))
 					continue;
 
 				if ((transition_tests[i].type == TRANSITION_MODESET_FAST) &&
-				    !output_is_internal_panel(output))
+				    !igt_output_is_internal_panel(output))
 					continue;
 
 				if (pipe_count == 2 * count && !data.extended)
diff --git a/tests/kms_hdr.c b/tests/kms_hdr.c
index efa5964cf..c1c1663a2 100644
--- a/tests/kms_hdr.c
+++ b/tests/kms_hdr.c
@@ -730,7 +730,7 @@ static void test_hdr(data_t *data, uint32_t flags)
 			continue;
 		}
 
-		if ((flags & TEST_BRIGHTNESS) && !output_is_internal_panel(output)) {
+		if ((flags & TEST_BRIGHTNESS) && !igt_output_is_internal_panel(output)) {
 			igt_info("%s: Can't run brightness test on non-internal panel.\n",
 				 igt_output_name(output));
 			continue;
-- 
2.25.1


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

* RE: [PATCH i-g-t 3/6] lib/igt_kms: add helpers for connector type
  2025-10-15 10:17 ` [PATCH i-g-t 3/6] lib/igt_kms: add helpers for connector type Kunal Joshi
@ 2025-10-27  5:51   ` B, Jeevan
  0 siblings, 0 replies; 9+ messages in thread
From: B, Jeevan @ 2025-10-27  5:51 UTC (permalink / raw)
  To: Joshi, Kunal1, igt-dev@lists.freedesktop.org; +Cc: Joshi, Kunal1

> -----Original Message-----
> From: igt-dev <igt-dev-bounces@lists.freedesktop.org> On Behalf Of Kunal Joshi
> Sent: Wednesday, October 15, 2025 3:48 PM
> To: igt-dev@lists.freedesktop.org
> Cc: Joshi, Kunal1 <kunal1.joshi@intel.com>
> Subject: [PATCH i-g-t 3/6] lib/igt_kms: add helpers for connector type
> 
> Introduce helpers for checking output
> connector type, reuse same mechanism for output_is_internal_panel.
> 
> Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com>
> ---
>  lib/igt_kms.c                  | 74 ++++++++++++++++++++++++++++------
>  lib/igt_kms.h                  |  9 ++++-
>  tests/intel/kms_dsc_helper.c   |  2 +-
>  tests/intel/kms_pm_backlight.c |  2 +-
>  tests/kms_atomic_transition.c  |  4 +-
>  tests/kms_hdr.c                |  2 +-
>  6 files changed, 74 insertions(+), 19 deletions(-)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c index eab4cb92f..f29778f2d 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -3479,22 +3479,70 @@ igt_plane_t
> *igt_pipe_get_plane_type_index(igt_pipe_t *pipe, int plane_type,  }
> 
>  /**
> - * output_is_internal_panel:
> + * igt_output_type_in_mask - test connector type membership
> + * @output: output (may be NULL)
> + * @mask: bitmask where bit N corresponds to DRM_MODE_CONNECTOR_*
> value
> +N
> + *
> + * Returns: true if @output has a connector and its connector_type bit
> +is set
> + * in @mask. Safe for DRM_MODE_CONNECTOR_Unknown (0). If @output or its
> + * connector is NULL, returns false.
> + */
> +bool igt_output_type_in_mask(igt_output_t *output, uint64_t mask) {
> +	unsigned int type;
> +
> +	if (!output || !output->config.connector)
> +		return false;
> +
> +	type = output->config.connector->connector_type;
> +
> +	return (mask & CONNECTOR_TYPE_BIT(type)) != 0; }
> +
> +/**
> + * igt_output_is_dp_family - classify DP/eDP as DP family
> + * @output: output
> + *
> + * Returns: true if @output is DisplayPort or eDP.
> + */
> +bool igt_output_is_dp_family(igt_output_t *output) {
> +	uint64_t mask =
> +		CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_DisplayPort)
> |
> +		CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_eDP);
> +
> +	return igt_output_type_in_mask(output, mask); }
> +
> +/**
> + * igt_output_is_hdmi - classify HDMI connectors
> + * @output: output
> + *
> + * Returns: true if @output is HDMI (A or B).
> + */
> +bool igt_output_is_hdmi(igt_output_t *output) {
> +	uint64_t mask =
> +		CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_HDMIA) |
> +		CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_HDMIB);
> +
> +	return igt_output_type_in_mask(output, mask); }
> +
> +/**
> + * igt_output_is_internal_panel:
>   * @output: Target output
>   *
>   * Returns: True if the given @output type is internal else False.
>   */
> -bool output_is_internal_panel(igt_output_t *output)
> +bool igt_output_is_internal_panel(igt_output_t *output)
>  {
> -	switch (output->config.connector->connector_type) {
> -	case DRM_MODE_CONNECTOR_LVDS:
> -	case DRM_MODE_CONNECTOR_eDP:
> -	case DRM_MODE_CONNECTOR_DSI:
> -	case DRM_MODE_CONNECTOR_DPI:
> -		return true;
> -	default:
> -		return false;
> -	}
> +	uint64_t mask =
> CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_LVDS) |
> +
> 	CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_eDP)  |
> +
> 	CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_DSI)  |
> +
> 	CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_DPI);
> +
> +	return igt_output_type_in_mask(output, mask);
>  }
Code looks good, but I have one small suggestion. You could define the bitmask values once and reuse them, instead of manually composing them in each helper.

#define CONNECTOR_MASK_DP_FAMILY \
	(CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_DisplayPort) | \
	 CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_eDP))

#define CONNECTOR_MASK_HDMI \
	(CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_HDMIA) | \
	 CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_HDMIB))

#define CONNECTOR_MASK_INTERNAL_PANEL \
	(CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_LVDS) | \
	 CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_eDP)  | \
	 CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_DSI)  | \
	 CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_DPI))
> 
>  igt_output_t **__igt_pipe_populate_outputs(igt_display_t *display, igt_output_t
> **chosen_outputs) @@ -3521,7 +3569,7 @@ igt_output_t
> **__igt_pipe_populate_outputs(igt_display_t *display, igt_output_t
>  			uint32_t pipe_mask = output-
> >config.valid_crtc_idx_mask & full_pipe_mask;
>  			bool found = false;
> 
> -			if (output_is_internal_panel(output)) {
> +			if (igt_output_is_internal_panel(output)) {
>  				/*
>  				 * Internal panel should be assigned to pipe A
>  				 * if possible, so make sure they're enumerated
> @@ -3549,7 +3597,7 @@ igt_output_t
> **__igt_pipe_populate_outputs(igt_display_t *display, igt_output_t
>  					    * Overwrite internal panel if not
> assigned,
>  					    * external outputs are faster to do
> modesets
>  					    */
> -
> output_is_internal_panel(chosen_outputs[j]))
> +
> igt_output_is_internal_panel(chosen_outputs[j]))
>  					chosen_outputs[j] = output;
>  			}
> 
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h index 7121ab985..c8d394ea9 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -569,7 +569,14 @@ igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe,
> int plane_type);  int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
> igt_plane_t *igt_pipe_get_plane_type_index(igt_pipe_t *pipe, int plane_type,
>  					   int index);
> -bool output_is_internal_panel(igt_output_t *output);
> +#ifndef CONNECTOR_TYPE_BIT
> +#define CONNECTOR_TYPE_BIT(e) (1ULL << (e)) #endif
> +
> +bool igt_output_type_in_mask(igt_output_t *output, uint64_t mask); bool
> +igt_output_is_dp_family(igt_output_t *output); bool
> +igt_output_is_hdmi(igt_output_t *output); bool
> +igt_output_is_internal_panel(igt_output_t *output);
>  igt_output_t *igt_get_single_output_for_pipe(igt_display_t *display, enum pipe
> pipe);
> 
>  void igt_pipe_request_out_fence(igt_pipe_t *pipe); diff --git
> a/tests/intel/kms_dsc_helper.c b/tests/intel/kms_dsc_helper.c index
> cea4304e4..4f23c39af 100644
> --- a/tests/intel/kms_dsc_helper.c
> +++ b/tests/intel/kms_dsc_helper.c
> @@ -74,7 +74,7 @@ bool is_dsc_supported_by_sink(int drmfd, igt_output_t
> *output)
>  		return false;
>  	}
> 
> -	if (!output_is_internal_panel(output) &&
> +	if (!igt_output_is_internal_panel(output) &&
>  	    !igt_is_fec_supported(drmfd, output->name)) {
>  		igt_info("DSC cannot be enabled without FEC on %s\n",
>  			  output->name);
> diff --git a/tests/intel/kms_pm_backlight.c b/tests/intel/kms_pm_backlight.c
> index a0ecf2b0e..27c31d695 100644
> --- a/tests/intel/kms_pm_backlight.c
> +++ b/tests/intel/kms_pm_backlight.c
> @@ -239,7 +239,7 @@ igt_main
>  		igt_display_require(&display, drm_open_driver(DRIVER_INTEL |
> DRIVER_XE));
> 
>  		for_each_connected_output(&display, output) {
> -			if (!output_is_internal_panel(output))
> +			if (!igt_output_is_internal_panel(output))
>  				continue;
> 
>  			if (found)
> diff --git a/tests/kms_atomic_transition.c b/tests/kms_atomic_transition.c index
> a13830965..8e0ed9d08 100644
> --- a/tests/kms_atomic_transition.c
> +++ b/tests/kms_atomic_transition.c
> @@ -1224,11 +1224,11 @@ igt_main_args("", long_opts, help_str, opt_handler,
> &data)
>  				 * panels with long power cycle delays.
>  				 */
>  				if ((transition_tests[i].type ==
> TRANSITION_MODESET) &&
> -				    output_is_internal_panel(output))
> +				    igt_output_is_internal_panel(output))
>  					continue;
> 
>  				if ((transition_tests[i].type ==
> TRANSITION_MODESET_FAST) &&
> -				    !output_is_internal_panel(output))
> +				    !igt_output_is_internal_panel(output))
>  					continue;
> 
>  				if (pipe_count == 2 * count && !data.extended)
> diff --git a/tests/kms_hdr.c b/tests/kms_hdr.c index efa5964cf..c1c1663a2
> 100644
> --- a/tests/kms_hdr.c
> +++ b/tests/kms_hdr.c
> @@ -730,7 +730,7 @@ static void test_hdr(data_t *data, uint32_t flags)
>  			continue;
>  		}
> 
> -		if ((flags & TEST_BRIGHTNESS) &&
> !output_is_internal_panel(output)) {
> +		if ((flags & TEST_BRIGHTNESS) &&
> +!igt_output_is_internal_panel(output)) {
>  			igt_info("%s: Can't run brightness test on non-internal
> panel.\n",
>  				 igt_output_name(output));
>  			continue;
> --
> 2.25.1


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

* [PATCH i-g-t 0/6] RFC: Add new test for eDP data override
@ 2025-11-24 18:27 Jeevan B
  2025-11-24 18:27 ` [PATCH i-g-t 1/6] tests/intel/kms_dp_link_training: rename to tests/intel/kms_link_training Jeevan B
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Jeevan B @ 2025-11-24 18:27 UTC (permalink / raw)
  To: igt-dev; +Cc: kunal1.joshi, suraj.kandpal, Jeevan B

Ignore the first 4 patches as those are under review in a
different series. Since those patches are dependencies for
the last two patches, I have included them.

Please review patches 5 & 6: 

lib/igt_kms: Add helper to get eDP/DP supported link rates
tests/intel/kms_link_training: Add edp-data-override subtest

Jeevan B (2):
  lib/igt_kms: Add helper to get eDP/DP supported link rates
  RFC: tests/intel/kms_link_training: Add edp-data-override subtest

Kunal Joshi (4):
  tests/intel/kms_dp_link_training: rename to
    tests/intel/kms_link_training
  tests/intel/kms_dp_linktrain_fallback: rename to
    tests/intel/kms_linktrain_fallback
  lib/igt_kms: add helpers for connector type
  tests/intel/kms_link_training: extend test for eDP connector

 lib/igt_kms.c                                 | 126 +++-
 lib/igt_kms.h                                 |  11 +-
 tests/intel/kms_dp_linktrain_fallback.c       | 639 ------------------
 tests/intel/kms_dsc_helper.c                  |   2 +-
 ...dp_link_training.c => kms_link_training.c} | 191 +++++-
 tests/intel/kms_pm_backlight.c                |   2 +-
 tests/kms_atomic_transition.c                 |   4 +-
 tests/kms_hdr.c                               |   2 +-
 tests/meson.build                             |  16 +-
 9 files changed, 323 insertions(+), 670 deletions(-)
 delete mode 100644 tests/intel/kms_dp_linktrain_fallback.c
 rename tests/intel/{kms_dp_link_training.c => kms_link_training.c} (65%)

-- 
2.43.0


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

* [PATCH i-g-t 1/6] tests/intel/kms_dp_link_training: rename to tests/intel/kms_link_training
  2025-11-24 18:27 [PATCH i-g-t 0/6] RFC: Add new test for eDP data override Jeevan B
@ 2025-11-24 18:27 ` Jeevan B
  2025-11-24 18:27 ` [PATCH i-g-t 2/6] tests/intel/kms_dp_linktrain_fallback: rename to tests/intel/kms_linktrain_fallback Jeevan B
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Jeevan B @ 2025-11-24 18:27 UTC (permalink / raw)
  To: igt-dev; +Cc: kunal1.joshi, suraj.kandpal, Imre Deak, Arun R Murthy, Jeevan B

From: Kunal Joshi <kunal1.joshi@intel.com>

Renames kms_dp_link_training -> kms_link_training
and update meson build for compilation

Cc: Imre Deak <imre.deak@intel.com>
Cc: Arun R Murthy <arun.r.murthy@intel.com>
Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com>
Reviewed-by: Jeevan B <jeevan.b@intel.com>
---
 .../intel/{kms_dp_link_training.c => kms_link_training.c} | 0
 tests/meson.build                                         | 8 ++++----
 2 files changed, 4 insertions(+), 4 deletions(-)
 rename tests/intel/{kms_dp_link_training.c => kms_link_training.c} (100%)

diff --git a/tests/intel/kms_dp_link_training.c b/tests/intel/kms_link_training.c
similarity index 100%
rename from tests/intel/kms_dp_link_training.c
rename to tests/intel/kms_link_training.c
diff --git a/tests/meson.build b/tests/meson.build
index ecc0f4c7f..24675e61e 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -249,7 +249,6 @@ intel_kms_progs = [
 	'kms_ccs',
 	'kms_cdclk',
 	'kms_dirtyfb',
-	'kms_dp_link_training',
         'kms_dp_linktrain_fallback',
 	'kms_draw_crc',
 	'kms_dsc',
@@ -262,6 +261,7 @@ intel_kms_progs = [
 	'kms_frontbuffer_tracking',
 	'kms_joiner',
 	'kms_legacy_colorkey',
+        'kms_link_training',
 	'kms_mmap_write_crc',
 	'kms_pipe_b_c_ivb',
 	'kms_pipe_stress',
@@ -386,11 +386,11 @@ extra_sources = {
 	'kms_dp_linktrain_fallback': [
            join_paths ('intel', 'kms_mst_helper.c'),
            join_paths ('intel', 'kms_dsc_helper.c') ],
-	'kms_dp_link_training': [
-           join_paths ('intel', 'kms_mst_helper.c'),
-           join_paths ('intel', 'kms_joiner_helper.c') ],
 	'kms_dsc': [ join_paths ('intel', 'kms_dsc_helper.c') ],
 	'kms_joiner': [ join_paths ('intel', 'kms_joiner_helper.c') ],
+        'kms_link_training': [
+           join_paths ('intel', 'kms_mst_helper.c'),
+           join_paths ('intel', 'kms_joiner_helper.c') ],
 	'kms_psr2_sf':  [ join_paths ('intel', 'kms_dsc_helper.c') ],
 }
 
-- 
2.43.0


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

* [PATCH i-g-t 2/6] tests/intel/kms_dp_linktrain_fallback: rename to tests/intel/kms_linktrain_fallback
  2025-11-24 18:27 [PATCH i-g-t 0/6] RFC: Add new test for eDP data override Jeevan B
  2025-11-24 18:27 ` [PATCH i-g-t 1/6] tests/intel/kms_dp_link_training: rename to tests/intel/kms_link_training Jeevan B
@ 2025-11-24 18:27 ` Jeevan B
  2025-11-24 18:27 ` [PATCH i-g-t 3/6] lib/igt_kms: add helpers for connector type Jeevan B
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Jeevan B @ 2025-11-24 18:27 UTC (permalink / raw)
  To: igt-dev; +Cc: kunal1.joshi, suraj.kandpal, Imre Deak, Arun R Murthy, Jeevan B

From: Kunal Joshi <kunal1.joshi@intel.com>

rename kms_dp_linktrain_fallback -> kms_linktrain_fallback
and update meson build for compilation

Cc: Imre Deak <imre.deak@intel.com>
Cc: Arun R Murthy <arun.r.murthy@intel.com>
Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com>
Reviewed-by: Jeevan B <jeevan.b@intel.com>
---
 tests/intel/kms_dp_linktrain_fallback.c | 639 ------------------------
 tests/meson.build                       |   8 +-
 2 files changed, 4 insertions(+), 643 deletions(-)
 delete mode 100644 tests/intel/kms_dp_linktrain_fallback.c

diff --git a/tests/intel/kms_dp_linktrain_fallback.c b/tests/intel/kms_dp_linktrain_fallback.c
deleted file mode 100644
index 4d6740883..000000000
--- a/tests/intel/kms_dp_linktrain_fallback.c
+++ /dev/null
@@ -1,639 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2024 Intel Corporation
- */
-
-/**
- * TEST: kms dp linktrain fallback
- * Category: Display
- * Description: Test link training fallback for eDP/DP connectors
- * Driver requirement: i915, xe
- * Mega feature: General Display Features
- */
-
-#include <sys/types.h>
-#include "igt_sysfs.h"
-#include "igt.h"
-#include "kms_mst_helper.h"
-#include "kms_dsc_helper.h"
-
-/**
- * SUBTEST: dp-fallback
- * Description: Test fallback on DP connectors
- *
- * SUBTEST: dsc-fallback
- * Description: Test fallback to DSC when BW isn't sufficient
- */
-
-#define RETRAIN_COUNT 1
-/*
- * Two consecutives link training failures
- * reduces link params (link rate, lane count)
- */
-#define LT_FAILURE_REDUCED_CAPS 2
-#define SPURIOUS_HPD_RETRY 3
-
-static int traversed_mst_outputs[IGT_MAX_PIPES];
-static int traversed_mst_output_count;
-typedef struct {
-	int drm_fd;
-	igt_display_t display;
-	drmModeModeInfo *mode;
-	igt_output_t *output;
-	enum pipe pipe;
-	struct igt_fb fb;
-	struct igt_plane *primary;
-	int n_pipes;
-} data_t;
-
-typedef int (*condition_check_fn)(int drm_fd, igt_output_t *output);
-
-IGT_TEST_DESCRIPTION("Test link-training / dsc fallback");
-
-static bool setup_mst_outputs(data_t *data, igt_output_t *mst_output[],
-			      int *output_count)
-{
-	int i;
-	igt_output_t *output;
-
-	/*
-	 * Check if this is already traversed
-	 */
-	for (i = 0; i < traversed_mst_output_count; i++)
-		if (i < IGT_MAX_PIPES &&
-		    traversed_mst_outputs[i] == data->output->config.connector->connector_id)
-			return false;
-
-	igt_assert_f(igt_find_all_mst_output_in_topology(data->drm_fd, &data->display,
-							 data->output, mst_output,
-							 output_count) == 0,
-							 "Unable to find mst outputs or given output is not mst\n");
-
-	for (i = 0; i < *output_count; i++) {
-		output = mst_output[i];
-		if (traversed_mst_output_count < IGT_MAX_PIPES) {
-			traversed_mst_outputs[traversed_mst_output_count++] = output->config.connector->connector_id;
-			igt_info("Output %s is in same topology as %s\n",
-				 igt_output_name(output),
-				 igt_output_name(data->output));
-		} else {
-			igt_assert_f(false, "Unable to save traversed output\n");
-			return false;
-		}
-	}
-	return true;
-}
-
-static void setup_pipe_on_outputs(data_t *data,
-				      igt_output_t *outputs[],
-				      int *output_count)
-{
-	int i = 0;
-
-	igt_require_f(data->n_pipes >= *output_count,
-		      "Need %d pipes to assign to %d outputs\n",
-		      data->n_pipes, *output_count);
-
-	for_each_pipe(&data->display, data->pipe) {
-		if (i >= *output_count)
-			break;
-		/*
-		 * TODO: add support for modes requiring joined pipes
-		 */
-		igt_info("Setting pipe %s on output %s\n",
-			 kmstest_pipe_name(data->pipe),
-			 igt_output_name(outputs[i]));
-		igt_output_set_pipe(outputs[i++], data->pipe);
-	}
-}
-
-static void setup_modeset_on_outputs(data_t *data,
-				     igt_output_t *outputs[],
-				     int *output_count,
-				     drmModeModeInfo *mode[],
-				     struct igt_fb fb[],
-				     struct igt_plane *primary[])
-{
-	int i;
-
-	for (i = 0; i < *output_count; i++) {
-		mode[i] = igt_output_get_mode(outputs[i]);
-		igt_info("Mode %dx%d@%d on output %s\n",
-			 mode[i]->hdisplay, mode[i]->vdisplay,
-			 mode[i]->vrefresh,
-			 igt_output_name(outputs[i]));
-		primary[i] = igt_output_get_plane_type(outputs[i],
-						       DRM_PLANE_TYPE_PRIMARY);
-		igt_create_color_fb(data->drm_fd,
-				    mode[i]->hdisplay,
-				    mode[i]->vdisplay,
-				    DRM_FORMAT_XRGB8888,
-				    DRM_FORMAT_MOD_LINEAR, 0.0, 1.0, 0.0,
-				    &fb[i]);
-		igt_plane_set_fb(primary[i], &fb[i]);
-	}
-}
-
-static void set_connector_link_status_good(data_t *data, igt_output_t *outputs[],
-					   int *output_count)
-{
-	int i;
-	igt_output_t *output;
-
-        /*
-         * update the link status to good for all outputs
-         */
-        for_each_connected_output(&data->display, output)
-		for(i = 0; i < *output_count; i++)
-			if (output->id == outputs[i]->id)
-				igt_output_set_prop_value(output,
-							  IGT_CONNECTOR_LINK_STATUS,
-							  DRM_MODE_LINK_STATUS_GOOD);
-}
-
-static bool validate_modeset_for_outputs(data_t *data,
-					igt_output_t *outputs[],
-					int *output_count,
-					drmModeModeInfo *mode[],
-					struct igt_fb fb[],
-					struct igt_plane *primary[])
-{
-	igt_require_f(*output_count > 0, "Require at least 1 output\n");
-	setup_pipe_on_outputs(data, outputs, output_count);
-	igt_assert_f(igt_fit_modes_in_bw(&data->display), "Unable to fit modes in bw\n");
-	setup_modeset_on_outputs(data, outputs,
-				 output_count,
-				 mode, fb, primary);
-	return true;
-}
-
-static bool setup_outputs(data_t *data, bool is_mst,
-		      igt_output_t *outputs[],
-		      int *output_count, drmModeModeInfo *mode[],
-		      struct igt_fb fb[], struct igt_plane *primary[])
-{
-	bool ret;
-
-	*output_count = 0;
-
-	if (is_mst) {
-		ret = setup_mst_outputs(data, outputs, output_count);
-		if (!ret) {
-			igt_info("Skipping MST output %s as already tested\n",
-				 igt_output_name(data->output));
-			return false;
-		}
-	} else
-		if ((*output_count) < IGT_MAX_PIPES)
-			outputs[(*output_count)++] = data->output;
-
-	ret = validate_modeset_for_outputs(data, outputs,
-					   output_count, mode,
-					   fb, primary);
-
-	if (!ret) {
-		igt_info("Skipping output %s as valid pipe/output combo not found\n",
-			 igt_output_name(data->output));
-		return false;
-	}
-
-	igt_display_commit2(&data->display, COMMIT_ATOMIC);
-	return true;
-}
-
-static int check_condition_with_timeout(int drm_fd, igt_output_t *output,
-					condition_check_fn check_fn,
-					double interval, double timeout)
-{
-	struct timespec start_time, current_time;
-	double elapsed_time;
-
-	clock_gettime(CLOCK_MONOTONIC, &start_time);
-
-	while (1) {
-		if (check_fn(drm_fd, output) == 0)
-			return 0;
-
-		clock_gettime(CLOCK_MONOTONIC, &current_time);
-		elapsed_time = (current_time.tv_sec - start_time.tv_sec) +
-			(current_time.tv_nsec - start_time.tv_nsec) / 1e9;
-
-		if (elapsed_time >= timeout)
-			return -1;
-
-		usleep((useconds_t)(interval * 1000000));
-	}
-}
-
-/*
- * Force a link training failure followed by link retrain, then
- * block until the driver has no further pending retrain/failure.
- * Returns false if we time out waiting.
- */
-static bool force_failure_and_wait(data_t *data,
-				   igt_output_t *output,
-				   int failure_type,
-				   int retrain_count,
-				   double interval,
-				   double timeout)
-{
-	igt_force_lt_failure(data->drm_fd, output, failure_type);
-	igt_force_link_retrain(data->drm_fd, output, retrain_count);
-
-	/* Wait until there's no pending retrain */
-	if (check_condition_with_timeout(data->drm_fd, output,
-					 igt_get_dp_pending_retrain,
-					 interval, timeout)) {
-		igt_info("Timed out waiting for pending retrain\n");
-		return false;
-	}
-
-	/* Wait until there's no pending LT failures */
-	if (check_condition_with_timeout(data->drm_fd, output,
-					 igt_get_dp_pending_lt_failures,
-					 interval, timeout)) {
-		igt_info("Timed out waiting for pending LT failures\n");
-		return false;
-	}
-
-	return true;
-}
-
-/*
- * Waits for a hotplug event, then checks that the link-status is BAD.
- * Returns false if the link-status isn't BAD or no hotplug arrives in time.
- */
-static bool wait_for_hotplug_and_check_bad(int drm_fd,
-					   data_t *data,
-					   igt_output_t *output,
-					   struct udev_monitor *mon,
-					   double hotplug_timeout)
-{
-	uint32_t link_status_prop_id;
-	uint64_t link_status_value;
-	drmModePropertyPtr link_status_prop;
-
-	if (!igt_hotplug_detected(mon, hotplug_timeout)) {
-		igt_info("No hotplug event within %.2f seconds.\n", hotplug_timeout);
-		return false;
-	}
-
-	kmstest_get_property(drm_fd,
-			     output->config.connector->connector_id,
-			     DRM_MODE_OBJECT_CONNECTOR,
-			     "link-status",
-			     &link_status_prop_id, &link_status_value,
-			     &link_status_prop);
-
-	if (link_status_value != DRM_MODE_LINK_STATUS_BAD) {
-		igt_info("Expected link-status=BAD but got %" PRIu64 "\n",
-			 link_status_value);
-		return false;
-	}
-
-	return true;
-}
-
-/*
- * Sets link status=GOOD for the specified outputs, then calls
- * validate_modeset_for_outputs() to re-commit. Returns false
- * if the re-commit fails.
- */
-static bool fix_link_status_and_recommit(data_t *data,
-					 igt_output_t *outputs[],
-					 int *output_count,
-					 drmModeModeInfo * modes[],
-					 struct igt_fb fbs[],
-					 struct igt_plane *primaries[])
-{
-	int i;
-	igt_output_t *out;
-
-	/* Set link-status=GOOD on each tested output */
-	for_each_connected_output(&data->display, out) {
-		for (i = 0; i < *output_count; i++) {
-			if (out->id == outputs[i]->id) {
-				igt_output_set_prop_value(
-					out, IGT_CONNECTOR_LINK_STATUS,
-					DRM_MODE_LINK_STATUS_GOOD);
-			}
-		}
-	}
-
-	if (!validate_modeset_for_outputs(data, outputs, output_count,
-					  modes, fbs, primaries)) {
-		igt_info("Modeset validation failed after forcing link-status=GOOD\n");
-		return false;
-	}
-
-	if (igt_display_try_commit_atomic(&data->display,
-					  DRM_MODE_ATOMIC_ALLOW_MODESET,
-					  NULL) != 0) {
-		igt_info("Commit failed after restoring link-status=GOOD\n");
-		return false;
-	}
-
-	return true;
-}
-
-static void test_fallback(data_t *data, bool is_mst)
-{
-	int output_count, retries;
-	int max_link_rate, curr_link_rate, prev_link_rate;
-	int max_lane_count, curr_lane_count, prev_lane_count;
-	igt_output_t *outputs[IGT_MAX_PIPES];
-	drmModeModeInfo * modes[IGT_MAX_PIPES];
-	struct igt_fb fbs[IGT_MAX_PIPES];
-	struct igt_plane *primaries[IGT_MAX_PIPES];
-	struct udev_monitor *mon;
-
-	retries = SPURIOUS_HPD_RETRY;
-
-	igt_display_reset(&data->display);
-	igt_reset_link_params(data->drm_fd, data->output);
-	if (!setup_outputs(data, is_mst, outputs,
-			   &output_count, modes, fbs,
-			   primaries))
-		return;
-
-	igt_info("Testing link training fallback on %s\n",
-		 igt_output_name(data->output));
-	max_link_rate = igt_get_max_link_rate(data->drm_fd, data->output);
-	max_lane_count = igt_get_max_lane_count(data->drm_fd, data->output);
-	prev_link_rate = igt_get_current_link_rate(data->drm_fd, data->output);
-	prev_lane_count = igt_get_current_lane_count(data->drm_fd, data->output);
-
-	while (!igt_get_dp_link_retrain_disabled(data->drm_fd,
-						 data->output)) {
-		igt_info("Current link rate: %d, Current lane count: %d\n",
-			 prev_link_rate,
-			 prev_lane_count);
-		mon = igt_watch_uevents();
-
-		igt_assert_f(force_failure_and_wait(data, data->output,
-						    LT_FAILURE_REDUCED_CAPS,
-						    RETRAIN_COUNT,
-						    1.0, 20.0),
-						    "Link training failure steps timed out\n");
-
-		if (igt_get_dp_link_retrain_disabled(data->drm_fd,
-						     data->output)) {
-			igt_reset_connectors();
-			return;
-		}
-
-		igt_assert_f(wait_for_hotplug_and_check_bad(data->drm_fd,
-							    data,
-							    data->output,
-							    mon,
-							    20.0), "Didn't get hotplug or link status != BAD\n");
-
-		igt_flush_uevents(mon);
-		set_connector_link_status_good(data, outputs, &output_count);
-		igt_assert_f(fix_link_status_and_recommit(data,
-							  outputs,
-							  &output_count,
-							  modes,
-							  fbs,
-							  primaries), "modeset failed\n");
-		igt_assert_eq(data->output->values[IGT_CONNECTOR_LINK_STATUS], DRM_MODE_LINK_STATUS_GOOD);
-		curr_link_rate = igt_get_current_link_rate(data->drm_fd, data->output);
-		curr_lane_count = igt_get_current_lane_count(data->drm_fd, data->output);
-
-		igt_debug("Fallback state: prev %dx%d, curr %dx%d, max %dx%d, retries=%u\n",
-			  prev_link_rate, prev_lane_count,
-			  curr_link_rate, curr_lane_count,
-			  max_link_rate,  max_lane_count,
-			  retries);
-		igt_assert_f((curr_link_rate < prev_link_rate ||
-			     curr_lane_count < prev_lane_count) ||
-			     ((curr_link_rate == max_link_rate && curr_lane_count == max_lane_count) && --retries),
-			     "Fallback unsuccessful\n");
-
-		prev_link_rate = curr_link_rate;
-		prev_lane_count = curr_lane_count;
-	}
-}
-
-static bool run_lt_fallback_test(data_t *data)
-{
-	bool ran = false;
-	igt_output_t *output;
-
-	for_each_connected_output(&data->display, output) {
-		data->output = output;
-
-		if (!igt_has_force_link_training_failure_debugfs(data->drm_fd,
-								 data->output)) {
-			igt_info("Output %s doesn't support forcing link training failure\n",
-				 igt_output_name(data->output));
-			continue;
-		}
-
-		if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) {
-			igt_info("Skipping output %s as it's not DP\n", output->name);
-				continue;
-		}
-
-		ran = true;
-
-		/*
-		 * Check output is MST
-		 */
-		if (igt_check_output_is_dp_mst(data->output)) {
-			igt_info("Testing MST output %s\n",
-				 igt_output_name(data->output));
-			test_fallback(data, true);
-		} else {
-			igt_info("Testing DP output %s\n",
-				 igt_output_name(data->output));
-			test_fallback(data, false);
-		}
-	}
-	return ran;
-}
-
-static void test_dsc_sst_fallback(data_t *data)
-{
-	bool non_dsc_mode_found = false;
-	bool dsc_fallback_successful = false;
-	int ret;
-	struct udev_monitor *mon;
-	drmModeModeInfo *mode_to_check;
-	igt_output_t *outputs[IGT_MAX_PIPES];
-	int output_count = 0;
-
-	igt_info("Checking DSC fallback on %s\n", igt_output_name(data->output));
-	data->pipe = PIPE_A;
-
-	igt_display_reset(&data->display);
-	igt_reset_link_params(data->drm_fd, data->output);
-	igt_force_link_retrain(data->drm_fd, data->output, RETRAIN_COUNT);
-
-	/* Find a mode that doesn't require DSC initially */
-	for_each_connector_mode(data->output) {
-		data->mode = &data->output->config.connector->modes[j__];
-		igt_create_color_fb(data->drm_fd, data->mode->hdisplay,
-				    data->mode->vdisplay, DRM_FORMAT_XRGB8888,
-				    DRM_FORMAT_MOD_LINEAR, 0.0, 1.0, 0.0,
-				    &data->fb);
-		igt_output_override_mode(data->output, data->mode);
-		igt_output_set_pipe(data->output, data->pipe);
-		data->primary = igt_output_get_plane_type(data->output,
-						DRM_PLANE_TYPE_PRIMARY);
-		igt_plane_set_fb(data->primary, &data->fb);
-
-		ret = igt_display_try_commit_atomic(&data->display,
-						    DRM_MODE_ATOMIC_TEST_ONLY |
-						    DRM_MODE_ATOMIC_ALLOW_MODESET,
-						    NULL);
-		if (ret != 0) {
-			igt_debug("Skipping mode %dx%d@%d on %s\n",
-				 data->mode->hdisplay, data->mode->vdisplay,
-				 data->mode->vrefresh,
-				 igt_output_name(data->output));
-			continue;
-		}
-		igt_display_commit2(&data->display, COMMIT_ATOMIC);
-
-		if (!igt_is_dsc_enabled(data->drm_fd,
-					data->output->name)) {
-			drmModeModeInfo *non_dsc_mode
-				= igt_output_get_mode(data->output);
-			igt_info("Found mode %dx%d@%d %s that doesn't need DSC with link rate %d and lane count %d\n",
-				 non_dsc_mode->hdisplay, non_dsc_mode->vdisplay,
-				 non_dsc_mode->vrefresh, non_dsc_mode->name,
-				 igt_get_current_link_rate(data->drm_fd, data->output),
-				 igt_get_current_lane_count(data->drm_fd, data->output));
-			non_dsc_mode_found = true;
-			break;
-		}
-	}
-	igt_require_f(non_dsc_mode_found,
-		      "No non-DSC mode found on %s\n",
-		      igt_output_name(data->output));
-
-	/* Repeatedly force link failure until DSC is required (or link is disabled) */
-	while (!igt_get_dp_link_retrain_disabled(data->drm_fd, data->output)) {
-		mon = igt_watch_uevents();
-
-		igt_assert_f(force_failure_and_wait(data, data->output,
-						    LT_FAILURE_REDUCED_CAPS,
-						    RETRAIN_COUNT, 1.0, 20.0),
-			     "Forcing DSC fallback timed out\n");
-
-		if (igt_get_dp_link_retrain_disabled(data->drm_fd,
-						     data->output)) {
-			igt_reset_connectors();
-			igt_flush_uevents(mon);
-			return;
-		}
-
-		igt_assert_f(wait_for_hotplug_and_check_bad(data->drm_fd,
-							    data,
-							    data->output,
-							    mon,
-							    20.0),
-			     "Didn't get hotplug or link-status=BAD for DSC\n");
-		igt_flush_uevents(mon);
-
-		outputs[output_count++] = data->output;
-		set_connector_link_status_good(data, outputs, &output_count);
-		igt_display_commit2(&data->display, COMMIT_ATOMIC);
-
-		mode_to_check = igt_output_get_mode(data->output);
-
-		if (igt_is_dsc_enabled(data->drm_fd, data->output->name)) {
-			igt_info("mode %dx%d@%d now requires DSC with link rate %d and lane count %d\n",
-				 mode_to_check->hdisplay, mode_to_check->vdisplay,
-				 mode_to_check->vrefresh,
-				 igt_get_current_link_rate(data->drm_fd, data->output),
-				 igt_get_current_lane_count(data->drm_fd, data->output));
-			igt_info("DSC fallback successful on %s\n",
-				 igt_output_name(data->output));
-			dsc_fallback_successful = true;
-			break;
-		} else {
-			igt_info("mode %dx%d@%d still doesn't require DSC\n",
-				 mode_to_check->hdisplay, mode_to_check->vdisplay,
-				 mode_to_check->vrefresh);
-		}
-	}
-	igt_assert_f(dsc_fallback_successful, "DSC fallback unsuccessful\n");
-}
-
-static bool run_dsc_sst_fallaback_test(data_t *data)
-{
-	bool ran = false;
-	igt_output_t *output;
-
-	if (!is_dsc_supported_by_source(data->drm_fd)) {
-		igt_info("DSC not supported by source.\n");
-		return ran;
-	}
-
-	for_each_connected_output(&data->display, output) {
-		data->output = output;
-
-		if (!igt_has_force_link_training_failure_debugfs(data->drm_fd,
-								 data->output)) {
-			igt_info("Output %s doesn't support forcing link training.\n",
-				 igt_output_name(data->output));
-			continue;
-		}
-
-		if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) {
-			igt_info("Skipping output %s as it's not DP\n", output->name);
-			continue;
-		}
-
-		if (!is_dsc_supported_by_sink(data->drm_fd, data->output))
-			continue;
-
-		ran = true;
-		test_dsc_sst_fallback(data);
-	}
-
-	return ran;
-}
-
-igt_main
-{
-	data_t data = {};
-
-	igt_fixture {
-		unsigned int debug_mask_if_ci = DRM_UT_KMS;
-		data.drm_fd = drm_open_driver_master(DRIVER_INTEL |
-						     DRIVER_XE);
-		kmstest_set_vt_graphics_mode();
-		igt_display_require(&data.display, data.drm_fd);
-		igt_display_require_output(&data.display);
-		for_each_pipe(&data.display, data.pipe)
-			data.n_pipes++;
-		igt_install_exit_handler(igt_drm_debug_mask_reset_exit_handler);
-		update_debug_mask_if_ci(debug_mask_if_ci);
-
-		/*
-		 * Some environments may have environment
-		 * variable set to ignore long hpd, disable it for this test
-		 */
-		igt_assert_f(igt_ignore_long_hpd(data.drm_fd, false),
-			     "Unable to disable ignore long hpd\n");
-	}
-
-	igt_subtest("dp-fallback") {
-		igt_require_f(run_lt_fallback_test(&data),
-			      "Skipping test as no output found or none supports fallback\n");
-	}
-
-	igt_subtest("dsc-fallback") {
-		igt_require_f(run_dsc_sst_fallaback_test(&data),
-			      "Skipping test as DSC fallback conditions not met.\n");
-	}
-
-	igt_fixture {
-		igt_remove_fb(data.drm_fd, &data.fb);
-		igt_display_fini(&data.display);
-		close(data.drm_fd);
-	}
-}
diff --git a/tests/meson.build b/tests/meson.build
index 24675e61e..e004036c8 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -249,7 +249,6 @@ intel_kms_progs = [
 	'kms_ccs',
 	'kms_cdclk',
 	'kms_dirtyfb',
-        'kms_dp_linktrain_fallback',
 	'kms_draw_crc',
 	'kms_dsc',
 	'kms_fb_coherency',
@@ -262,6 +261,7 @@ intel_kms_progs = [
 	'kms_joiner',
 	'kms_legacy_colorkey',
         'kms_link_training',
+        'kms_linktrain_fallback',
 	'kms_mmap_write_crc',
 	'kms_pipe_b_c_ivb',
 	'kms_pipe_stress',
@@ -383,14 +383,14 @@ extra_sources = {
 	'kms_chamelium_frames': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ],
 	'kms_chamelium_hpd': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ],
 	'kms_chamelium_sharpness_filter': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ],
-	'kms_dp_linktrain_fallback': [
-           join_paths ('intel', 'kms_mst_helper.c'),
-           join_paths ('intel', 'kms_dsc_helper.c') ],
 	'kms_dsc': [ join_paths ('intel', 'kms_dsc_helper.c') ],
 	'kms_joiner': [ join_paths ('intel', 'kms_joiner_helper.c') ],
         'kms_link_training': [
            join_paths ('intel', 'kms_mst_helper.c'),
            join_paths ('intel', 'kms_joiner_helper.c') ],
+        'kms_linktrain_fallback': [
+           join_paths ('intel', 'kms_mst_helper.c'),
+           join_paths ('intel', 'kms_dsc_helper.c') ],
 	'kms_psr2_sf':  [ join_paths ('intel', 'kms_dsc_helper.c') ],
 }
 
-- 
2.43.0


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

* [PATCH i-g-t 3/6] lib/igt_kms: add helpers for connector type
  2025-11-24 18:27 [PATCH i-g-t 0/6] RFC: Add new test for eDP data override Jeevan B
  2025-11-24 18:27 ` [PATCH i-g-t 1/6] tests/intel/kms_dp_link_training: rename to tests/intel/kms_link_training Jeevan B
  2025-11-24 18:27 ` [PATCH i-g-t 2/6] tests/intel/kms_dp_linktrain_fallback: rename to tests/intel/kms_linktrain_fallback Jeevan B
@ 2025-11-24 18:27 ` Jeevan B
  2025-11-24 18:27 ` [PATCH i-g-t 4/6] tests/intel/kms_link_training: extend test for eDP connector Jeevan B
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Jeevan B @ 2025-11-24 18:27 UTC (permalink / raw)
  To: igt-dev; +Cc: kunal1.joshi, suraj.kandpal

From: Kunal Joshi <kunal1.joshi@intel.com>

Introduce helpers for checking output
connector type, reuse same mechanism for
output_is_internal_panel.

Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com>
---
 lib/igt_kms.c                  | 74 ++++++++++++++++++++++++++++------
 lib/igt_kms.h                  |  9 ++++-
 tests/intel/kms_dsc_helper.c   |  2 +-
 tests/intel/kms_pm_backlight.c |  2 +-
 tests/kms_atomic_transition.c  |  4 +-
 tests/kms_hdr.c                |  2 +-
 6 files changed, 74 insertions(+), 19 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 8973ffdb2..c03cfed09 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -3501,22 +3501,70 @@ igt_plane_t *igt_pipe_get_plane_type_index(igt_pipe_t *pipe, int plane_type,
 }
 
 /**
- * output_is_internal_panel:
+ * igt_output_type_in_mask - test connector type membership
+ * @output: output (may be NULL)
+ * @mask: bitmask where bit N corresponds to DRM_MODE_CONNECTOR_* value N
+ *
+ * Returns: true if @output has a connector and its connector_type bit is set
+ * in @mask. Safe for DRM_MODE_CONNECTOR_Unknown (0). If @output or its
+ * connector is NULL, returns false.
+ */
+bool igt_output_type_in_mask(igt_output_t *output, uint64_t mask)
+{
+	unsigned int type;
+
+	if (!output || !output->config.connector)
+		return false;
+
+	type = output->config.connector->connector_type;
+
+	return (mask & CONNECTOR_TYPE_BIT(type)) != 0;
+}
+
+/**
+ * igt_output_is_dp_family - classify DP/eDP as DP family
+ * @output: output
+ *
+ * Returns: true if @output is DisplayPort or eDP.
+ */
+bool igt_output_is_dp_family(igt_output_t *output)
+{
+	uint64_t mask =
+		CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_DisplayPort) |
+		CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_eDP);
+
+	return igt_output_type_in_mask(output, mask);
+}
+
+/**
+ * igt_output_is_hdmi - classify HDMI connectors
+ * @output: output
+ *
+ * Returns: true if @output is HDMI (A or B).
+ */
+bool igt_output_is_hdmi(igt_output_t *output)
+{
+	uint64_t mask =
+		CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_HDMIA) |
+		CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_HDMIB);
+
+	return igt_output_type_in_mask(output, mask);
+}
+
+/**
+ * igt_output_is_internal_panel:
  * @output: Target output
  *
  * Returns: True if the given @output type is internal else False.
  */
-bool output_is_internal_panel(igt_output_t *output)
+bool igt_output_is_internal_panel(igt_output_t *output)
 {
-	switch (output->config.connector->connector_type) {
-	case DRM_MODE_CONNECTOR_LVDS:
-	case DRM_MODE_CONNECTOR_eDP:
-	case DRM_MODE_CONNECTOR_DSI:
-	case DRM_MODE_CONNECTOR_DPI:
-		return true;
-	default:
-		return false;
-	}
+	uint64_t mask = CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_LVDS) |
+			CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_eDP)  |
+			CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_DSI)  |
+			CONNECTOR_TYPE_BIT(DRM_MODE_CONNECTOR_DPI);
+
+	return igt_output_type_in_mask(output, mask);
 }
 
 igt_output_t **__igt_pipe_populate_outputs(igt_display_t *display, igt_output_t **chosen_outputs)
@@ -3543,7 +3591,7 @@ igt_output_t **__igt_pipe_populate_outputs(igt_display_t *display, igt_output_t
 			uint32_t pipe_mask = output->config.valid_crtc_idx_mask & full_pipe_mask;
 			bool found = false;
 
-			if (output_is_internal_panel(output)) {
+			if (igt_output_is_internal_panel(output)) {
 				/*
 				 * Internal panel should be assigned to pipe A
 				 * if possible, so make sure they're enumerated
@@ -3571,7 +3619,7 @@ igt_output_t **__igt_pipe_populate_outputs(igt_display_t *display, igt_output_t
 					    * Overwrite internal panel if not assigned,
 					    * external outputs are faster to do modesets
 					    */
-					   output_is_internal_panel(chosen_outputs[j]))
+					   igt_output_is_internal_panel(chosen_outputs[j]))
 					chosen_outputs[j] = output;
 			}
 
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index f7ff0b17e..cd9f6840a 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -578,7 +578,14 @@ igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
 int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
 igt_plane_t *igt_pipe_get_plane_type_index(igt_pipe_t *pipe, int plane_type,
 					   int index);
-bool output_is_internal_panel(igt_output_t *output);
+#ifndef CONNECTOR_TYPE_BIT
+#define CONNECTOR_TYPE_BIT(e) (1ULL << (e))
+#endif
+
+bool igt_output_type_in_mask(igt_output_t *output, uint64_t mask);
+bool igt_output_is_dp_family(igt_output_t *output);
+bool igt_output_is_hdmi(igt_output_t *output);
+bool igt_output_is_internal_panel(igt_output_t *output);
 igt_output_t *igt_get_single_output_for_pipe(igt_display_t *display, enum pipe pipe);
 
 void igt_pipe_request_out_fence(igt_pipe_t *pipe);
diff --git a/tests/intel/kms_dsc_helper.c b/tests/intel/kms_dsc_helper.c
index cea4304e4..4f23c39af 100644
--- a/tests/intel/kms_dsc_helper.c
+++ b/tests/intel/kms_dsc_helper.c
@@ -74,7 +74,7 @@ bool is_dsc_supported_by_sink(int drmfd, igt_output_t *output)
 		return false;
 	}
 
-	if (!output_is_internal_panel(output) &&
+	if (!igt_output_is_internal_panel(output) &&
 	    !igt_is_fec_supported(drmfd, output->name)) {
 		igt_info("DSC cannot be enabled without FEC on %s\n",
 			  output->name);
diff --git a/tests/intel/kms_pm_backlight.c b/tests/intel/kms_pm_backlight.c
index a0ecf2b0e..27c31d695 100644
--- a/tests/intel/kms_pm_backlight.c
+++ b/tests/intel/kms_pm_backlight.c
@@ -239,7 +239,7 @@ igt_main
 		igt_display_require(&display, drm_open_driver(DRIVER_INTEL | DRIVER_XE));
 
 		for_each_connected_output(&display, output) {
-			if (!output_is_internal_panel(output))
+			if (!igt_output_is_internal_panel(output))
 				continue;
 
 			if (found)
diff --git a/tests/kms_atomic_transition.c b/tests/kms_atomic_transition.c
index 419afe4dd..f97fc000d 100644
--- a/tests/kms_atomic_transition.c
+++ b/tests/kms_atomic_transition.c
@@ -1225,11 +1225,11 @@ igt_main_args("", long_opts, help_str, opt_handler, &data)
 				 * panels with long power cycle delays.
 				 */
 				if ((transition_tests[i].type == TRANSITION_MODESET) &&
-				    output_is_internal_panel(output))
+				    igt_output_is_internal_panel(output))
 					continue;
 
 				if ((transition_tests[i].type == TRANSITION_MODESET_FAST) &&
-				    !output_is_internal_panel(output))
+				    !igt_output_is_internal_panel(output))
 					continue;
 
 				if (pipe_count == 2 * count && !data.extended)
diff --git a/tests/kms_hdr.c b/tests/kms_hdr.c
index 40187275b..3a931ac9e 100644
--- a/tests/kms_hdr.c
+++ b/tests/kms_hdr.c
@@ -734,7 +734,7 @@ static void test_hdr(data_t *data, uint32_t flags)
 			continue;
 		}
 
-		if ((flags & TEST_BRIGHTNESS) && !output_is_internal_panel(output)) {
+		if ((flags & TEST_BRIGHTNESS) && !igt_output_is_internal_panel(output)) {
 			igt_info("%s: Can't run brightness test on non-internal panel.\n",
 				 igt_output_name(output));
 			continue;
-- 
2.43.0


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

* [PATCH i-g-t 4/6] tests/intel/kms_link_training: extend test for eDP connector
  2025-11-24 18:27 [PATCH i-g-t 0/6] RFC: Add new test for eDP data override Jeevan B
                   ` (2 preceding siblings ...)
  2025-11-24 18:27 ` [PATCH i-g-t 3/6] lib/igt_kms: add helpers for connector type Jeevan B
@ 2025-11-24 18:27 ` Jeevan B
  2025-11-24 18:27 ` [PATCH i-g-t 5/6] lib/igt_kms: Add helper to get eDP/DP supported link rates Jeevan B
  2025-11-24 18:27 ` [PATCH i-g-t 6/6] RFC: tests/intel/kms_link_training: Add edp-data-override subtest Jeevan B
  5 siblings, 0 replies; 9+ messages in thread
From: Jeevan B @ 2025-11-24 18:27 UTC (permalink / raw)
  To: igt-dev; +Cc: kunal1.joshi, suraj.kandpal, Imre Deak, Arun R Murthy, Jeevan B

From: Kunal Joshi <kunal1.joshi@intel.com>

Extend kms_link_training test for eDP connector.
non-uhbr-sst subtest expected to and skip
expected for rest of the subtest as of now.

v2: use helper for eDP/DP check (Jeevan)

Cc: Imre Deak <imre.deak@intel.com>
Cc: Arun R Murthy <arun.r.murthy@intel.com>
Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com>
Reviewed-by: Jeevan B <jeevan.b@intel.com>
---
 tests/intel/kms_link_training.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/tests/intel/kms_link_training.c b/tests/intel/kms_link_training.c
index fb9b42608..4ddbd72f8 100644
--- a/tests/intel/kms_link_training.c
+++ b/tests/intel/kms_link_training.c
@@ -266,10 +266,8 @@ static bool test_link_rate(data_t *data, bool mst, bool uhbr)
 		      "Test supported only on Intel platforms.\n");
 
 	for_each_connected_output(&data->display, tmp_output) {
-		if (tmp_output->config.connector->connector_type !=
-		    DRM_MODE_CONNECTOR_DisplayPort) {
-			igt_info("Skipping non-DisplayPort output %s\n",
-					tmp_output->name);
+		if (!igt_output_is_dp_family(tmp_output)) {
+			igt_info("Skipping non-DisplayPort output %s\n", tmp_output->name);
 			igt_info("----------------------------------------------------\n");
 			continue;
 		}
-- 
2.43.0


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

* [PATCH i-g-t 5/6] lib/igt_kms: Add helper to get eDP/DP supported link rates
  2025-11-24 18:27 [PATCH i-g-t 0/6] RFC: Add new test for eDP data override Jeevan B
                   ` (3 preceding siblings ...)
  2025-11-24 18:27 ` [PATCH i-g-t 4/6] tests/intel/kms_link_training: extend test for eDP connector Jeevan B
@ 2025-11-24 18:27 ` Jeevan B
  2025-11-24 18:27 ` [PATCH i-g-t 6/6] RFC: tests/intel/kms_link_training: Add edp-data-override subtest Jeevan B
  5 siblings, 0 replies; 9+ messages in thread
From: Jeevan B @ 2025-11-24 18:27 UTC (permalink / raw)
  To: igt-dev; +Cc: kunal1.joshi, suraj.kandpal, Jeevan B

Add igt_get_supported_link_rates to parse debugfs and return available
eDP/DP link rates for a given connector.

Signed-off-by: Jeevan B <jeevan.b@intel.com>
---
 lib/igt_kms.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_kms.h |  2 ++
 2 files changed, 54 insertions(+)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index c03cfed09..4071aa00a 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -7632,3 +7632,55 @@ bool igt_has_lobf_debugfs(int drmfd, igt_output_t *output)
                                               buf, sizeof(buf));
         return res == 0;
 }
+
+/**
+ * igt_get_supported_link_rates:
+ * @drmfd: A drm file descriptor
+ * @connector_name: Name of the libdrm connector we're going to use
+ *
+ * Returns: All the link rates supported by the connector
+ */
+int igt_get_supported_link_rates(int drmfd, char *connector_name,
+		       int *rates, int max_rates)
+{
+	char buf[48];
+	int fd, res;
+	int count = 0;
+	char *token, *star;
+
+	if (!rates || max_rates <= 0) {
+		return -1;
+        }
+
+	fd = igt_debugfs_connector_dir(drmfd, connector_name, O_RDONLY);
+	igt_assert_lte(0, fd);
+
+	res = igt_debugfs_simple_read(fd, "i915_dp_force_link_rate", buf, sizeof(buf));
+	igt_require(res > 0);
+
+	igt_require_f(res > 0,
+		      "Unable to read i915_dp_force_link_rate for %s\n",
+		      connector_name);
+
+	buf[res] = '\0'; /* Null terminate */
+	token = strtok(buf, " \t\n");
+
+	while (token && count < max_rates) {
+		if (!strcmp(token, "[auto]")) {
+			token = strtok(NULL, " \t\n");
+			continue;
+		}
+
+		star = strchr(token, '*');
+		if (star)
+			*star = '\0';
+
+		if (isdigit(token[0])) {
+			rates[count++] = atoi(token);
+		}
+
+		token = strtok(NULL, " \t\n");
+	}
+
+	return count;
+}
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index cd9f6840a..474a809ea 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -1303,6 +1303,8 @@ void igt_set_link_params(int drm_fd, igt_output_t *output,
 int igt_backlight_read(int *result, const char *fname, igt_backlight_context_t *context);
 int igt_backlight_write(int value, const char *fname, igt_backlight_context_t *context);
 uint32_t igt_get_connected_output_count(igt_display_t *display);
+int igt_get_supported_link_rates(int drmfd, char *connector_name, int *rates,
+				 int max_rates);
 
 drmModePropertyBlobRes *igt_get_writeback_formats_blob(igt_output_t *output);
 
-- 
2.43.0


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

* [PATCH i-g-t 6/6] RFC: tests/intel/kms_link_training: Add edp-data-override subtest
  2025-11-24 18:27 [PATCH i-g-t 0/6] RFC: Add new test for eDP data override Jeevan B
                   ` (4 preceding siblings ...)
  2025-11-24 18:27 ` [PATCH i-g-t 5/6] lib/igt_kms: Add helper to get eDP/DP supported link rates Jeevan B
@ 2025-11-24 18:27 ` Jeevan B
  5 siblings, 0 replies; 9+ messages in thread
From: Jeevan B @ 2025-11-24 18:27 UTC (permalink / raw)
  To: igt-dev; +Cc: kunal1.joshi, suraj.kandpal, Jeevan B

Add test for eDP data override for 2.43 and 6.75 Gbps which has
some issues. eDP should overide to 2.7 and 8.1 Gbps when supported
by panel.

Signed-off-by: Jeevan B <jeevan.b@intel.com>
Link: https://lore.kernel.org/r/20250821042653.269227-3-suraj.kandpal@intel.com
---
 tests/intel/kms_link_training.c | 185 ++++++++++++++++++++++++++++++++
 1 file changed, 185 insertions(+)

diff --git a/tests/intel/kms_link_training.c b/tests/intel/kms_link_training.c
index 4ddbd72f8..22c4c9fd3 100644
--- a/tests/intel/kms_link_training.c
+++ b/tests/intel/kms_link_training.c
@@ -19,6 +19,9 @@
  *
  * SUBTEST: non-uhbr-mst
  * Description: Test we can drive non-UHBR rates over MST.
+ *
+ * SUBTEST: edp-data-override
+ * Description: Test eDP data override rates.
  */
 
 #include "igt.h"
@@ -293,6 +296,180 @@ static bool test_link_rate(data_t *data, bool mst, bool uhbr)
 	return ran_any_output;
 }
 
+static bool test_link_override(data_t *data, int target_rate, const char *rate_name,
+		    bool expect_success, int timeout_sec)
+{
+	char rate_str[32];
+	char lane_str[32];
+	int current_rate;
+	bool training_completed;
+
+	igt_info("Testing %s (%d kHz) - expect %s...\n",
+		 rate_name, target_rate, expect_success ? "SUCCESS" : "BLOCK/FAIL");
+
+	igt_display_reset(&data->display);
+	igt_reset_link_params(data->drm_fd, data->output);
+	do_modeset(data, false);
+
+	snprintf(rate_str, sizeof(rate_str), "%d", target_rate);
+	snprintf(lane_str, sizeof(lane_str), "4");
+	igt_set_link_params(data->drm_fd, data->output, rate_str, lane_str);
+	igt_force_link_retrain(data->drm_fd, data->output, RETRAIN_COUNT);
+
+	training_completed = (check_condition_with_timeout(data->drm_fd, data->output,
+							   igt_get_dp_pending_retrain,
+							   1.0, timeout_sec) == 0);
+
+	if (training_completed) {
+		current_rate = igt_get_current_link_rate(data->drm_fd, data->output);
+		assert_link_status_good(data, false);
+
+		if (expect_success) {
+			if (current_rate == target_rate) {
+				igt_info("%s succeeded at %d kHz\n", rate_name, current_rate);
+				return true;
+			} else {
+				igt_info("%s failed: requested %d kHz, got %d kHz\n",
+					 rate_name, target_rate, current_rate);
+				return false;
+			}
+		} else {
+			if (current_rate != target_rate) {
+				igt_info("%s blocked: requested %d kHz, fell back to %d kHz\n",
+					 rate_name, target_rate, current_rate);
+				return true;
+			} else {
+				igt_info("%s was NOT blocked: got requested %d kHz\n",
+					  rate_name, current_rate);
+				return false;
+			}
+		}
+	} else {
+		if (expect_success) {
+			igt_info("%s failed with timeout\n", rate_name);
+			return false;
+		} else {
+			igt_info("%s completely rejected (timeout)\n", rate_name);
+			return true;
+		}
+	}
+}
+
+static void analyze_supported_rates(int *rates, int num_rates,
+				   bool *found_243, bool *found_675,
+				   bool *found_270, bool *found_810)
+{
+	int i;
+
+	*found_243 = false;
+	*found_675 = false;
+	*found_270 = false;
+	*found_810 = false;
+
+	for (i = 0; i < num_rates; i++) {
+		igt_info("  %d kHz (%.2f Gbps)",
+			 rates[i], rates[i] / 100000.0);
+
+		switch (rates[i]) {
+			case 243000:
+				*found_243 = true;
+				igt_info("Unsupported!");
+				break;
+			case 675000:
+				*found_675 = true;
+				igt_info("Unsupported!");
+				break;
+			case 270000:
+				*found_270 = true;
+				igt_info("Supported");
+				break;
+			case 810000:
+				*found_810 = true;
+				igt_info("Supported");
+				break;
+                }
+		igt_info("\n");
+	}
+}
+
+static bool test_edp_data_override(data_t *data)
+{
+	igt_output_t *edp_output = NULL;
+	int supported_rates[16];
+	int num_rates = 0;
+	bool found_243, found_675, found_270, found_810;
+	bool test_results[4] = {false};
+	bool data_override_works, safe_rates_available;
+	bool all_tests_passed;
+
+	igt_skip_on_f(!is_intel_device(data->drm_fd),
+		      "Test supported only on Intel platforms.\n");
+
+	for_each_connected_output(&data->display, edp_output) {
+		if (igt_output_is_dp_family(edp_output) &&
+		    strstr(edp_output->name, "eDP")) {
+			data->output = edp_output;
+			break;
+		}
+	}
+
+	igt_require_f(data->output != NULL, "No eDP output found\n");
+	igt_info("Testing eDP data override on: %s\n", data->output->name);
+
+	num_rates = igt_get_supported_link_rates(data->drm_fd, data->output->name,
+						 supported_rates, 16);
+	igt_assert_f(num_rates >= 2 && num_rates <= 10,
+		     "Unexpected number of rates (%d), data override might be broken\n", num_rates);
+
+	analyze_supported_rates(supported_rates, num_rates,
+				&found_243, &found_675, &found_270, &found_810);
+
+	igt_info("PHASE 1: Testing Unsupported rates (expect override/blocking)\n");
+
+	if (found_243)
+		test_results[0] = test_link_override(data, 243000, "2.43 Gbps Override rate",
+						     false, 10);
+
+	if (found_675)
+		test_results[1] = test_link_override(data, 675000, "6.75 Gbps Override rate",
+						 false, 10);
+
+	igt_info("PHASE 2: Testing Supported rates\n");
+
+	if (found_270) {
+		test_results[2] = test_link_override(data, 270000, "2.7 Gbps data rate",
+						 true, 10);
+	} else {
+		igt_info("Skipping 2.7 Gbps test - not available\n");
+		test_results[2] = true;
+	}
+
+	if (found_810) {
+		test_results[3] = test_link_override(data, 810000, "8.1 Gbps data rate",
+						 true, 10);
+	} else {
+		igt_info("Skipping 8.1 Gbps test - not available\n");
+		test_results[3] = true;
+	}
+
+	igt_reset_link_params(data->drm_fd, data->output);
+
+	data_override_works = (!found_243 && !found_675);
+	safe_rates_available = (found_270 || found_810);
+	all_tests_passed = (test_results[0] && test_results[1] &&
+				 test_results[2] && test_results[3]);
+
+	igt_info("====================================================\n");
+	igt_info("eDP data override working: %s\n", data_override_works ? "YES" : "NO");
+	igt_info("Safe override rates available: %s\n", safe_rates_available ? "YES" : "NO");
+	igt_info("All rate tests passed: %s\n", all_tests_passed ? "YES" : "NO");
+	igt_info("Overall test result: %s\n",
+		 (data_override_works && safe_rates_available && all_tests_passed) ?
+		 "SUCCESS" : "FAIL");
+
+	return (data_override_works && safe_rates_available && all_tests_passed);
+}
+
 IGT_TEST_DESCRIPTION("Test to validate link training on SST/MST with "
 		     "UHBR/NON_UHBR rates");
 
@@ -342,6 +519,14 @@ igt_main
 			      "Didn't find any MST output with NON-UHBR rates.\n");
 	}
 
+	igt_describe("Test eDP data override correctly");
+	igt_subtest("edp-data-override") {
+		igt_require_f(intel_display_ver(data.devid) > 35,
+			      "eDP override not supported on platform\n");
+		igt_require_f(test_edp_data_override(&data),
+			      "eDP data override test failed\n");
+	}
+
 	igt_fixture {
 		igt_reset_connectors();
 		igt_display_fini(&data.display);
-- 
2.43.0


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

end of thread, other threads:[~2025-11-24 18:28 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-24 18:27 [PATCH i-g-t 0/6] RFC: Add new test for eDP data override Jeevan B
2025-11-24 18:27 ` [PATCH i-g-t 1/6] tests/intel/kms_dp_link_training: rename to tests/intel/kms_link_training Jeevan B
2025-11-24 18:27 ` [PATCH i-g-t 2/6] tests/intel/kms_dp_linktrain_fallback: rename to tests/intel/kms_linktrain_fallback Jeevan B
2025-11-24 18:27 ` [PATCH i-g-t 3/6] lib/igt_kms: add helpers for connector type Jeevan B
2025-11-24 18:27 ` [PATCH i-g-t 4/6] tests/intel/kms_link_training: extend test for eDP connector Jeevan B
2025-11-24 18:27 ` [PATCH i-g-t 5/6] lib/igt_kms: Add helper to get eDP/DP supported link rates Jeevan B
2025-11-24 18:27 ` [PATCH i-g-t 6/6] RFC: tests/intel/kms_link_training: Add edp-data-override subtest Jeevan B
  -- strict thread matches above, loose matches on Subject: below --
2025-10-15 10:17 [PATCH i-g-t 0/6] extend link training test cases for eDP connector Kunal Joshi
2025-10-15 10:17 ` [PATCH i-g-t 3/6] lib/igt_kms: add helpers for connector type Kunal Joshi
2025-10-27  5:51   ` B, Jeevan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).