From: Imre Deak <imre.deak@intel.com>
To: <intel-gfx@lists.freedesktop.org>, <intel-xe@lists.freedesktop.org>
Subject: [PATCH 107/108] drm/i915/kunit: DP link: add update config tests
Date: Tue, 28 Apr 2026 15:52:28 +0300 [thread overview]
Message-ID: <20260428125233.1664668-108-imre.deak@intel.com> (raw)
In-Reply-To: <20260428125233.1664668-1-imre.deak@intel.com>
Add KUnit tests for link_caps updates, covering reset and merge updates
when supported rates and lane counts shrink or expand.
The tests also cover updates with disabled configurations, including
random shrink and expand sequences, to verify that disabled state,
allowed configurations, ordering, and max limits stay consistent across
updates.
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
.../i915/display/tests/intel_dp_link_test.c | 763 ++++++++++++++++++
1 file changed, 763 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/tests/intel_dp_link_test.c b/drivers/gpu/drm/i915/display/tests/intel_dp_link_test.c
index e6feb68cb912f..10c4679f31efd 100644
--- a/drivers/gpu/drm/i915/display/tests/intel_dp_link_test.c
+++ b/drivers/gpu/drm/i915/display/tests/intel_dp_link_test.c
@@ -82,12 +82,29 @@ struct link_config_set {
int size;
};
+struct test_config_table {
+ struct kunit *test;
+
+ struct link_rate_set rates;
+ int max_lane_count;
+ struct link_config_set disabled_configs;
+};
+
static const int standard_dp_link_rates[] = {
162000, 270000, 540000, 810000, 1000000, 1350000, 2000000
};
#define LINK_TEST_NUM_STANDARD_RATES (ARRAY_SIZE(standard_dp_link_rates))
+#define INIT_STANDARD_TABLE(__test, __num_rates, __max_lane_count) { \
+ .test = (__test), \
+ .rates = { \
+ .entries = standard_dp_link_rates, \
+ .size = (__num_rates), \
+ }, \
+ .max_lane_count = (__max_lane_count), \
+}
+
static const struct link_config_set standard_dp_link_configs[] = {
[TEST_CONFIG_ORDER_KEY_BW] = { /* MBps PBN */
.entries = {
@@ -180,12 +197,56 @@ static const struct link_config_set standard_dp_link_configs[] = {
},
};
+static int lookup_rate(const struct link_rate_set *rate_set, int rate)
+{
+ int i;
+
+ for (i = 0; i < rate_set->size; i++)
+ if (rate_set->entries[i] == rate)
+ return i;
+
+ return -1;
+}
+
+static bool has_rate(const struct link_rate_set *rate_set, int rate)
+{
+ return lookup_rate(rate_set, rate) >= 0;
+}
+
static bool link_configs_match(const struct intel_dp_link_config *a,
const struct intel_dp_link_config *b)
{
return a->rate == b->rate && a->lane_count == b->lane_count;
}
+static int lookup_config(const struct link_config_set *config_set,
+ const struct intel_dp_link_config *config)
+{
+ int i;
+
+ for (i = 0; i < config_set->size; i++)
+ if (link_configs_match(&config_set->entries[i], config))
+ return i;
+
+ return -1;
+}
+
+static bool has_config(const struct link_config_set *config_set,
+ const struct intel_dp_link_config *config)
+{
+ return lookup_config(config_set, config) >= 0;
+}
+
+static void add_config(struct kunit *test,
+ struct link_config_set *config_set,
+ const struct intel_dp_link_config *config)
+{
+ KUNIT_ASSERT_LT(test, config_set->size, ARRAY_SIZE(config_set->entries));
+
+ config_set->entries[config_set->size] = *config;
+ config_set->size++;
+}
+
static u32 get_all_config_mask(void)
{
return GENMASK_U32(LINK_TEST_MAX_CONFIGS - 1, 0);
@@ -274,9 +335,711 @@ static void intel_dp_link_caps_test_baseline(struct kunit *test)
baseline_test_for_order(test, link_caps, config_orders[i]);
}
+static int get_num_configs(int num_rates, int max_lane_count)
+{
+ return num_rates * LINK_TEST_NUM_LANE_CONFIGS(max_lane_count);
+}
+
+static int rand_in_range(struct test_ctx *ctx, int min, int max)
+{
+ return min + (prandom_u32_state(&ctx->rnd) % (max - min + 1));
+}
+
+/*
+ * TEST: Update reset
+ * ------------------
+ * Verify that resetting link_caps with the DP standard rates/lane
+ * counts updates the configuration table accordingly for all
+ * combinations.
+ */
+static u32 get_link_caps_enabled_config_mask(struct kunit *test,
+ struct intel_dp_link_caps *link_caps)
+{
+ struct test_ctx *ctx = test->priv;
+ const struct intel_dp_link_caps_test_ops *ops =
+ ctx->link_caps_ops;
+ struct intel_dp_link_config old_limits;
+ u32 mask;
+
+ /*
+ * The link_caps allowed config mask is limited by both the disabled
+ * state of the configs and the current max limits parameters. To get
+ * the enabled mask unaffected by the max limit parameters, get the
+ * allowed mask by resetting the max limits temporarily.
+ */
+ ops->get_max_limits(link_caps, &old_limits);
+ ops->reset_max_limits(link_caps);
+
+ mask = ops->get_allowed_config_mask(link_caps);
+
+ ops->set_max_limits(link_caps, &old_limits);
+
+ return mask;
+}
+
+static void verify_bw_asc_config_order(struct kunit *test,
+ const struct intel_dp_link_config *last_config,
+ const struct intel_dp_link_config *config)
+{
+ int config_bw = drm_dp_max_dprx_data_rate(config->rate,
+ config->lane_count);
+ int last_config_bw = drm_dp_max_dprx_data_rate(last_config->rate,
+ last_config->lane_count);
+
+ KUNIT_EXPECT_GE(test, config_bw, last_config_bw);
+ if (config_bw == last_config_bw)
+ KUNIT_EXPECT_GT(test, config->rate, last_config->rate);
+}
+
+static void verify_bw_desc_config_order(struct kunit *test,
+ const struct intel_dp_link_config *last_config,
+ const struct intel_dp_link_config *config)
+{
+ int config_bw = drm_dp_max_dprx_data_rate(config->rate,
+ config->lane_count);
+ int last_config_bw = drm_dp_max_dprx_data_rate(last_config->rate,
+ last_config->lane_count);
+
+ KUNIT_EXPECT_LE(test, config_bw, last_config_bw);
+ if (config_bw == last_config_bw)
+ KUNIT_EXPECT_LT(test, config->rate, last_config->rate);
+}
+
+static void verify_rate_lane_asc_config_order(struct kunit *test,
+ const struct intel_dp_link_config *last_config,
+ const struct intel_dp_link_config *config)
+{
+ KUNIT_EXPECT_GE(test, config->rate, last_config->rate);
+ if (config->rate == last_config->rate)
+ KUNIT_EXPECT_GT(test, config->lane_count, last_config->lane_count);
+}
+
+static void verify_rate_lane_desc_config_order(struct kunit *test,
+ const struct intel_dp_link_config *last_config,
+ const struct intel_dp_link_config *config)
+{
+ KUNIT_EXPECT_LE(test, config->rate, last_config->rate);
+ if (config->rate == last_config->rate)
+ KUNIT_EXPECT_LT(test, config->lane_count, last_config->lane_count);
+}
+
+static void verify_config_order(struct kunit *test,
+ struct intel_dp_link_caps_config_order config_order,
+ const struct intel_dp_link_config *last_config,
+ const struct intel_dp_link_config *config)
+{
+ switch (config_order.key) {
+ case INTEL_DP_LINK_CAPS_CONFIG_ORDER_KEY_BW:
+ if (config_order.dir == INTEL_DP_LINK_CAPS_CONFIG_ORDER_DIR_ASC)
+ verify_bw_asc_config_order(test, last_config, config);
+ else
+ verify_bw_desc_config_order(test, last_config, config);
+ break;
+ case INTEL_DP_LINK_CAPS_CONFIG_ORDER_KEY_RATE_LANE:
+ if (config_order.dir == INTEL_DP_LINK_CAPS_CONFIG_ORDER_DIR_ASC)
+ verify_rate_lane_asc_config_order(test, last_config, config);
+ else
+ verify_rate_lane_desc_config_order(test, last_config, config);
+ break;
+ default:
+ KUNIT_FAIL_AND_ABORT(test, "Missing order key: %d", config_order.key);
+ }
+}
+
+static void
+verify_link_caps_for_order(const struct test_config_table *expected_table,
+ struct intel_dp_link_caps *link_caps,
+ struct intel_dp_link_caps_config_order config_order)
+{
+ struct kunit *test = expected_table->test;
+ struct test_ctx *ctx = test->priv;
+ const struct intel_dp_link_caps_test_ops *ops =
+ ctx->link_caps_ops;
+ struct intel_dp_link_config expected_max_limits = {};
+ struct intel_dp_link_config actual_max_limits;
+ struct intel_dp_link_config last_config = {};
+ struct intel_dp_link_config iter_config;
+ int num_actual_configs = 0;
+ int iter_config_idx;
+
+ test_for_each_dp_link_config_idx(ctx, config_order, get_all_config_mask(),
+ &iter_config, &iter_config_idx) {
+ bool config_disabled;
+
+ num_actual_configs++;
+
+ /*
+ * Verify the config's rate/lane-count values and its ordering relative
+ * to the previous config.
+ */
+ if (last_config.rate)
+ verify_config_order(test, config_order, &last_config, &iter_config);
+ last_config = iter_config;
+
+ KUNIT_EXPECT_TRUE(test, has_rate(&expected_table->rates,
+ iter_config.rate));
+ KUNIT_EXPECT_LE(test, iter_config.lane_count,
+ expected_table->max_lane_count);
+ KUNIT_EXPECT_TRUE(test, is_power_of_2(iter_config.lane_count));
+
+ /* Verify the config's disabled state */
+ config_disabled = !(get_link_caps_enabled_config_mask(test, link_caps) &
+ BIT(iter_config_idx));
+ KUNIT_EXPECT_EQ(test, config_disabled,
+ has_config(&expected_table->disabled_configs,
+ &iter_config));
+
+ /*
+ * Update the max limits for allowed configs, verified at the
+ * end for the whole config table.
+ */
+ if (!(ops->get_allowed_config_mask(link_caps) &
+ BIT(iter_config_idx)))
+ continue;
+
+ expected_max_limits.rate = max(expected_max_limits.rate,
+ iter_config.rate);
+ expected_max_limits.lane_count = max(expected_max_limits.lane_count,
+ iter_config.lane_count);
+ }
+
+ KUNIT_EXPECT_EQ(test, num_actual_configs,
+ get_num_configs(expected_table->rates.size,
+ expected_table->max_lane_count));
+
+ ops->get_max_limits(link_caps, &actual_max_limits);
+ KUNIT_EXPECT_TRUE(test, link_configs_match(&expected_max_limits,
+ &actual_max_limits));
+}
+
+static void verify_link_caps(const struct test_config_table *expected_table,
+ struct intel_dp_link_caps *link_caps)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(config_orders); i++)
+ verify_link_caps_for_order(expected_table, link_caps, config_orders[i]);
+}
+
+/*
+ * Filter out the disabled configs, which got removed after a configuration
+ * shrink step reduced the maximum rate and/or maximum lane count of the
+ * configurations.
+ *
+ * Also make sure that at least one configuration (the minimal config) remains
+ * enabled after a shrink step.
+ */
+static void update_disabled_configs(struct test_config_table *expected_table)
+{
+ struct kunit *test = expected_table->test;
+ struct link_config_set new_disabled_configs = {};
+ const struct intel_dp_link_config min_config = {
+ .rate = expected_table->rates.entries[0],
+ .lane_count = 1,
+ };
+ bool min_config_disabled = false;
+ int num_configs;
+ int i;
+
+ num_configs = get_num_configs(expected_table->rates.size,
+ expected_table->max_lane_count);
+
+ for (i = 0; i < expected_table->disabled_configs.size; i++) {
+ const struct intel_dp_link_config *config =
+ &expected_table->disabled_configs.entries[i];
+
+ if (config->rate >
+ expected_table->rates.entries[expected_table->rates.size - 1] ||
+ config->lane_count >
+ expected_table->max_lane_count)
+ continue;
+
+ /*
+ * Mark the minimum config disabled only at the end, and only if that
+ * would not leave all configs disabled.
+ */
+ if (link_configs_match(config, &min_config)) {
+ min_config_disabled = true;
+
+ continue;
+ }
+
+ add_config(test, &new_disabled_configs, config);
+ }
+
+ expected_table->disabled_configs = new_disabled_configs;
+
+ if (min_config_disabled &&
+ expected_table->disabled_configs.size + 1 < num_configs)
+ add_config(test, &expected_table->disabled_configs, &min_config);
+}
+
+static void update_link_caps_and_verify(struct test_config_table *expected_table,
+ struct intel_dp_link_caps *link_caps,
+ enum intel_dp_link_caps_update_mode update_mode)
+{
+ struct kunit *test = expected_table->test;
+ struct test_ctx *ctx = test->priv;
+ const struct intel_dp_link_caps_test_ops *ops =
+ ctx->link_caps_ops;
+
+ update_disabled_configs(expected_table);
+
+ ops->update(link_caps,
+ expected_table->rates.entries, expected_table->rates.size,
+ expected_table->max_lane_count,
+ update_mode);
+
+ /*
+ * In case of adding new configurations vs. replacing the current
+ * ones with new ones, the max limits tracked by link_caps don't
+ * get updated automatically, do that here as expected by all the
+ * test cases.
+ */
+ if (update_mode == INTEL_DP_LINK_CAPS_UPDATE_MERGE)
+ ops->reset_max_limits(link_caps);
+
+ verify_link_caps(expected_table, link_caps);
+}
+
+static void intel_dp_link_caps_test_update_reset(struct kunit *test)
+{
+ struct test_ctx *ctx = test->priv;
+ struct intel_dp_link_caps *link_caps = ctx->dev.dp.link.caps;
+ int max_lane_count;
+ int num_rates;
+
+ for (max_lane_count = 1;
+ max_lane_count <= LINK_TEST_MAX_LANE_COUNT;
+ max_lane_count <<= 1) {
+ for (num_rates = 1;
+ num_rates <= LINK_TEST_NUM_STANDARD_RATES;
+ num_rates++) {
+ struct test_config_table expected_table =
+ INIT_STANDARD_TABLE(test, num_rates,
+ max_lane_count);
+
+ update_link_caps_and_verify(&expected_table, link_caps,
+ INTEL_DP_LINK_CAPS_UPDATE_RESET);
+ }
+ }
+}
+
+/*
+ * TEST: Update shrink and expand
+ * ------------------------------
+ * Verify that removing or adding supported rates/lane counts updates
+ * the configuration table accordingly.
+ */
+static void disable_configs_and_verify(struct kunit *test,
+ struct intel_dp_link_caps *link_caps,
+ struct test_config_table *expected_table,
+ const struct link_config_set *config_set)
+{
+ struct test_ctx *ctx = test->priv;
+ const struct intel_dp_link_caps_test_ops *ops =
+ ctx->link_caps_ops;
+ int i;
+
+ for (i = 0; i < config_set->size; i++) {
+ int config_idx;
+
+ config_idx = ops->find_allowed_config_idx(link_caps,
+ INTEL_DP_LINK_CAPS_CONFIG_MATCH_EXACT,
+ &config_set->entries[i]);
+ KUNIT_ASSERT_GE(test, config_idx, 0);
+
+ KUNIT_ASSERT_FALSE(test, has_config(&expected_table->disabled_configs,
+ &config_set->entries[i]));
+ add_config(test, &expected_table->disabled_configs, &config_set->entries[i]);
+
+ ops->disable_config(link_caps, config_idx);
+
+ verify_link_caps(expected_table, link_caps);
+ }
+}
+
+static void disable_configs_for_shrink_and_verify(struct test_config_table *expected_table,
+ struct intel_dp_link_caps *link_caps)
+{
+ struct kunit *test = expected_table->test;
+ struct link_config_set config_set = {};
+ struct intel_dp_link_config max_config;
+
+ /*
+ * When configs shrink disable the config with the
+ * second-highest rate,lane params, so the disabled config
+ * stays around after the configs got shrunk.
+ */
+ KUNIT_ASSERT_GE(test, expected_table->rates.size, 2);
+ KUNIT_ASSERT_GE(test, expected_table->max_lane_count, 2);
+
+ max_config.rate = expected_table->rates.entries[expected_table->rates.size - 2];
+ max_config.lane_count = expected_table->max_lane_count >> 1;
+
+ add_config(test, &config_set, &max_config);
+ disable_configs_and_verify(test, link_caps, expected_table,
+ &config_set);
+}
+
+static void disable_configs_for_expand_and_verify(struct test_config_table *expected_table,
+ struct intel_dp_link_caps *link_caps)
+{
+ struct kunit *test = expected_table->test;
+ struct link_config_set config_set = {};
+ struct intel_dp_link_config max_config;
+
+ KUNIT_ASSERT_GE(test, expected_table->rates.size, 1);
+
+ max_config.rate = expected_table->rates.entries[expected_table->rates.size - 1];
+ max_config.lane_count = expected_table->max_lane_count;
+
+ add_config(test, &config_set, &max_config);
+ disable_configs_and_verify(test, link_caps, expected_table,
+ &config_set);
+}
+
+static void get_nth_rate_lane_config(const struct test_config_table *expected_table, int n,
+ struct intel_dp_link_config *config)
+{
+ int num_lane_configs = LINK_TEST_NUM_LANE_CONFIGS(expected_table->max_lane_count);
+ int rate_idx = n / num_lane_configs;
+ int lane_count_exp = n % num_lane_configs;
+
+ config->rate = expected_table->rates.entries[rate_idx];
+ config->lane_count = 1 << lane_count_exp;
+}
+
+static void test_update_rates_shrink(struct kunit *test, bool disable_configs)
+{
+ struct test_ctx *ctx = test->priv;
+ struct intel_dp_link_caps *link_caps = ctx->dev.dp.link.caps;
+ struct test_config_table expected_table =
+ INIT_STANDARD_TABLE(test, LINK_TEST_NUM_STANDARD_RATES,
+ LINK_TEST_MAX_LANE_COUNT);
+
+ update_link_caps_and_verify(&expected_table, link_caps,
+ INTEL_DP_LINK_CAPS_UPDATE_RESET);
+
+ while (expected_table.rates.size > 1) {
+ if (disable_configs)
+ disable_configs_for_shrink_and_verify(&expected_table, link_caps);
+
+ expected_table.rates.size--;
+
+ update_link_caps_and_verify(&expected_table, link_caps,
+ INTEL_DP_LINK_CAPS_UPDATE_MERGE);
+ }
+}
+
+static void intel_dp_link_caps_test_update_rates_shrink(struct kunit *test)
+{
+ test_update_rates_shrink(test, false);
+}
+
+static void intel_dp_link_caps_test_update_rates_shrink_disable(struct kunit *test)
+{
+ test_update_rates_shrink(test, true);
+}
+
+static void test_update_rates_expand(struct kunit *test, bool disable_configs)
+{
+ struct test_ctx *ctx = test->priv;
+ struct intel_dp_link_caps *link_caps = ctx->dev.dp.link.caps;
+ struct test_config_table expected_table =
+ INIT_STANDARD_TABLE(test, 1, LINK_TEST_MAX_LANE_COUNT);
+
+ update_link_caps_and_verify(&expected_table, link_caps,
+ INTEL_DP_LINK_CAPS_UPDATE_RESET);
+
+ while (expected_table.rates.size < LINK_TEST_NUM_STANDARD_RATES) {
+ if (disable_configs)
+ disable_configs_for_expand_and_verify(&expected_table, link_caps);
+
+ expected_table.rates.size++;
+
+ update_link_caps_and_verify(&expected_table, link_caps,
+ INTEL_DP_LINK_CAPS_UPDATE_MERGE);
+ }
+}
+
+static void intel_dp_link_caps_test_update_rates_expand(struct kunit *test)
+{
+ test_update_rates_expand(test, false);
+}
+
+static void intel_dp_link_caps_test_update_rates_expand_disable(struct kunit *test)
+{
+ test_update_rates_expand(test, true);
+}
+
+static void test_update_lanes_shrink(struct kunit *test, bool disable_configs)
+{
+ struct test_ctx *ctx = test->priv;
+ struct intel_dp_link_caps *link_caps = ctx->dev.dp.link.caps;
+ struct test_config_table expected_table =
+ INIT_STANDARD_TABLE(test, LINK_TEST_NUM_STANDARD_RATES,
+ LINK_TEST_MAX_LANE_COUNT);
+
+ update_link_caps_and_verify(&expected_table, link_caps,
+ INTEL_DP_LINK_CAPS_UPDATE_RESET);
+
+ while (expected_table.max_lane_count > 1) {
+ if (disable_configs)
+ disable_configs_for_shrink_and_verify(&expected_table, link_caps);
+
+ expected_table.max_lane_count >>= 1;
+
+ update_link_caps_and_verify(&expected_table, link_caps,
+ INTEL_DP_LINK_CAPS_UPDATE_MERGE);
+ }
+}
+
+static void intel_dp_link_caps_test_update_lanes_shrink(struct kunit *test)
+{
+ test_update_lanes_shrink(test, false);
+}
+
+static void intel_dp_link_caps_test_update_lanes_shrink_disable(struct kunit *test)
+{
+ test_update_lanes_shrink(test, true);
+}
+
+static void test_update_lanes_expand(struct kunit *test, bool disable_configs)
+{
+ struct test_ctx *ctx = test->priv;
+ struct intel_dp_link_caps *link_caps = ctx->dev.dp.link.caps;
+ struct test_config_table expected_table =
+ INIT_STANDARD_TABLE(test, LINK_TEST_NUM_STANDARD_RATES, 1);
+
+ update_link_caps_and_verify(&expected_table, link_caps,
+ INTEL_DP_LINK_CAPS_UPDATE_RESET);
+
+ while (expected_table.max_lane_count < LINK_TEST_MAX_LANE_COUNT) {
+ if (disable_configs)
+ disable_configs_for_expand_and_verify(&expected_table, link_caps);
+
+ expected_table.max_lane_count <<= 1;
+
+ update_link_caps_and_verify(&expected_table, link_caps,
+ INTEL_DP_LINK_CAPS_UPDATE_MERGE);
+ }
+}
+
+static void intel_dp_link_caps_test_update_lanes_expand(struct kunit *test)
+{
+ test_update_lanes_expand(test, false);
+}
+
+static void intel_dp_link_caps_test_update_lanes_expand_disable(struct kunit *test)
+{
+ test_update_lanes_expand(test, true);
+}
+
+static void disable_random_configs_and_verify(struct test_config_table *expected_table,
+ struct intel_dp_link_caps *link_caps)
+{
+ struct kunit *test = expected_table->test;
+ struct test_ctx *ctx = test->priv;
+ struct link_config_set config_set = {};
+ u32 disabled_config_mask;
+ int num_configs;
+ int i;
+
+ num_configs = get_num_configs(expected_table->rates.size,
+ expected_table->max_lane_count);
+ disabled_config_mask = prandom_u32_state(&ctx->rnd) &
+ GENMASK_U32(num_configs - 1, 0);
+
+ for (i = 0; i < num_configs; i++) {
+ struct intel_dp_link_config config;
+
+ /* At least one config must remain enabled. */
+ if (expected_table->disabled_configs.size +
+ config_set.size + 1 >= num_configs)
+ break;
+
+ if (!(BIT(i) & disabled_config_mask))
+ continue;
+
+ get_nth_rate_lane_config(expected_table, i, &config);
+ /* Don't disable a config twice. */
+ if (has_config(&expected_table->disabled_configs, &config))
+ continue;
+
+ add_config(test, &config_set, &config);
+ }
+
+ disable_configs_and_verify(test, link_caps, expected_table,
+ &config_set);
+}
+
+static void get_params_shrink_step(struct test_ctx *ctx,
+ int num_rates, int max_lane_count,
+ int *rates_step, int *lanes_step)
+{
+ int shrink_mask;
+
+ *rates_step = 0;
+ *lanes_step = 0;
+
+ if (num_rates == 1)
+ shrink_mask = BIT(0); /* shrink only lanes */
+ else if (max_lane_count == 1)
+ shrink_mask = BIT(1); /* shrink only rates */
+ else
+ shrink_mask = rand_in_range(ctx,
+ BIT(0),
+ BIT(0) | BIT(1)); /* shrink one or both params */
+
+ if (shrink_mask & BIT(1))
+ *rates_step = rand_in_range(ctx, 1, num_rates - 1);
+
+ if (shrink_mask & BIT(0))
+ *lanes_step = rand_in_range(ctx, 1, ilog2(max_lane_count));
+}
+
+static void get_params_expand_step(struct test_ctx *ctx,
+ int max_num_rates, int num_rates,
+ int max_supported_lane_count, int max_lane_count,
+ int *rates_step, int *lanes_step)
+{
+ int expand_mask;
+
+ *rates_step = 0;
+ *lanes_step = 0;
+
+ if (num_rates == max_num_rates)
+ expand_mask = BIT(0); /* expand only lanes */
+ else if (max_lane_count == max_supported_lane_count)
+ expand_mask = BIT(1); /* expand only rates */
+ else
+ expand_mask = rand_in_range(ctx,
+ BIT(0),
+ BIT(0) | BIT(1)); /* expand one or both params */
+
+ if (expand_mask & BIT(1))
+ *rates_step = rand_in_range(ctx, 1, max_num_rates - num_rates);
+
+ if (expand_mask & BIT(0))
+ *lanes_step = rand_in_range(ctx, 1, ilog2(max_supported_lane_count /
+ max_lane_count));
+}
+
+static void test_update_params_shrink_random(struct kunit *test, bool disable_configs)
+{
+ struct test_ctx *ctx = test->priv;
+ struct intel_dp_link_caps *link_caps = ctx->dev.dp.link.caps;
+ struct test_config_table expected_table =
+ INIT_STANDARD_TABLE(test, LINK_TEST_NUM_STANDARD_RATES,
+ LINK_TEST_MAX_LANE_COUNT);
+
+ update_link_caps_and_verify(&expected_table, link_caps,
+ INTEL_DP_LINK_CAPS_UPDATE_RESET);
+
+ while (expected_table.rates.size > 1 || expected_table.max_lane_count > 1) {
+ int rates_step;
+ int lanes_step;
+
+ if (disable_configs)
+ disable_random_configs_and_verify(&expected_table, link_caps);
+
+ get_params_shrink_step(ctx,
+ expected_table.rates.size,
+ expected_table.max_lane_count,
+ &rates_step, &lanes_step);
+
+ expected_table.rates.size -= rates_step;
+ expected_table.max_lane_count >>= lanes_step;
+
+ update_link_caps_and_verify(&expected_table, link_caps,
+ INTEL_DP_LINK_CAPS_UPDATE_MERGE);
+ }
+}
+
+static void intel_dp_link_caps_test_update_params_shrink_random(struct kunit *test)
+{
+ int i;
+
+ for (i = 0; i < LINK_TEST_NUM_RANDOM_ITERATIONS; i++)
+ test_update_params_shrink_random(test, false);
+}
+
+static void intel_dp_link_caps_test_update_params_shrink_disable_random(struct kunit *test)
+{
+ int i;
+
+ for (i = 0; i < LINK_TEST_NUM_RANDOM_ITERATIONS; i++)
+ test_update_params_shrink_random(test, true);
+}
+
+static void test_update_params_expand_random(struct kunit *test, bool disable_configs)
+{
+ struct test_ctx *ctx = test->priv;
+ struct intel_dp_link_caps *link_caps = ctx->dev.dp.link.caps;
+ struct test_config_table expected_table =
+ INIT_STANDARD_TABLE(test, 1, 1);
+
+ update_link_caps_and_verify(&expected_table, link_caps,
+ INTEL_DP_LINK_CAPS_UPDATE_RESET);
+
+ while (expected_table.rates.size < LINK_TEST_NUM_STANDARD_RATES ||
+ expected_table.max_lane_count < LINK_TEST_MAX_LANE_COUNT) {
+ int rates_step;
+ int lanes_step;
+
+ if (disable_configs)
+ disable_random_configs_and_verify(&expected_table, link_caps);
+
+ get_params_expand_step(ctx,
+ LINK_TEST_NUM_STANDARD_RATES,
+ expected_table.rates.size,
+ LINK_TEST_MAX_LANE_COUNT,
+ expected_table.max_lane_count,
+ &rates_step, &lanes_step);
+
+ expected_table.rates.size += rates_step;
+ expected_table.max_lane_count <<= lanes_step;
+
+ update_link_caps_and_verify(&expected_table, link_caps,
+ INTEL_DP_LINK_CAPS_UPDATE_MERGE);
+ }
+}
+
+static void intel_dp_link_caps_test_update_params_expand_random(struct kunit *test)
+{
+ int i;
+
+ for (i = 0; i < LINK_TEST_NUM_RANDOM_ITERATIONS; i++)
+ test_update_params_expand_random(test, false);
+}
+
+static void intel_dp_link_caps_test_update_params_expand_disable_random(struct kunit *test)
+{
+ int i;
+
+ for (i = 0; i < LINK_TEST_NUM_RANDOM_ITERATIONS; i++)
+ test_update_params_expand_random(test, true);
+}
+
static struct kunit_case intel_dp_link_test_cases[] = {
KUNIT_CASE(intel_dp_link_caps_test_baseline),
+ KUNIT_CASE(intel_dp_link_caps_test_update_reset),
+
+ KUNIT_CASE(intel_dp_link_caps_test_update_rates_shrink),
+ KUNIT_CASE(intel_dp_link_caps_test_update_rates_shrink_disable),
+ KUNIT_CASE(intel_dp_link_caps_test_update_rates_expand),
+ KUNIT_CASE(intel_dp_link_caps_test_update_rates_expand_disable),
+ KUNIT_CASE(intel_dp_link_caps_test_update_lanes_shrink),
+ KUNIT_CASE(intel_dp_link_caps_test_update_lanes_shrink_disable),
+ KUNIT_CASE(intel_dp_link_caps_test_update_lanes_expand),
+ KUNIT_CASE(intel_dp_link_caps_test_update_lanes_expand_disable),
+ KUNIT_CASE(intel_dp_link_caps_test_update_params_shrink_random),
+ KUNIT_CASE(intel_dp_link_caps_test_update_params_shrink_disable_random),
+ KUNIT_CASE(intel_dp_link_caps_test_update_params_expand_random),
+ KUNIT_CASE(intel_dp_link_caps_test_update_params_expand_disable_random),
+
{}
};
--
2.49.1
next prev parent reply other threads:[~2026-04-28 12:56 UTC|newest]
Thread overview: 113+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-28 12:50 [PATCH 000/108] drm/i915/dp_link: Refactor DP link capability logic Imre Deak
2026-04-28 12:50 ` [PATCH 001/108] drm/i915/dp: Move clamping max link rate to common rates setup Imre Deak
2026-04-28 12:50 ` [PATCH 002/108] drm/i915/dp: Clamp max lane count to max common lane count Imre Deak
2026-04-28 12:50 ` [PATCH 003/108] drm/i915/dp: Bump connector epoch on link capability changes Imre Deak
2026-04-28 12:50 ` [PATCH 004/108] drm/i915/dp_link_training: Introduce link training state struct Imre Deak
2026-04-28 12:50 ` [PATCH 005/108] drm/i915/dp_link_training: Factor out link training state reset helper Imre Deak
2026-04-28 12:50 ` [PATCH 006/108] drm/i915/dp_link_training: Reset link training state on link capability change Imre Deak
2026-04-28 12:50 ` [PATCH 007/108] drm/i915/dp_link_training: Flush commits in debugfs entries Imre Deak
2026-04-28 12:50 ` [PATCH 008/108] drm/i915/dp_link_training: Move link training helpers to link training code Imre Deak
2026-04-28 12:50 ` [PATCH 009/108] drm/i915/dp_link_training: Use link_training as base pointer in debugfs Imre Deak
2026-04-28 12:50 ` [PATCH 010/108] drm/i915/dp_link_training: Add helpers to access force retrain state Imre Deak
2026-04-28 12:50 ` [PATCH 011/108] drm/i915/dp_link_training: Move link recovery/debug state to link_training Imre Deak
2026-04-28 12:50 ` [PATCH 012/108] drm/i915/dp_link_training: Prevent repeated autoretrain attempts Imre Deak
2026-04-28 12:50 ` [PATCH 013/108] drm/i915/dp_link_training: Clamp sequential link training failure counter Imre Deak
2026-04-28 12:50 ` [PATCH 014/108] drm/i915/dp_link_training: Check for pending autoretrain explicitly Imre Deak
2026-04-28 12:50 ` [PATCH 015/108] drm/i915/dp_link_training: Add helper to query pending autoretrain Imre Deak
2026-04-28 12:50 ` [PATCH 016/108] drm/i915/dp_link_training: Add helper to query allowed autoretrain Imre Deak
2026-04-28 12:50 ` [PATCH 017/108] drm/i915/dp_link_training: Add helper to mark link training failure Imre Deak
2026-04-28 12:50 ` [PATCH 018/108] drm/i915/dp_link_training: Add helper to reset link recovery state Imre Deak
2026-04-28 12:51 ` [PATCH 019/108] drm/i915/dp_link_training: Track link recovery state with an enum Imre Deak
2026-04-28 12:51 ` [PATCH 020/108] drm/i915/dp_link_training: Add no-fallback link recovery state Imre Deak
2026-04-28 12:51 ` [PATCH 021/108] drm/i915/display: Factor out a helper to modeset a pipe with atomic state Imre Deak
2026-04-28 12:51 ` [PATCH 022/108] drm/i915/display: Simplify intel_modeset_commit_pipes_for_atomic_state() Imre Deak
2026-04-28 12:51 ` [PATCH 023/108] drm/i915/dp_link_training: Allocate atomic state for autoretrain modeset Imre Deak
2026-04-28 12:51 ` [PATCH 024/108] drm/i915/dp_link_training: Disallow autoretrains after failed modeset Imre Deak
2026-04-28 12:51 ` [PATCH 025/108] drm/i915/dp_link_training: Fix kernel-doc of intel_dp_init_lttpr_and_dprx_caps() Imre Deak
2026-04-28 12:51 ` [PATCH 026/108] drm/i915/dp_link_training: Document DP link recovery logic Imre Deak
2026-04-28 12:51 ` [PATCH 027/108] drm/i915/dp: Rename intel_dp_link_config to intel_dp_link_config_entry Imre Deak
2026-04-28 12:51 ` [PATCH 028/108] drm/i915/dp: Add struct intel_dp_link_config Imre Deak
2026-04-28 12:51 ` [PATCH 029/108] drm/i915/dp_link_caps: Introduce DP link capability module Imre Deak
2026-04-28 12:51 ` [PATCH 030/108] drm/i915/dp_link_caps: Move common rate helpers to link caps Imre Deak
2026-04-28 12:51 ` [PATCH 031/108] drm/i915/dp_link_caps: Move forced link param " Imre Deak
2026-04-28 12:51 ` [PATCH 032/108] drm/i915/dp: Simplify querying of forced link parameters Imre Deak
2026-04-28 12:51 ` [PATCH 033/108] drm/i915/dp_link_caps: Move forced and max link debugfs entries to link caps Imre Deak
2026-04-28 12:51 ` [PATCH 034/108] drm/i915/dp_link_training: Use helpers to get forced link params Imre Deak
2026-04-28 12:51 ` [PATCH 035/108] drm/i915/dp_link_caps: Move forced link params to link_caps Imre Deak
2026-04-28 12:51 ` [PATCH 036/108] drm/i915/dp_link_caps: Move link config helpers to link caps Imre Deak
2026-04-28 12:51 ` [PATCH 037/108] drm/i915/dp_link_caps: Move link config tracking to link_caps Imre Deak
2026-04-28 12:51 ` [PATCH 038/108] drm/i915/dp_link_caps: Rename helper updating the link configurations Imre Deak
2026-04-28 12:51 ` [PATCH 039/108] drm/i915/dp: Factor out helper to get link rate capabilities Imre Deak
2026-04-28 12:51 ` [PATCH 040/108] drm/i915/dp_link_caps: Pass supported link rates to link caps update Imre Deak
2026-04-28 12:51 ` [PATCH 041/108] drm/i915/dp_link_caps: Add helper to get all supported link rates Imre Deak
2026-04-28 12:51 ` [PATCH 042/108] drm/i915/dp_link_caps: Add helper to get the number of " Imre Deak
2026-04-28 12:51 ` [PATCH 043/108] drm/i915/dp_link_caps: Add helper to get common rate index Imre Deak
2026-04-28 12:51 ` [PATCH 044/108] drm/i915/dp_link_caps: Move tracking of common rates to link_caps struct Imre Deak
2026-04-28 12:51 ` [PATCH 045/108] drm/i915/dp_link_caps: Track max common lane count in link_caps Imre Deak
2026-04-28 12:51 ` [PATCH 046/108] drm/i915/dp_link_caps: Move max lane count change detection to link_caps Imre Deak
2026-04-28 12:51 ` [PATCH 047/108] drm/i915/dp_link_caps: Use max common lane count from link_caps Imre Deak
2026-04-28 12:51 ` [PATCH 048/108] drm/i915/dp_link_caps: Move updating max link limits to link_caps update Imre Deak
2026-04-28 12:51 ` [PATCH 049/108] drm/i915/dp_link_caps: Add helpers to get max link limits Imre Deak
2026-04-28 12:51 ` [PATCH 050/108] drm/i915/dp_link_caps: Add helpers to set " Imre Deak
2026-04-28 12:51 ` [PATCH 051/108] drm/i915/dp_link_caps: Validate " Imre Deak
2026-04-28 12:51 ` [PATCH 052/108] drm/i915/dp_link_caps: Add helper to reset " Imre Deak
2026-04-28 12:51 ` [PATCH 053/108] drm/i915/dp_link_caps: Add helper to reset link_caps state Imre Deak
2026-04-28 12:51 ` [PATCH 054/108] drm/i915/dp_link_caps: Move max link limits to link_caps Imre Deak
2026-04-28 12:51 ` [PATCH 055/108] drm/i915/dp_link_caps: Pass link_caps to static functions Imre Deak
2026-04-28 12:51 ` [PATCH 056/108] drm/i915/dp_link_caps: Pass link_caps to config update/lookup helpers Imre Deak
2026-04-28 12:51 ` [PATCH 057/108] drm/i915/dp_link_caps: Pass link_caps to common rate helpers Imre Deak
2026-04-28 12:51 ` [PATCH 058/108] drm/i915/dp_link_caps: Add link_caps prefix " Imre Deak
2026-04-28 12:51 ` [PATCH 059/108] drm/i915/dp_link_caps: Add missing documentation to exported functions Imre Deak
2026-04-28 12:51 ` [PATCH 060/108] drm/i915/dp_link_caps: Set forced link params before resetting link params Imre Deak
2026-04-28 12:51 ` [PATCH 061/108] drm/i915/dp_link_caps: Adjust max_limits during link config update Imre Deak
2026-04-28 12:51 ` [PATCH 062/108] drm/i915/dp_link_caps: Adjust max_limits when setting or resetting it Imre Deak
2026-04-28 12:51 ` [PATCH 063/108] drm/i915/dp: Simplify the modeset max link rate limit computation Imre Deak
2026-04-28 12:51 ` [PATCH 064/108] drm/i915/dp: Query max limits via link_caps during mode validation Imre Deak
2026-04-28 12:51 ` [PATCH 065/108] drm/i915/dp_tunnel: Query max link limits via link_caps for BW computation Imre Deak
2026-04-28 12:51 ` [PATCH 066/108] drm/i915/doc: Document DP link capabilities Imre Deak
2026-04-28 12:51 ` [PATCH 067/108] drm/i915/dp_link_caps: Move config table members to a substruct Imre Deak
2026-04-28 12:51 ` [PATCH 068/108] drm/i915/dp_link_caps: Factor out a helper to look up a config table rate Imre Deak
2026-04-28 12:51 ` [PATCH 069/108] drm/i915/dp_link_caps: Pass config table pointer to rate lookup helper Imre Deak
2026-04-28 12:51 ` [PATCH 070/108] drm/i915/dp_link_caps: Factor out helper to get link config from table by index Imre Deak
2026-04-28 12:51 ` [PATCH 071/108] drm/i915/dp_link_caps: Add helper to get config at iterator position Imre Deak
2026-04-28 12:51 ` [PATCH 072/108] drm/i915/dp_link_caps: Add helper to find position of matching config Imre Deak
2026-04-28 12:51 ` [PATCH 073/108] drm/i915/dp_link_training: Reset the max link limits in the fallback code Imre Deak
2026-04-28 12:51 ` [PATCH 074/108] drm/i915/dp_link_training: Use config iterator for BW-order fallback Imre Deak
2026-04-28 12:51 ` [PATCH 075/108] drm/i915/dp_link_training: Look up configurations using fuzzy rate matching Imre Deak
2026-04-28 12:51 ` [PATCH 076/108] drm/i915/dp_link_caps: Pass table pointer to the sort compare function Imre Deak
2026-04-28 12:51 ` [PATCH 077/108] drm/i915/dp_link_caps: Compare config tables instead of link parameters Imre Deak
2026-04-28 12:51 ` [PATCH 078/108] drm/i915/dp_link_caps: Precompute config table before update Imre Deak
2026-04-28 12:52 ` [PATCH 079/108] drm/i915/dp_link_caps: Compare internal config entries during table matching Imre Deak
2026-04-28 12:52 ` [PATCH 080/108] drm/i915/dp_link_caps: Use virtual config indexing in config table Imre Deak
2026-04-28 12:52 ` [PATCH 081/108] drm/i915/dp_link_caps: Simplify idx->link rate/lane count lookup Imre Deak
2026-04-28 12:52 ` [PATCH 082/108] drm/i915/dp_link_caps: Simplify BW order pos->config index array Imre Deak
2026-04-28 12:52 ` [PATCH 083/108] drm/i915/dp_link_caps: Add helper to get iteration order for a connector Imre Deak
2026-04-28 12:52 ` [PATCH 084/108] drm/i915/dp_link_caps: Add reset and merge update modes Imre Deak
2026-04-28 12:52 ` [PATCH 085/108] drm/i915/dp_link_caps: Add mask for disabled link configurations Imre Deak
2026-04-28 12:52 ` [PATCH 086/108] drm/i915/dp_link_caps: Add link configuration iterators Imre Deak
2026-04-28 12:52 ` [PATCH 087/108] drm/i915/dp_link_caps: Preserve disabled config mask during merge update Imre Deak
2026-04-28 12:52 ` [PATCH 088/108] drm/i915/dp_link_caps: Account for disabled configs during max link info update Imre Deak
2026-04-28 12:52 ` [PATCH 089/108] drm/i915/dp_link_caps: Add debugfs entry showing allowed configurations Imre Deak
2026-04-28 12:52 ` [PATCH 090/108] drm/i915/dp: Add a mask of valid configurations for modeset computation Imre Deak
2026-04-28 12:52 ` [PATCH 091/108] drm/i915/dp: Iterate configurations via link_caps for SST non-DSC Imre Deak
2026-04-28 12:52 ` [PATCH 092/108] drm/i915/dp: Iterate configurations via link_caps for SST DSC Imre Deak
2026-04-28 12:52 ` [PATCH 093/108] drm/i915/dp: Use link caps for eDP DSC config selection Imre Deak
2026-04-28 12:52 ` [PATCH 094/108] drm/i915/dp_mst: Use link caps for non-DSC " Imre Deak
2026-04-28 12:52 ` [PATCH 095/108] drm/i915/dp_mst: Use link caps for MST DSC " Imre Deak
2026-04-28 12:52 ` [PATCH 096/108] drm/i915/dp_test: Use link caps for compliance link configs Imre Deak
2026-04-28 12:52 ` [PATCH 097/108] drm/i915/dp: Remove min/max link config limits Imre Deak
2026-04-28 12:52 ` [PATCH 098/108] drm/i915/dp_link_training: Account for disabled configs during SST fallback Imre Deak
2026-04-28 12:52 ` [PATCH 099/108] drm/i915/dp_link_training: Disable failed config during fallback Imre Deak
2026-04-28 12:52 ` [PATCH 100/108] drm/i915/kunit: Enable KUnit tests Imre Deak
2026-04-28 12:52 ` [PATCH 101/108] drm/i915/kunit: Add DP link test stub Imre Deak
2026-04-29 7:36 ` [PATCH v2 " Imre Deak
2026-04-28 12:52 ` [PATCH 102/108] drm/xe/kunit: Add display test config Imre Deak
2026-04-28 12:52 ` [PATCH 103/108] drm/xe/kunit: Build DP link display tests Imre Deak
2026-04-28 12:52 ` [PATCH 104/108] drm/i915/kunit: setup DP link test context Imre Deak
2026-04-28 12:52 ` [PATCH 105/108] drm/i915/kunit: Export link training and caps funcs for testing Imre Deak
2026-04-28 12:52 ` [PATCH 106/108] drm/i915/kunit: DP link: add baseline fixed table reference test Imre Deak
2026-04-28 12:52 ` Imre Deak [this message]
2026-04-28 12:52 ` [PATCH 108/108] drm/i915/kunit: DP link: add fallback tests Imre Deak
2026-04-28 14:38 ` ✗ Fi.CI.BUILD: failure for drm/i915/dp_link: Refactor DP link capability logic Patchwork
2026-04-29 9:17 ` ✓ i915.CI.BAT: success for drm/i915/dp_link: Refactor DP link capability logic (rev2) Patchwork
2026-04-29 15:35 ` ✗ i915.CI.Full: failure " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260428125233.1664668-108-imre.deak@intel.com \
--to=imre.deak@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=intel-xe@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox