[PATCH 096/108] drm/i915/dp_test: Use link caps for compliance link configs

Imre Deak
2026-04-28T12:55:35Z

Use the link caps configuration mask when applying DP compliance test
link parameters during state computation. Expose a link caps API query
function required for the configuration selection.

Preserve the legacy behavior of falling back to all configurations with
the requested lane count if the requested rate and lane count pair is
not allowed.

In case no valid configuration is found fail the modeset.

Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/display/intel_dp.c | 3 +-
.../gpu/drm/i915/display/intel_dp_link_caps.c | 23 +++++
.../gpu/drm/i915/display/intel_dp_link_caps.h | 6 +-
drivers/gpu/drm/i915/display/intel_dp_test.c | 92 +++++++++++++++----
drivers/gpu/drm/i915/display/intel_dp_test.h | 3 +-
5 files changed, 107 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index c33209ec7782f..d577cdb1dc4e7 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2793,7 +2793,8 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp,
limits->link_config_mask = BIT(max_config_idx);
}

- intel_dp_test_compute_config(intel_dp, crtc_state, limits);
+ if (!intel_dp_test_compute_config(connector, crtc_state, limits))
+ return false;

return intel_dp_compute_config_link_bpp_limits(connector,
crtc_state,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_caps.c b/drivers/gpu/drm/i915/display/intel_dp_link_caps.c
index f822c8952df3b..6eb5b67b6168b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_caps.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_caps.c
@@ -702,6 +702,29 @@ find_config_table_entry_idx(const struct intel_dp_link_caps_config_table *config
return rate_lane_iter_pos_to_config_idx(iter_pos, config_table->max_lane_count);
}

+/**
+ * intel_dp_link_caps_find_allowed_config_idx - find index of matching allowed config
+ * @link_caps: link capabilities state
+ * @match_type: requested match type
+ * @link_config: link configuration to match
+ *
+ * Search the currently allowed link configurations for a match to
+ * @link_config.
+ *
+ * Return:
+ * * Index of the first matching allowed configuration.
+ * * %-1 if no allowed configuration matches.
+ */
+int intel_dp_link_caps_find_allowed_config_idx(struct intel_dp_link_caps *link_caps,
+ enum intel_dp_link_caps_config_match_type match_type,
+ const struct intel_dp_link_config *link_config)
+{
+ return find_config_table_entry_idx(&link_caps->config_table,
+ intel_dp_link_caps_get_allowed_config_mask(link_caps),
+ match_type,
+ link_config);
+}
+
/**
* intel_dp_link_caps_find_allowed_config_pos - find matching allowed config position
* @link_caps: link capabilities state
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_caps.h b/drivers/gpu/drm/i915/display/intel_dp_link_caps.h
index 742b88e6b0643..1e4ce6a58e4fd 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_caps.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_caps.h
@@ -92,7 +92,8 @@ struct intel_dp_link_caps_config_order {
* supported nominal link rate.
*
* Selects how
- * intel_dp_link_caps_find_allowed_config_pos() matches
+ * intel_dp_link_caps_find_allowed_config_pos() and
+ * intel_dp_link_caps_find_allowed_config_idx() match
* the requested &struct intel_dp_link_config against the currently
* allowed configurations.
*/
@@ -189,6 +190,9 @@ intel_dp_link_caps_get_config_by_pos(struct intel_dp_link_caps *link_caps,
struct intel_dp_link_caps_config_order config_order,
int iter_pos,
struct intel_dp_link_config *config, int *config_idx);
+int intel_dp_link_caps_find_allowed_config_idx(struct intel_dp_link_caps *link_caps,
+ enum intel_dp_link_caps_config_match_type match_type,
+ const struct intel_dp_link_config *config);
int intel_dp_link_caps_find_allowed_config_pos(struct intel_dp_link_caps *link_caps,
struct intel_dp_link_caps_config_order order,
enum intel_dp_link_caps_config_match_type match_type,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.c b/drivers/gpu/drm/i915/display/intel_dp_test.c
index 0b791eee3b910..fcc71d21be2fd 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_test.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_test.c
@@ -28,13 +28,66 @@ void intel_dp_test_reset(struct intel_dp *intel_dp)
memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance));
}

