[PATCH 083/108] drm/i915/dp_link_caps: Add helper to get iteration order for a connector

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

Add a helper to select the link configuration iteration order for a
connector. This keeps the connector-specific ordering policy in the
link caps module and allows using the same ordering during configuration
computation and fallback.

Also add the rate/lane order key, used by SST connectors, and descending
order direction, used for maximum-configuration-first policies such as
intel_dp::use_max_params and MST.

Signed-off-by: Imre Deak <imre.deak@intel.com>
---
.../gpu/drm/i915/display/intel_dp_link_caps.c | 57 +++++++++++++++++++
.../gpu/drm/i915/display/intel_dp_link_caps.h | 10 ++++
2 files changed, 67 insertions(+)

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 685fbc34b8df9..d7ffb8e8e9cf9 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_caps.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_caps.c
@@ -170,6 +170,52 @@ struct intel_dp_link_caps {
struct intel_dp_link_config max_limits;
};

+static enum intel_dp_link_caps_config_order_key
+order_key_for_connector(struct intel_connector *connector)
+{
+ if (connector->mst.dp)
+ return INTEL_DP_LINK_CAPS_CONFIG_ORDER_KEY_BW;
+ else
+ return INTEL_DP_LINK_CAPS_CONFIG_ORDER_KEY_RATE_LANE;
+}
+
+static enum intel_dp_link_caps_config_order_direction
+order_dir_for_connector(struct intel_connector *connector)
+{
+ struct intel_dp *intel_dp = intel_attached_dp(connector);
+
+ if (connector->mst.dp || intel_dp->use_max_params)
+ return INTEL_DP_LINK_CAPS_CONFIG_ORDER_DIR_DESC;
+ else
+ return INTEL_DP_LINK_CAPS_CONFIG_ORDER_DIR_ASC;
+}
+
+/**
+ * intel_dp_link_caps_config_order_for_connector - get config iteration order
+ * @connector: connector to get the iteration order for
+ *
+ * Return the configuration ordering to use for @connector.
+ *
+ * The returned order is suitable for the configuration iterators.
+ *
+ * See also:
+ * - @for_each_dp_link_config()
+ * - @for_each_dp_link_config_idx()
+ *
+ * Return:
+ * Configuration ordering for @connector.
+ */
+struct intel_dp_link_caps_config_order
+intel_dp_link_caps_config_order_for_connector(struct intel_connector *connector)
+{
+ struct intel_dp_link_caps_config_order order = {
+ .key = order_key_for_connector(connector),
+ .dir = order_dir_for_connector(connector)
+ };
+
+ return order;
+}
+
static int lookup_rate(const struct intel_dp_link_caps_config_table *table, int index)
{
if (WARN_ON(index < 0 || index >= table->num_rates))
@@ -373,6 +419,9 @@ get_table_config_by_pos(const struct intel_dp_link_caps_config_table *config_tab
switch (config_order.dir) {
case INTEL_DP_LINK_CAPS_CONFIG_ORDER_DIR_ASC:
break;
+ case INTEL_DP_LINK_CAPS_CONFIG_ORDER_DIR_DESC:
+ iter_pos = config_table->num_configs - 1 - iter_pos;
+ break;
default:
MISSING_CASE(config_order.dir);

@@ -384,12 +433,20 @@ get_table_config_by_pos(const struct intel_dp_link_caps_config_table *config_tab
*config_idx = config_table->bw_order_map[iter_pos];

break;
+ case INTEL_DP_LINK_CAPS_CONFIG_ORDER_KEY_RATE_LANE:
+ *config_idx =
+ rate_lane_iter_pos_to_config_idx(iter_pos,
+ config_table->max_lane_count);
+ break;
default:
MISSING_CASE(config_order.key);

goto out_fail;
}

+ if (*config_idx < 0)
+ goto out_fail;
+
to_intel_dp_link_config(config_table, *config_idx, config);

return true;
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 6599325932ab6..ff737dbb7f4ad 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_caps.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_caps.h
@@ -15,6 +15,8 @@ struct intel_dp_link_config;
* enum intel_dp_link_caps_config_order_key - key used to order configurations
* @INTEL_DP_LINK_CAPS_CONFIG_ORDER_KEY_BW:
* Order configurations by bandwidth, then by link rate.
+ * @INTEL_DP_LINK_CAPS_CONFIG_ORDER_KEY_RATE_LANE:
+ * Order configurations by link rate, then by lane count.
* @INTEL_DP_LINK_CAPS_CONFIG_ORDER_KEY_NUM:
* Number of ordering keys.
*
@@ -27,6 +29,7 @@ struct intel_dp_link_config;
*/
enum intel_dp_link_caps_config_order_key {
INTEL_DP_LINK_CAPS_CONFIG_ORDER_KEY_BW,
+ INTEL_DP_LINK_CAPS_CONFIG_ORDER_KEY_RATE_LANE,

INTEL_DP_LINK_CAPS_CONFIG_ORDER_KEY_NUM
};
@@ -35,6 +38,8 @@ enum intel_dp_link_caps_config_order_key {
* enum intel_dp_link_caps_config_order_direction - iteration direction
* @INTEL_DP_LINK_CAPS_CONFIG_ORDER_DIR_ASC:
* Iterate in ascending order according to the selected ordering key.
+ * @INTEL_DP_LINK_CAPS_CONFIG_ORDER_DIR_DESC:
+ * Iterate in descending order according to the selected ordering key.
* @INTEL_DP_LINK_CAPS_CONFIG_ORDER_DIR_NUM:
* Number of ordering directions.
*
@@ -46,6 +51,7 @@ enum intel_dp_link_caps_config_order_key {
*/
enum intel_dp_link_caps_config_order_direction {
INTEL_DP_LINK_CAPS_CONFIG_ORDER_DIR_ASC,
+ INTEL_DP_LINK_CAPS_CONFIG_ORDER_DIR_DESC,

INTEL_DP_LINK_CAPS_CONFIG_ORDER_DIR_NUM
};
@@ -62,6 +68,7 @@ enum intel_dp_link_caps_config_order_direction {
* Describes an iteration order for link configurations.
*
* See also:
+ * - intel_dp_link_caps_config_order_for_connector()
* - intel_dp_link_caps_get_config_by_pos()
*/
struct intel_dp_link_caps_config_order {
@@ -89,6 +96,9 @@ enum intel_dp_link_caps_config_match_type {
INTEL_DP_LINK_CAPS_CONFIG_MATCH_FUZZY_RATE,
};

+struct intel_dp_link_caps_config_order
+intel_dp_link_caps_config_order_for_connector(struct intel_connector *connector);
+
int intel_dp_link_caps_common_rate(struct intel_dp_link_caps *link_caps, int index);
int intel_dp_link_caps_common_rate_idx(struct intel_dp_link_caps *link_caps, int rate);
int intel_dp_link_caps_max_common_rate(struct intel_dp_link_caps *link_caps);
--
2.49.1