[PATCH 040/108] drm/i915/dp_link_caps: Pass supported link rates to link caps update

Imre Deak
2026-04-28T12:53:51Z

Pass the supported link rates explicitly to intel_dp_link_caps_update().
This prepares for tracking these capabilities internally within the
link caps module.

Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/display/intel_dp.c | 30 ++----------
.../gpu/drm/i915/display/intel_dp_link_caps.c | 47 ++++++++++++++++---
.../gpu/drm/i915/display/intel_dp_link_caps.h | 5 +-
3 files changed, 50 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 347ea9bbe1ef2..febcf413bb63b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -665,21 +665,6 @@ int intel_dp_rate_index(const int *rates, int len, int rate)
return -1;
}

-static bool current_common_caps_match(struct intel_dp *intel_dp,
- const int *rates, int num_rates)
-{
- const int *current_rates = intel_dp->common_rates;
- int num_current_rates = intel_dp->num_common_rates;
-
- if (num_current_rates != num_rates)
- return false;
-
- if (memcmp(current_rates, rates, num_rates * sizeof(rates[0])))
- return false;
-
- return true;
-}
-
static void intel_dp_get_common_rates(struct intel_dp *intel_dp,
int common_rates[DP_MAX_SUPPORTED_RATES],
int *num_common_rates)
@@ -705,22 +690,17 @@ static void intel_dp_get_common_rates(struct intel_dp *intel_dp,
/* Return %true if any supported or maximum link param changed. */
static bool intel_dp_set_common_link_params(struct intel_dp *intel_dp)
{
- int num_old_common_rates = intel_dp->num_common_rates;
int old_max_rate_limit = intel_dp->link.max_rate;
- int old_common_rates[DP_MAX_SUPPORTED_RATES];
+ int num_common_rates;
+ int common_rates[DP_MAX_SUPPORTED_RATES];
bool link_params_changed = false;
int len;

- static_assert(sizeof(old_common_rates) == sizeof(intel_dp->common_rates));
- memcpy(old_common_rates, intel_dp->common_rates, sizeof(old_common_rates));
-
- intel_dp_get_common_rates(intel_dp, intel_dp->common_rates, &intel_dp->num_common_rates);
-
- if (!current_common_caps_match(intel_dp, old_common_rates, num_old_common_rates))
+ intel_dp_get_common_rates(intel_dp, common_rates, &num_common_rates);
+ if (intel_dp_link_caps_update(intel_dp,
+ common_rates, num_common_rates))
link_params_changed = true;

- intel_dp_link_caps_update(intel_dp);
-
len = intel_dp_common_len_rate_limit(intel_dp, intel_dp->link.max_rate);
if (len > 0)
intel_dp->link.max_rate = intel_dp_common_rate(intel_dp, len - 1);
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 6e021b616934e..9f8b7da98305f 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_caps.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_caps.c
@@ -8,6 +8,7 @@
#include <linux/log2.h>
#include <linux/slab.h>
#include <linux/sort.h>
+#include <linux/string.h>
#include <linux/types.h>

#include <drm/drm_print.h>
@@ -131,28 +132,56 @@ static int link_config_cmp_by_bw(const void *a, const void *b, const void *p)
intel_dp_link_config_rate(intel_dp, lc_b);
}

-void intel_dp_link_caps_update(struct intel_dp *intel_dp)
+static bool current_common_caps_match(struct intel_dp *intel_dp,
+ const int *rates, int num_rates)
+{
+ const int *current_rates = intel_dp->common_rates;
+ int num_current_rates = intel_dp->num_common_rates;
+
+ if (num_current_rates != num_rates)
+ return false;
+
+ if (memcmp(current_rates, rates, num_rates * sizeof(rates[0])))
+ return false;
+
+ return true;
+}
+
+/* Return %true if the supported link parameters have changed. */
+bool intel_dp_link_caps_update(struct intel_dp *intel_dp,
+ const int *rates, int num_rates)
{
struct intel_dp_link_caps *link_caps = intel_dp->link.caps;
struct intel_display *display = to_intel_display(intel_dp);
+ int old_rates[DP_MAX_SUPPORTED_RATES];
struct intel_dp_link_config_entry *lc;
+ bool link_params_changed = false;
int num_common_lane_configs;
+ int num_old_rates;
int i;
int j;

if (drm_WARN_ON(display->drm, !is_power_of_2(intel_dp_max_common_lane_count(intel_dp))))
- return;
+ return false;
+
+ if (drm_WARN_ON(display->drm, num_rates > ARRAY_SIZE(intel_dp->common_rates)))
+ return false;

num_common_lane_configs = ilog2(intel_dp_max_common_lane_count(intel_dp)) + 1;

- if (drm_WARN_ON(display->drm, intel_dp->num_common_rates * num_common_lane_configs >
+ if (drm_WARN_ON(display->drm, num_rates * num_common_lane_configs >
ARRAY_SIZE(link_caps->configs)))
- return;
+ return false;

- link_caps->num_configs = intel_dp->num_common_rates * num_common_lane_configs;
+ num_old_rates = intel_dp->num_common_rates;
+ memcpy(old_rates, intel_dp->common_rates, num_old_rates * sizeof(old_rates[0]));
+
+ memcpy(intel_dp->common_rates, rates, num_rates * sizeof(rates[0]));
+ intel_dp->num_common_rates = num_rates;
+ link_caps->num_configs = num_rates * num_common_lane_configs;

lc = &link_caps->configs[0];
- for (i = 0; i < intel_dp->num_common_rates; i++) {
+ for (i = 0; i < num_rates; i++) {
for (j = 0; j < num_common_lane_configs; j++) {
lc->lane_count_exp = j;
lc->link_rate_idx = i;
@@ -165,6 +194,12 @@ void intel_dp_link_caps_update(struct intel_dp *intel_dp)
sizeof(link_caps->configs[0]),
link_config_cmp_by_bw, NULL,
intel_dp);
+
+ if (!current_common_caps_match(intel_dp, old_rates, num_old_rates))
+ link_params_changed = true;
+
+ /* TODO: Also detect a change in the max lane count and max link limits. */
+ return link_params_changed;
}

void intel_dp_link_config_get(struct intel_dp *intel_dp, int idx, int *link_rate, int *lane_count)
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 aed2122a05d24..09e580bc5c9b3 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_caps.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_caps.h
@@ -4,6 +4,8 @@
#ifndef __INTEL_DP_LINK_CAPS_H__
#define __INTEL_DP_LINK_CAPS_H__

+#include <linux/types.h>
+
struct intel_connector;
struct intel_dp;
struct intel_dp_link_caps;
@@ -20,7 +22,8 @@ void intel_dp_link_caps_get_forced_params(struct intel_dp_link_caps *link_caps,
int intel_dp_link_config_index(struct intel_dp *intel_dp, int link_rate, int lane_count);
void intel_dp_link_config_get(struct intel_dp *intel_dp, int idx, int *link_rate, int *lane_count);

-void intel_dp_link_caps_update(struct intel_dp *intel_dp);
+bool intel_dp_link_caps_update(struct intel_dp *intel_dp,
+ const int *rates, int num_rates);

void intel_dp_link_caps_debugfs_add(struct intel_connector *connector);

--
2.49.1