[PATCH 071/108] drm/i915/dp_link_caps: Add helper to get config at iterator position

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

Add a helper to look up a link configuration for a given iteration order
at a given position, returning the canonical index and rate/lane info.
This prepares for iterating over any set of configurations in a
specified order.

This is needed by a follow-up replacing the configuration index based
look up in the fallback code (intel_dp_link_config_get()) with the
helper added here.

Signed-off-by: Imre Deak <imre.deak@intel.com>
---
.../gpu/drm/i915/display/intel_dp_link_caps.c | 73 +++++++++++++++++++
.../gpu/drm/i915/display/intel_dp_link_caps.h | 63 ++++++++++++++++
2 files changed, 136 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 f17e30e84901b..48b57aea557ca 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_caps.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_caps.c
@@ -15,6 +15,7 @@

#include "intel_display_core.h"
#include "intel_display_types.h"
+#include "intel_display_utils.h"
#include "intel_dp.h"
#include "intel_dp_link_caps.h"

@@ -309,6 +310,46 @@ to_intel_dp_link_config(const struct intel_dp_link_caps_config_table *table,
config->lane_count = link_config_idx_to_lane_count(table, config_idx);
}

+static bool
+get_table_config_by_pos(const struct intel_dp_link_caps_config_table *config_table,
+ struct intel_dp_link_caps_config_order config_order,
+ int iter_pos,
+ struct intel_dp_link_config *config, int *config_idx)
+{
+ if (!in_range(iter_pos, 0, config_table->num_configs))
+ goto out_fail;
+
+ switch (config_order.dir) {
+ case INTEL_DP_LINK_CAPS_CONFIG_ORDER_DIR_ASC:
+ break;
+ default:
+ MISSING_CASE(config_order.dir);
+
+ goto out_fail;
+ }
+
+ switch (config_order.key) {
+ case INTEL_DP_LINK_CAPS_CONFIG_ORDER_KEY_BW:
+ *config_idx = iter_pos;
+
+ break;
+ default:
+ MISSING_CASE(config_order.key);
+
+ goto out_fail;
+ }
+
+ to_intel_dp_link_config(config_table, *config_idx, config);
+
+ return true;
+
+out_fail:
+ *config = INTEL_DP_LINK_CONFIG_NULL;
+ *config_idx = -1;
+
+ return false;
+}
+
static u32 calc_allowed_config_mask(struct intel_dp_link_caps *link_caps,
u32 disabled_config_mask,
const struct intel_dp_link_config *max_limits,
@@ -370,6 +411,38 @@ u32 intel_dp_link_caps_get_allowed_config_mask(struct intel_dp_link_caps *link_c
&link_caps->max_limits, &forced_params);
}

+/**
+ * intel_dp_link_caps_get_config_by_pos - get config at a given iterator position
+ * @link_caps: link capability state
+ * @config_order: iteration order
+ * @iter_pos: position in the @config_order iteration order
+ * @config: returned link configuration
+ * @config_idx: returned config index
+ *
+ * Look up the link config at iterator position @iter_pos in the order
+ * described by @config_order.
+ *
+ * Note that any mapping between @iter_pos and @config_idx is an
+ * implementation detail defined by @config_order and must not be
+ * relied upon. The returned @config_idx always, regardless of
+ * @config_order, uses the canonical configuration index/mask scheme
+ * shared by the link-caps API.
+ *
+ * Return:
+ * - %true if @iter_pos is valid, storing the configuration in @config and
+ * its index in @config_idx.
+ * - %false if @iter_pos is out of range, storing %INTEL_DP_LINK_CONFIG_NULL
+ * in @config and -1 in @config_idx.
+ */
+bool 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)
+{
+ return get_table_config_by_pos(&link_caps->config_table, config_order, iter_pos,
+ config, config_idx);
+}
+
static void set_max_link_limits_no_update(struct intel_dp_link_caps *link_caps,
const struct intel_dp_link_config *max_link_limits)
{
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 7fe0e4a028f26..79cd50db90ba6 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_caps.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_caps.h
@@ -11,6 +11,64 @@ struct intel_dp;
struct intel_dp_link_caps;
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_NUM:
+ * Number of ordering keys.
+ *
+ * Selects how a caller wants the configuration table to be ordered,
+ * together with an &enum intel_dp_link_caps_config_order_direction, for
+ * iteration queries.
+ *
+ * See also:
+ * - &struct intel_dp_link_caps_config_order
+ */
+enum intel_dp_link_caps_config_order_key {
+ INTEL_DP_LINK_CAPS_CONFIG_ORDER_KEY_BW,
+
+ INTEL_DP_LINK_CAPS_CONFIG_ORDER_KEY_NUM
+};
+
+/**
+ * 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_NUM:
+ * Number of ordering directions.
+ *
+ * Selects the direction associated with an
+ * &enum intel_dp_link_caps_config_order_key for iteration queries.
+ *
+ * See also:
+ * - &struct intel_dp_link_caps_config_order
+ */
+enum intel_dp_link_caps_config_order_direction {
+ INTEL_DP_LINK_CAPS_CONFIG_ORDER_DIR_ASC,
+
+ INTEL_DP_LINK_CAPS_CONFIG_ORDER_DIR_NUM
+};
+
+/**
+ * struct intel_dp_link_caps_config_order - configuration ordering
+ * @key:
+ * Key used to order configurations, see
+ * &enum intel_dp_link_caps_config_order_key.
+ * @dir:
+ * Direction of the selected ordering, see
+ * &enum intel_dp_link_caps_config_order_direction.
+ *
+ * Describes an iteration order for link configurations.
+ *
+ * See also:
+ * - intel_dp_link_caps_get_config_by_pos()
+ */
+struct intel_dp_link_caps_config_order {
+ enum intel_dp_link_caps_config_order_key key;
+ enum intel_dp_link_caps_config_order_direction dir;
+};
+
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);
@@ -24,6 +82,11 @@ u32 intel_dp_link_caps_get_allowed_config_mask(struct intel_dp_link_caps *link_c

int intel_dp_link_config_index(struct intel_dp_link_caps *link_caps,
int link_rate, int lane_count);
+bool
+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);
void intel_dp_link_config_get(struct intel_dp_link_caps *link_caps,
int idx, int *link_rate, int *lane_count);

--
2.49.1