+static u32 find_link_configs_for_lane_count(struct intel_connector *connector,
+ struct intel_dp_link_caps *link_caps,
+ const struct link_config_limits *limits,
+ int lane_count)
+{
+ struct intel_dp_link_config link_config;
+ struct intel_dp_link_caps_config_order order =
+ intel_dp_link_caps_config_order_for_connector(connector);
+ int link_config_idx;
+ u32 mask = 0;
+
+ for_each_dp_link_config_idx(link_caps, order, limits->link_config_mask,
+ &link_config, &link_config_idx) {
+ if (link_config.lane_count == lane_count)
+ mask |= BIT(link_config_idx);
+ }
+
+ return mask;
+}
+
+static u32 find_test_link_configs(struct intel_connector *connector,
+ struct intel_dp_link_caps *link_caps,
+ const struct link_config_limits *limits,
+ const struct intel_dp_link_config *link_params)
+{
+ u32 mask = 0;
+ int idx;
+
+ idx = intel_dp_link_caps_find_allowed_config_idx(link_caps,
+ INTEL_DP_LINK_CAPS_CONFIG_MATCH_EXACT,
+ link_params);
+
+ /* Preserve the legacy behavior: if the requested (rate, lane_count)
+ * combination is not an allowed config, fall back to all configs
+ * matching the requested lane count.
+ *
+ * TODO: Recheck whether this behavior is actually correct.
+ */
+ if (idx >= 0 && (limits->link_config_mask & BIT(idx)))
+ mask = BIT(idx);
+ else
+ mask = find_link_configs_for_lane_count(connector, link_caps,
+ limits,
+ link_params->lane_count);
+
+ return mask;
+
+}
+
/* Adjust link config limits based on compliance test requests. */
-void intel_dp_test_compute_config(struct intel_dp *intel_dp,
+bool intel_dp_test_compute_config(struct intel_connector *connector,
struct intel_crtc_state *pipe_config,
struct link_config_limits *limits)
{
+ struct intel_dp *intel_dp = intel_attached_dp(connector);
struct intel_dp_link_caps *link_caps = intel_dp->link.caps;
+ struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
struct intel_display *display = to_intel_display(intel_dp);
+ struct intel_dp_link_config requested_config;
+ u32 requested_config_mask;

/* For DP Compliance we override the computed bpp for the pipe */
if (intel_dp->compliance.test_data.bpc != 0) {
@@ -48,24 +101,29 @@ void intel_dp_test_compute_config(struct intel_dp *intel_dp,
}

/* Use values requested by Compliance Test Request */
- if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) {
- int index;
+ if (intel_dp->compliance.test_type != DP_TEST_LINK_TRAINING)
+ return true;

- /* Validate the compliance test data since max values
- * might have changed due to link train fallback.
- */
- if (intel_dp_link_params_valid(intel_dp, intel_dp->compliance.test_link_rate,
- intel_dp->compliance.test_lane_count)) {
- index = intel_dp_link_caps_common_rate_idx(link_caps,
- intel_dp->compliance.test_link_rate);
- if (index >= 0) {
- limits->min_rate = intel_dp->compliance.test_link_rate;
- limits->max_rate = intel_dp->compliance.test_link_rate;
- }
- limits->min_lane_count = intel_dp->compliance.test_lane_count;
- limits->max_lane_count = intel_dp->compliance.test_lane_count;
- }
+ requested_config.rate = intel_dp->compliance.test_link_rate;
+ requested_config.lane_count = intel_dp->compliance.test_lane_count;
+
+ requested_config_mask = find_test_link_configs(connector, link_caps,
+ limits,
+ &requested_config);
+
+ if (requested_config_mask == 0) {
+ drm_dbg_kms(display->drm,
+ "[ENCODER:%d:%s] Invalid autotest link config parameters: %dx%d\n",
+ encoder->base.base.id, encoder->base.name,
+ requested_config.lane_count,
+ requested_config.rate);
+
+ return false;
}
+
+ limits->link_config_mask = requested_config_mask;
+
+ return true;
}

/* Compliance test status bits */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.h b/drivers/gpu/drm/i915/display/intel_dp_test.h
index dcc167e4c7f65..a08f37a63dc9a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_test.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_test.h
@@ -6,6 +6,7 @@

#include <linux/types.h>

+struct intel_connector;
struct intel_crtc_state;
struct intel_display;
struct intel_dp;
@@ -13,7 +14,7 @@ struct link_config_limits;

void intel_dp_test_reset(struct intel_dp *intel_dp);
void intel_dp_test_request(struct intel_dp *intel_dp);
-void intel_dp_test_compute_config(struct intel_dp *intel_dp,
+bool intel_dp_test_compute_config(struct intel_connector *connector,
struct intel_crtc_state *pipe_config,
struct link_config_limits *limits);
bool intel_dp_test_phy(struct intel_dp *intel_dp);
--
2.49.1