[PATCH 084/108] drm/i915/dp_link_caps: Add reset and merge update modes

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

Add update modes to intel_dp_link_caps_update() to distinguish between
resetting link capability state for a new sink and merging newly read
capabilities into existing state.

Reset mode is used when a new sink is connected, after
intel_dp_reset_link_params() is called. Merge mode is used when an
already connected sink reports a capability change, preserving disabled
configurations that are still present after the update.

This patch only implements the reset mode, by resetting the maximum link
limits, the logic for merge behavior will be added by follow-up changes.

Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/display/intel_dp.c | 9 ++++++++-
.../gpu/drm/i915/display/intel_dp_link_caps.c | 15 ++++++++++++++-
.../gpu/drm/i915/display/intel_dp_link_caps.h | 19 ++++++++++++++++++-
3 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 875e835848c39..0255aeff84b85 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -686,14 +686,21 @@ 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)
{
+ enum intel_dp_link_caps_update_mode update_mode =
+ INTEL_DP_LINK_CAPS_UPDATE_MERGE;
int num_common_rates;
int common_rates[DP_MAX_SUPPORTED_RATES];
bool link_params_changed = false;

intel_dp_get_common_rates(intel_dp, common_rates, &num_common_rates);
+
+ if (intel_dp->reset_link_params)
+ update_mode = INTEL_DP_LINK_CAPS_UPDATE_RESET;
+
if (intel_dp_link_caps_update(intel_dp->link.caps,
common_rates, num_common_rates,
- intel_dp_max_common_lane_count(intel_dp)))
+ intel_dp_max_common_lane_count(intel_dp),
+ update_mode))
link_params_changed = true;

return link_params_changed;
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 d7ffb8e8e9cf9..9c0ad5cf87259 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_caps.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_caps.c
@@ -949,10 +949,19 @@ static bool build_config_table(struct intel_display *display,
* @rates: supported common link rates
* @num_rates: number of entries in @rates
* @max_lane_count: supported maximum lane count
+ * @update_mode: update mode controlling reset vs. merge behavior
*
* Rebuild the supported link configuration state from @rates and
* @max_lane_count.
*
+ * If @update_mode is %INTEL_DP_LINK_CAPS_UPDATE_RESET, reset the
+ * maximum link limits to the maximum supported rate and lane count, and
+ * re-enable all configurations.
+ *
+ * If @update_mode is %INTEL_DP_LINK_CAPS_UPDATE_MERGE, preserve the
+ * disabled state of configurations that were disabled before the update
+ * and are still present after it.
+ *
* Configuration indices are not stable across calls to this function, so
* callers should not cache such indices and masks built from them across
* updates via this function.
@@ -972,7 +981,8 @@ static bool build_config_table(struct intel_display *display,
* - %true if the supported link parameters have changed, %false otherwise.
*/
bool intel_dp_link_caps_update(struct intel_dp_link_caps *link_caps,
- const int *rates, int num_rates, int max_lane_count)
+ const int *rates, int num_rates, int max_lane_count,
+ enum intel_dp_link_caps_update_mode update_mode)
{
struct intel_dp *intel_dp = link_caps->dp;
struct intel_display *display = to_intel_display(intel_dp);
@@ -989,6 +999,9 @@ bool intel_dp_link_caps_update(struct intel_dp_link_caps *link_caps,

link_caps->config_table = new_table;

+ if (update_mode == INTEL_DP_LINK_CAPS_UPDATE_RESET)
+ reset_max_link_limits_no_update(link_caps);
+
/*
* A failure could be only due to a bug, the update function handles
* that case by removing all restriction and resetting the max limit
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 ff737dbb7f4ad..ff66056adc9b5 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_caps.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_caps.h
@@ -96,6 +96,22 @@ enum intel_dp_link_caps_config_match_type {
INTEL_DP_LINK_CAPS_CONFIG_MATCH_FUZZY_RATE,
};

+/**
+ * enum intel_dp_link_caps_update_mode - intel_dp_link_caps_update() mode
+ * @INTEL_DP_LINK_CAPS_UPDATE_RESET:
+ * Reset max link limits and re-enable all configurations.
+ * @INTEL_DP_LINK_CAPS_UPDATE_MERGE:
+ * Preserve the disabled state of configurations that remain present
+ * after the update.
+ *
+ * Controls how intel_dp_link_caps_update() applies newly read sink
+ * capabilities to the existing link capability state.
+ */
+enum intel_dp_link_caps_update_mode {
+ INTEL_DP_LINK_CAPS_UPDATE_RESET,
+ INTEL_DP_LINK_CAPS_UPDATE_MERGE,
+};
+
struct intel_dp_link_caps_config_order
intel_dp_link_caps_config_order_for_connector(struct intel_connector *connector);

@@ -127,7 +143,8 @@ bool intel_dp_link_caps_set_max_limits(struct intel_dp_link_caps *link_caps,
void intel_dp_link_caps_reset_max_limits(struct intel_dp_link_caps *link_caps);

bool intel_dp_link_caps_update(struct intel_dp_link_caps *link_caps,
- const int *rates, int num_rates, int max_lane_count);
+ const int *rates, int num_rates, int max_lane_count,
+ enum intel_dp_link_caps_update_mode update_mode);
void intel_dp_link_caps_reset(struct intel_dp_link_caps *link_caps);

void intel_dp_link_caps_debugfs_add(struct intel_connector *connector);
--
2.49.1