* [PATCH i-g-t 0/3] add dsc-fallback test
@ 2025-01-23 7:36 Kunal Joshi
2025-01-23 7:36 ` [PATCH i-g-t 1/3] tests/intel/kms_mst_helper: Add helper for MST-related functions Kunal Joshi
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: Kunal Joshi @ 2025-01-23 7:36 UTC (permalink / raw)
To: igt-dev; +Cc: Kunal Joshi
Add test to check we fallback to dsc when current
link params cannot accomadate bw required by
the current mode.
Kunal Joshi (3):
tests/intel/kms_mst_helper: Add helper for MST-related functions
tests/intel/kms_dp_linktrain_fallback: add dsc-fallback test
HAX: Do not merge
tests/intel-ci/fast-feedback.testlist | 3 +-
tests/intel-ci/xe-fast-feedback.testlist | 3 +-
tests/intel/kms_dp_linktrain_fallback.c | 380 +++++++++++++++++++----
tests/meson.build | 3 +
4 files changed, 319 insertions(+), 70 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH i-g-t 1/3] tests/intel/kms_mst_helper: Add helper for MST-related functions 2025-01-23 7:36 [PATCH i-g-t 0/3] add dsc-fallback test Kunal Joshi @ 2025-01-23 7:36 ` Kunal Joshi 2025-01-27 7:17 ` Sharma, Swati2 2025-01-23 7:37 ` [PATCH i-g-t 2/3] tests/intel/kms_dp_linktrain_fallback: add dsc-fallback test Kunal Joshi ` (2 subsequent siblings) 3 siblings, 1 reply; 10+ messages in thread From: Kunal Joshi @ 2025-01-23 7:36 UTC (permalink / raw) To: igt-dev; +Cc: Kunal Joshi This patch introduces kms_mst_helper.c and kms_mst_helper.h to centralize commonly used MST-related logic. The new function igt_find_all_mst_output_in_topology() enumerates MST outputs that share the same root connector, simplifying code reuse across tests needing outputs on same MST topology. The existing MST-related code in kms_dp_linktrain_fallback.c is updated to use the new helper, removing duplication. Additionally, meson.build is modified to include kms_mst_helper.c in the build process. Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com> --- tests/intel/kms_dp_linktrain_fallback.c | 28 ++++--------------------- tests/meson.build | 1 + 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/tests/intel/kms_dp_linktrain_fallback.c b/tests/intel/kms_dp_linktrain_fallback.c index a05e2015f..b10946781 100644 --- a/tests/intel/kms_dp_linktrain_fallback.c +++ b/tests/intel/kms_dp_linktrain_fallback.c @@ -16,6 +16,7 @@ #include <sys/types.h> #include "igt.h" +#include "kms_mst_helper.h" /** * SUBTEST: dp-fallback @@ -47,28 +48,6 @@ typedef int (*condition_check_fn)(int drm_fd, igt_output_t *output); IGT_TEST_DESCRIPTION("Test link training fallback"); -static void find_mst_outputs(int drm_fd, data_t *data, - igt_output_t *output, - igt_output_t *mst_outputs[], - int *num_mst_outputs) -{ - int output_root_id, root_id; - igt_output_t *connector_output; - - output_root_id = igt_get_dp_mst_connector_id(output); - /* - * If output is MST check all other connected output which shares - * same path and fill mst_outputs and num_mst_outputs - */ - for_each_connected_output(&data->display, connector_output) { - if (!igt_check_output_is_dp_mst(connector_output)) - continue; - root_id = igt_get_dp_mst_connector_id(connector_output); - if (((*num_mst_outputs) < IGT_MAX_PIPES) && root_id == output_root_id) - mst_outputs[(*num_mst_outputs)++] = connector_output; - } -} - static bool setup_mst_outputs(data_t *data, igt_output_t *mst_output[], int *output_count) { @@ -83,8 +62,9 @@ static bool setup_mst_outputs(data_t *data, igt_output_t *mst_output[], traversed_mst_outputs[i] == data->output->config.connector->connector_id) return false; - find_mst_outputs(data->drm_fd, data, data->output, - mst_output, output_count); + igt_assert_f(igt_find_all_mst_output_in_topology(data->drm_fd, &data->display, data->output, + mst_output, output_count), + "Unable to find mst outputs\n"); for (i = 0; i < *output_count; i++) { output = mst_output[i]; diff --git a/tests/meson.build b/tests/meson.build index 33dffad31..2cbd21c2a 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -367,6 +367,7 @@ extra_sources = { 'kms_chamelium_frames': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ], 'kms_chamelium_hpd': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ], 'kms_dsc': [ join_paths ('intel', 'kms_dsc_helper.c') ], + 'kms_dp_linktrain_fallback': [join_paths ('intel', 'kms_mst_helper.c')], 'kms_psr2_sf': [ join_paths ('intel', 'kms_dsc_helper.c') ], } -- 2.25.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH i-g-t 1/3] tests/intel/kms_mst_helper: Add helper for MST-related functions 2025-01-23 7:36 ` [PATCH i-g-t 1/3] tests/intel/kms_mst_helper: Add helper for MST-related functions Kunal Joshi @ 2025-01-27 7:17 ` Sharma, Swati2 2025-01-27 8:04 ` Joshi, Kunal1 0 siblings, 1 reply; 10+ messages in thread From: Sharma, Swati2 @ 2025-01-27 7:17 UTC (permalink / raw) To: Kunal Joshi, igt-dev Hi Kunal, If new helper is introduced, please move dp-mst related func() from igt_kms.c to kms_mst_helper.c On 23-01-2025 01:06 pm, Kunal Joshi wrote: > This patch introduces kms_mst_helper.c and kms_mst_helper.h > to centralize commonly used MST-related logic. > The new function igt_find_all_mst_output_in_topology() > enumerates MST outputs that share the same root connector, > simplifying code reuse across tests needing outputs on > same MST topology. The existing MST-related code in > kms_dp_linktrain_fallback.c is updated to use the new helper, > removing duplication. Additionally, meson.build is modified > to include kms_mst_helper.c in the build process. > > Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com> > --- > tests/intel/kms_dp_linktrain_fallback.c | 28 ++++--------------------- > tests/meson.build | 1 + > 2 files changed, 5 insertions(+), 24 deletions(-) > > diff --git a/tests/intel/kms_dp_linktrain_fallback.c b/tests/intel/kms_dp_linktrain_fallback.c > index a05e2015f..b10946781 100644 > --- a/tests/intel/kms_dp_linktrain_fallback.c > +++ b/tests/intel/kms_dp_linktrain_fallback.c > @@ -16,6 +16,7 @@ > #include <sys/types.h> > > #include "igt.h" > +#include "kms_mst_helper.h" > > /** > * SUBTEST: dp-fallback > @@ -47,28 +48,6 @@ typedef int (*condition_check_fn)(int drm_fd, igt_output_t *output); > > IGT_TEST_DESCRIPTION("Test link training fallback"); > > -static void find_mst_outputs(int drm_fd, data_t *data, > - igt_output_t *output, > - igt_output_t *mst_outputs[], > - int *num_mst_outputs) > -{ > - int output_root_id, root_id; > - igt_output_t *connector_output; > - > - output_root_id = igt_get_dp_mst_connector_id(output); > - /* > - * If output is MST check all other connected output which shares > - * same path and fill mst_outputs and num_mst_outputs > - */ > - for_each_connected_output(&data->display, connector_output) { > - if (!igt_check_output_is_dp_mst(connector_output)) > - continue; > - root_id = igt_get_dp_mst_connector_id(connector_output); > - if (((*num_mst_outputs) < IGT_MAX_PIPES) && root_id == output_root_id) > - mst_outputs[(*num_mst_outputs)++] = connector_output; > - } > -} > - > static bool setup_mst_outputs(data_t *data, igt_output_t *mst_output[], > int *output_count) > { > @@ -83,8 +62,9 @@ static bool setup_mst_outputs(data_t *data, igt_output_t *mst_output[], > traversed_mst_outputs[i] == data->output->config.connector->connector_id) > return false; > > - find_mst_outputs(data->drm_fd, data, data->output, > - mst_output, output_count); > + igt_assert_f(igt_find_all_mst_output_in_topology(data->drm_fd, &data->display, data->output, > + mst_output, output_count), > + "Unable to find mst outputs\n"); > > for (i = 0; i < *output_count; i++) { > output = mst_output[i]; > diff --git a/tests/meson.build b/tests/meson.build > index 33dffad31..2cbd21c2a 100644 > --- a/tests/meson.build > +++ b/tests/meson.build > @@ -367,6 +367,7 @@ extra_sources = { > 'kms_chamelium_frames': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ], > 'kms_chamelium_hpd': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ], > 'kms_dsc': [ join_paths ('intel', 'kms_dsc_helper.c') ], > + 'kms_dp_linktrain_fallback': [join_paths ('intel', 'kms_mst_helper.c')], > 'kms_psr2_sf': [ join_paths ('intel', 'kms_dsc_helper.c') ], > } > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH i-g-t 1/3] tests/intel/kms_mst_helper: Add helper for MST-related functions 2025-01-27 7:17 ` Sharma, Swati2 @ 2025-01-27 8:04 ` Joshi, Kunal1 0 siblings, 0 replies; 10+ messages in thread From: Joshi, Kunal1 @ 2025-01-27 8:04 UTC (permalink / raw) To: Sharma, Swati2, igt-dev On 27-01-2025 12:47, Sharma, Swati2 wrote: > Hi Kunal, > > If new helper is introduced, please move dp-mst related func() from > igt_kms.c to > > kms_mst_helper.c Hello Swati, That is already in plan but will not take that as part of this series. Will float a separate series for all MST functions to be present in MST helper. Many of them needs modification before integration in the helper. Thanks and Regards Kunal Joshi > > On 23-01-2025 01:06 pm, Kunal Joshi wrote: >> This patch introduces kms_mst_helper.c and kms_mst_helper.h >> to centralize commonly used MST-related logic. >> The new function igt_find_all_mst_output_in_topology() >> enumerates MST outputs that share the same root connector, >> simplifying code reuse across tests needing outputs on >> same MST topology. The existing MST-related code in >> kms_dp_linktrain_fallback.c is updated to use the new helper, >> removing duplication. Additionally, meson.build is modified >> to include kms_mst_helper.c in the build process. >> >> Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com> >> --- >> tests/intel/kms_dp_linktrain_fallback.c | 28 ++++--------------------- >> tests/meson.build | 1 + >> 2 files changed, 5 insertions(+), 24 deletions(-) >> >> diff --git a/tests/intel/kms_dp_linktrain_fallback.c >> b/tests/intel/kms_dp_linktrain_fallback.c >> index a05e2015f..b10946781 100644 >> --- a/tests/intel/kms_dp_linktrain_fallback.c >> +++ b/tests/intel/kms_dp_linktrain_fallback.c >> @@ -16,6 +16,7 @@ >> #include <sys/types.h> >> #include "igt.h" >> +#include "kms_mst_helper.h" >> /** >> * SUBTEST: dp-fallback >> @@ -47,28 +48,6 @@ typedef int (*condition_check_fn)(int drm_fd, >> igt_output_t *output); >> IGT_TEST_DESCRIPTION("Test link training fallback"); >> -static void find_mst_outputs(int drm_fd, data_t *data, >> - igt_output_t *output, >> - igt_output_t *mst_outputs[], >> - int *num_mst_outputs) >> -{ >> - int output_root_id, root_id; >> - igt_output_t *connector_output; >> - >> - output_root_id = igt_get_dp_mst_connector_id(output); >> - /* >> - * If output is MST check all other connected output which shares >> - * same path and fill mst_outputs and num_mst_outputs >> - */ >> - for_each_connected_output(&data->display, connector_output) { >> - if (!igt_check_output_is_dp_mst(connector_output)) >> - continue; >> - root_id = igt_get_dp_mst_connector_id(connector_output); >> - if (((*num_mst_outputs) < IGT_MAX_PIPES) && root_id == >> output_root_id) >> - mst_outputs[(*num_mst_outputs)++] = connector_output; >> - } >> -} >> - >> static bool setup_mst_outputs(data_t *data, igt_output_t >> *mst_output[], >> int *output_count) >> { >> @@ -83,8 +62,9 @@ static bool setup_mst_outputs(data_t *data, >> igt_output_t *mst_output[], >> traversed_mst_outputs[i] == >> data->output->config.connector->connector_id) >> return false; >> - find_mst_outputs(data->drm_fd, data, data->output, >> - mst_output, output_count); >> + igt_assert_f(igt_find_all_mst_output_in_topology(data->drm_fd, >> &data->display, data->output, >> + mst_output, output_count), >> + "Unable to find mst outputs\n"); >> for (i = 0; i < *output_count; i++) { >> output = mst_output[i]; >> diff --git a/tests/meson.build b/tests/meson.build >> index 33dffad31..2cbd21c2a 100644 >> --- a/tests/meson.build >> +++ b/tests/meson.build >> @@ -367,6 +367,7 @@ extra_sources = { >> 'kms_chamelium_frames': [ join_paths ('chamelium', >> 'kms_chamelium_helper.c') ], >> 'kms_chamelium_hpd': [ join_paths ('chamelium', >> 'kms_chamelium_helper.c') ], >> 'kms_dsc': [ join_paths ('intel', 'kms_dsc_helper.c') ], >> + 'kms_dp_linktrain_fallback': [join_paths ('intel', >> 'kms_mst_helper.c')], >> 'kms_psr2_sf': [ join_paths ('intel', 'kms_dsc_helper.c') ], >> } ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH i-g-t 2/3] tests/intel/kms_dp_linktrain_fallback: add dsc-fallback test 2025-01-23 7:36 [PATCH i-g-t 0/3] add dsc-fallback test Kunal Joshi 2025-01-23 7:36 ` [PATCH i-g-t 1/3] tests/intel/kms_mst_helper: Add helper for MST-related functions Kunal Joshi @ 2025-01-23 7:37 ` Kunal Joshi 2025-01-23 7:37 ` [PATCH i-g-t 3/3] HAX: Do not merge Kunal Joshi 2025-01-23 8:22 ` ✗ GitLab.Pipeline: warning for add dsc-fallback test Patchwork 3 siblings, 0 replies; 10+ messages in thread From: Kunal Joshi @ 2025-01-23 7:37 UTC (permalink / raw) To: igt-dev; +Cc: Kunal Joshi, Ankit Nautiyal add new dsc-fallback test which finds a mode which can be driven without DSC at current link params and reduces link param till we have combination (link_rate, lane_count) which requires DSC to be enabled. Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com> Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com> --- tests/intel/kms_dp_linktrain_fallback.c | 352 +++++++++++++++++++++--- tests/meson.build | 4 +- 2 files changed, 311 insertions(+), 45 deletions(-) diff --git a/tests/intel/kms_dp_linktrain_fallback.c b/tests/intel/kms_dp_linktrain_fallback.c index b10946781..471381f1d 100644 --- a/tests/intel/kms_dp_linktrain_fallback.c +++ b/tests/intel/kms_dp_linktrain_fallback.c @@ -17,10 +17,14 @@ #include "igt.h" #include "kms_mst_helper.h" +#include "kms_dsc_helper.h" /** * SUBTEST: dp-fallback * Description: Test fallback on DP connectors + * + * SUBTEST: dsc-fallback + * Description: Test we fallback to DSC when BW isn't sufficient */ #define RETRAIN_COUNT 1 @@ -238,16 +242,124 @@ static int check_condition_with_timeout(int drm_fd, igt_output_t *output, } } +/* + * Force a link training failure followed by link retrain, then + * block until the driver has no further pending retrain/failure. + * Returns false if we time out waiting. + */ +static bool force_failure_and_wait(data_t *data, + igt_output_t *output, + int failure_type, + int retrain_count, + double interval, + double timeout) +{ + igt_force_lt_failure(data->drm_fd, output, failure_type); + igt_force_link_retrain(data->drm_fd, output, retrain_count); + + /* Wait until there's no pending retrain */ + if (check_condition_with_timeout(data->drm_fd, output, + igt_get_dp_pending_retrain, + interval, timeout)) { + igt_info("Timed out waiting for pending retrain.\n"); + return false; + } + + /* Wait until there's no pending LT failures */ + if (check_condition_with_timeout(data->drm_fd, output, + igt_get_dp_pending_lt_failures, + interval, timeout)) { + igt_info("Timed out waiting for pending LT failures.\n"); + return false; + } + + return true; +} + +/* + * Waits for a hotplug event, then checks that the link-status is BAD. + * Returns false if the link-status isn't BAD or no hotplug arrives in time. + */ +static bool wait_for_hotplug_and_check_bad(int drm_fd, + data_t *data, + igt_output_t *output, + struct udev_monitor *mon, + double hotplug_timeout) +{ + uint32_t link_status_prop_id; + uint64_t link_status_value; + drmModePropertyPtr link_status_prop; + + if (!igt_hotplug_detected(mon, hotplug_timeout)) { + igt_info("No hotplug event within %.2f seconds.\n", hotplug_timeout); + return false; + } + + kmstest_get_property(drm_fd, + output->config.connector->connector_id, + DRM_MODE_OBJECT_CONNECTOR, + "link-status", + &link_status_prop_id, &link_status_value, + &link_status_prop); + + if (link_status_value != DRM_MODE_LINK_STATUS_BAD) { + igt_info("Expected link-status=BAD but got %" PRIu64 "\n", + link_status_value); + return false; + } + + return true; +} + +/* + * Sets link status=GOOD for the specified outputs, then calls + * validate_modeset_for_outputs() to re-commit. Returns false + * if the re-commit fails. + */ +static bool fix_link_status_and_recommit(data_t *data, + igt_output_t *outputs[], + int *output_count, + drmModeModeInfo * modes[], + struct igt_fb fbs[], + struct igt_plane *primarys[]) +{ + int i; + igt_output_t *out; + + /* Set link-status=GOOD on each tested output */ + for_each_connected_output(&data->display, out) { + for (i = 0; i < *output_count; i++) { + if (out->id == outputs[i]->id) { + igt_output_set_prop_value( + out, IGT_CONNECTOR_LINK_STATUS, + DRM_MODE_LINK_STATUS_GOOD); + } + } + } + + if (!validate_modeset_for_outputs(data, outputs, output_count, + modes, fbs, primarys)) { + igt_info("Modeset validation failed after forcing link-status=GOOD.\n"); + return false; + } + + if (igt_display_try_commit_atomic(&data->display, + DRM_MODE_ATOMIC_ALLOW_MODESET, + NULL) != 0) { + igt_info("Commit failed after restoring link-status=GOOD.\n"); + return false; + } + + return true; +} + static void test_fallback(data_t *data, bool is_mst) { int output_count, retries; int max_link_rate, curr_link_rate, prev_link_rate; int max_lane_count, curr_lane_count, prev_lane_count; igt_output_t *outputs[IGT_MAX_PIPES]; - uint32_t link_status_prop_id; - uint64_t link_status_value; - drmModeModeInfo *modes[IGT_MAX_PIPES]; - drmModePropertyPtr link_status_prop; + drmModeModeInfo * modes[IGT_MAX_PIPES]; struct igt_fb fbs[IGT_MAX_PIPES]; struct igt_plane *primarys[IGT_MAX_PIPES]; struct udev_monitor *mon; @@ -256,71 +368,71 @@ static void test_fallback(data_t *data, bool is_mst) igt_display_reset(&data->display); igt_reset_link_params(data->drm_fd, data->output); - if (!setup_outputs(data, is_mst, outputs, - &output_count, modes, fbs, - primarys)) + igt_force_link_retrain(data->drm_fd, data->output, 1); + + if (!setup_outputs(data, is_mst, outputs, &output_count, + modes, fbs, primarys)) return; igt_info("Testing link training fallback on %s\n", igt_output_name(data->output)); max_link_rate = igt_get_max_link_rate(data->drm_fd, data->output); max_lane_count = igt_get_max_lane_count(data->drm_fd, data->output); + prev_link_rate = igt_get_current_link_rate(data->drm_fd, data->output); prev_lane_count = igt_get_current_lane_count(data->drm_fd, data->output); - while (!igt_get_dp_link_retrain_disabled(data->drm_fd, - data->output)) { + while (!igt_get_dp_link_retrain_disabled(data->drm_fd, data->output)) { igt_info("Current link rate: %d, Current lane count: %d\n", - prev_link_rate, - prev_lane_count); + prev_link_rate, prev_lane_count); + mon = igt_watch_uevents(); - igt_force_lt_failure(data->drm_fd, data->output, - LT_FAILURE_REDUCED_CAPS); - igt_force_link_retrain(data->drm_fd, data->output, - RETRAIN_COUNT); - - igt_assert_eq(check_condition_with_timeout(data->drm_fd, - data->output, - igt_get_dp_pending_retrain, - 1.0, 20.0), 0); - igt_assert_eq(check_condition_with_timeout(data->drm_fd, - data->output, - igt_get_dp_pending_lt_failures, - 1.0, 20.0), 0); + + /* Force link failure, wait for retrain to clear */ + igt_assert_f(force_failure_and_wait(data, data->output, + LT_FAILURE_REDUCED_CAPS, + RETRAIN_COUNT, + 1.0, 20.0), + "Link training failure steps timed out\n"); if (igt_get_dp_link_retrain_disabled(data->drm_fd, data->output)) { igt_reset_connectors(); + igt_flush_uevents(mon); return; } - igt_assert_f(igt_hotplug_detected(mon, 20), - "Didn't get hotplug for force link training failure\n"); - - kmstest_get_property(data->drm_fd, - data->output->config.connector->connector_id, - DRM_MODE_OBJECT_CONNECTOR, "link-status", - &link_status_prop_id, &link_status_value, - &link_status_prop); - igt_assert_eq(link_status_value, DRM_MODE_LINK_STATUS_BAD); + /* Wait for hotplug + check link-status=BAD */ + igt_assert_f(wait_for_hotplug_and_check_bad(data->drm_fd, + data, + data->output, + mon, + 20.0), + "Didn't get hotplug or link-status=BAD\n"); igt_flush_uevents(mon); - set_connector_link_status_good(data, outputs, &output_count); - igt_assert_f(validate_modeset_for_outputs(data, + + /* Set link-status=GOOD and re-commit */ + igt_assert_f(fix_link_status_and_recommit(data, outputs, &output_count, modes, fbs, primarys), "modeset failed\n"); - igt_display_commit2(&data->display, COMMIT_ATOMIC); - igt_assert_eq(data->output->values[IGT_CONNECTOR_LINK_STATUS], DRM_MODE_LINK_STATUS_GOOD); - curr_link_rate = igt_get_current_link_rate(data->drm_fd, data->output); - curr_lane_count = igt_get_current_lane_count(data->drm_fd, data->output); + /* Ensure link-status is GOOD again */ + igt_assert_eq(data->output->values[IGT_CONNECTOR_LINK_STATUS], + DRM_MODE_LINK_STATUS_GOOD); + + curr_link_rate = igt_get_current_link_rate(data->drm_fd, + data->output); + curr_lane_count = igt_get_current_lane_count(data->drm_fd, + data->output); igt_assert_f((curr_link_rate < prev_link_rate || - curr_lane_count < prev_lane_count) || - ((curr_link_rate == max_link_rate && curr_lane_count == max_lane_count) && --retries), + curr_lane_count < prev_lane_count) || + ((curr_link_rate == max_link_rate && + curr_lane_count == max_lane_count) && --retries), "Fallback unsuccessful\n"); prev_link_rate = curr_link_rate; @@ -328,7 +440,117 @@ static void test_fallback(data_t *data, bool is_mst) } } -static bool run_test(data_t *data) +static void test_dsc_sst_fallback(data_t *data) +{ + bool non_dsc_mode_found = false; + bool dsc_fallback_successful = false; + int ret; + struct udev_monitor *mon; + drmModeModeInfo *mode_to_check; + igt_output_t *outputs[IGT_MAX_PIPES]; + int output_count = 0; + + igt_info("Checking DSC fallback on %s\n", igt_output_name(data->output)); + data->pipe = PIPE_A; + + igt_display_reset(&data->display); + igt_reset_link_params(data->drm_fd, data->output); + igt_force_link_retrain(data->drm_fd, data->output, 1); + + /* Find a mode that doesn't require DSC initially */ + for_each_connector_mode(data->output) { + data->mode = &data->output->config.connector->modes[j__]; + igt_create_color_fb(data->drm_fd, data->mode->hdisplay, + data->mode->vdisplay, DRM_FORMAT_XRGB8888, + DRM_FORMAT_MOD_LINEAR, 0.0, 1.0, 0.0, + &data->fb); + igt_output_override_mode(data->output, data->mode); + igt_output_set_pipe(data->output, data->pipe); + data->primary = igt_output_get_plane_type(data->output, + DRM_PLANE_TYPE_PRIMARY); + igt_plane_set_fb(data->primary, &data->fb); + + ret = igt_display_try_commit_atomic(&data->display, + DRM_MODE_ATOMIC_TEST_ONLY | + DRM_MODE_ATOMIC_ALLOW_MODESET, + NULL); + if (ret != 0) { + igt_info("Skipping mode %dx%d@%d on %s\n", + data->mode->hdisplay, data->mode->vdisplay, + data->mode->vrefresh, + igt_output_name(data->output)); + continue; + } + igt_display_commit2(&data->display, COMMIT_ATOMIC); + + if (!igt_is_dsc_enabled(data->drm_fd, + data->output->name)) { + drmModeModeInfo *non_dsc_mode + = igt_output_get_mode(data->output); + igt_info("Found mode %dx%d@%d %s that doesn't need DSC with link rate %d and lane count %d\n", + non_dsc_mode->hdisplay, non_dsc_mode->vdisplay, + non_dsc_mode->vrefresh, non_dsc_mode->name, + igt_get_current_link_rate(data->drm_fd, data->output), + igt_get_current_lane_count(data->drm_fd, data->output)); + non_dsc_mode_found = true; + break; + } + } + igt_require_f(non_dsc_mode_found, + "No non-DSC mode found on %s\n", + igt_output_name(data->output)); + + + /* Repeatedly force link failure until DSC is required (or link is disabled) */ + while (!igt_get_dp_link_retrain_disabled(data->drm_fd, data->output)) { + mon = igt_watch_uevents(); + + igt_assert_f(force_failure_and_wait(data, data->output, + LT_FAILURE_REDUCED_CAPS, + RETRAIN_COUNT, 1.0, 20.0), + "Forcing DSC fallback timed out\n"); + + if (igt_get_dp_link_retrain_disabled(data->drm_fd, + data->output)) { + igt_reset_connectors(); + igt_flush_uevents(mon); + return; + } + + igt_assert_f(wait_for_hotplug_and_check_bad(data->drm_fd, + data, + data->output, + mon, + 20.0), + "Didn't get hotplug or link-status=BAD for DSC\n"); + igt_flush_uevents(mon); + + outputs[output_count++] = data->output; + set_connector_link_status_good(data, outputs, &output_count); + igt_display_commit2(&data->display, COMMIT_ATOMIC); + + mode_to_check = igt_output_get_mode(data->output); + + if (igt_is_dsc_enabled(data->drm_fd, data->output->name)) { + igt_info("mode %dx%d@%d now requires DSC with link rate %d and lane count %d\n", + mode_to_check->hdisplay, mode_to_check->vdisplay, + mode_to_check->vrefresh, + igt_get_current_link_rate(data->drm_fd, data->output), + igt_get_current_lane_count(data->drm_fd, data->output)); + igt_info("DSC fallback successful on %s\n", + igt_output_name(data->output)); + dsc_fallback_successful = true; + break; + } else { + igt_info("mode %dx%d@%d still doesn't require DSC\n", + mode_to_check->hdisplay, mode_to_check->vdisplay, + mode_to_check->vrefresh); + } + } + igt_assert_f(dsc_fallback_successful, "DSC fallback unsuccessful\n"); +} + +static bool run_lt_fallback_test(data_t *data) { bool ran = false; igt_output_t *output; @@ -366,6 +588,43 @@ static bool run_test(data_t *data) return ran; } +static bool run_dsc_sst_fallaback_test(data_t *data) +{ + bool ran = false; + igt_output_t *output; + + if (!is_dsc_supported_by_source(data->drm_fd)) { + igt_info("DSC not supported by source.\n"); + return ran; + } + + for_each_connected_output(&data->display, output) { + data->output = output; + + if (!igt_has_force_link_training_failure_debugfs(data->drm_fd, + data->output)) { + igt_info("Output %s doesn't support forcing link training.\n", + igt_output_name(data->output)); + continue; + } + + if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) { + igt_info("Skipping output %s as it's not DP\n", output->name); + continue; + } + + if (!is_dsc_supported_by_sink(data->drm_fd, data->output)) { + igt_info("Skipping output %s as DSC not supported by sink\n", + igt_output_name(data->output)); + continue; + } + + ran = true; + test_dsc_sst_fallback(data); + } + return ran; +} + igt_main { data_t data = {}; @@ -381,8 +640,13 @@ igt_main } igt_subtest("dp-fallback") { - igt_require_f(run_test(&data), - "Skipping test as no output found or none supports fallback\n"); + igt_require_f(run_lt_fallback_test(&data), + "Skipping test as no DP output found or none supports forcing link fail\n"); + } + + igt_subtest("dsc-fallback") { + igt_require_f(run_dsc_sst_fallaback_test(&data), + "Skipping test: DSC fallback conditions not met.\n"); } igt_fixture { diff --git a/tests/meson.build b/tests/meson.build index 2cbd21c2a..dd75976dd 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -367,7 +367,9 @@ extra_sources = { 'kms_chamelium_frames': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ], 'kms_chamelium_hpd': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ], 'kms_dsc': [ join_paths ('intel', 'kms_dsc_helper.c') ], - 'kms_dp_linktrain_fallback': [join_paths ('intel', 'kms_mst_helper.c')], + 'kms_dp_linktrain_fallback': [ + join_paths ('intel', 'kms_mst_helper.c'), + join_paths ('intel', 'kms_dsc_helper.c')], 'kms_psr2_sf': [ join_paths ('intel', 'kms_dsc_helper.c') ], } -- 2.25.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH i-g-t 3/3] HAX: Do not merge 2025-01-23 7:36 [PATCH i-g-t 0/3] add dsc-fallback test Kunal Joshi 2025-01-23 7:36 ` [PATCH i-g-t 1/3] tests/intel/kms_mst_helper: Add helper for MST-related functions Kunal Joshi 2025-01-23 7:37 ` [PATCH i-g-t 2/3] tests/intel/kms_dp_linktrain_fallback: add dsc-fallback test Kunal Joshi @ 2025-01-23 7:37 ` Kunal Joshi 2025-01-23 8:22 ` ✗ GitLab.Pipeline: warning for add dsc-fallback test Patchwork 3 siblings, 0 replies; 10+ messages in thread From: Kunal Joshi @ 2025-01-23 7:37 UTC (permalink / raw) To: igt-dev; +Cc: Kunal Joshi Don't merge, just for CI testing --- tests/intel-ci/fast-feedback.testlist | 3 ++- tests/intel-ci/xe-fast-feedback.testlist | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/intel-ci/fast-feedback.testlist b/tests/intel-ci/fast-feedback.testlist index be0965110..668fb3888 100644 --- a/tests/intel-ci/fast-feedback.testlist +++ b/tests/intel-ci/fast-feedback.testlist @@ -1,6 +1,7 @@ # Try to load the driver if it's not available yet. igt@i915_module_load@load - +igt@kms_dp_linktrain_fallback@dsc-fallback +igt@kms_dp_linktrain_fallback@dp-fallbck # Keep alphabetically sorted by default igt@core_auth@basic-auth igt@debugfs_test@read_all_entries diff --git a/tests/intel-ci/xe-fast-feedback.testlist b/tests/intel-ci/xe-fast-feedback.testlist index 0234d3e72..28f8b5015 100644 --- a/tests/intel-ci/xe-fast-feedback.testlist +++ b/tests/intel-ci/xe-fast-feedback.testlist @@ -1,6 +1,7 @@ # Should be the first test igt@xe_module_load@load - +igt@kms_dp_linktrain_fallback@dsc-fallback +igt@kms_dp_linktrain_fallback@dp-fallback igt@fbdev@eof igt@fbdev@info igt@fbdev@nullptr -- 2.25.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* ✗ GitLab.Pipeline: warning for add dsc-fallback test 2025-01-23 7:36 [PATCH i-g-t 0/3] add dsc-fallback test Kunal Joshi ` (2 preceding siblings ...) 2025-01-23 7:37 ` [PATCH i-g-t 3/3] HAX: Do not merge Kunal Joshi @ 2025-01-23 8:22 ` Patchwork 3 siblings, 0 replies; 10+ messages in thread From: Patchwork @ 2025-01-23 8:22 UTC (permalink / raw) To: Kunal Joshi; +Cc: igt-dev == Series Details == Series: add dsc-fallback test URL : https://patchwork.freedesktop.org/series/143877/ State : warning == Summary == Pipeline status: FAILED. see https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/1350699 for the overview. build:tests-debian-meson has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/69822699): Checking whether type "struct sysinfo" has member "totalram" : YES Checking for function "memfd_create" : YES Configuring config.h using configuration Program python3 found: YES (/usr/bin/python3) Program igt_doc.py found: YES (/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py) Program gen_rst_index skipped: feature sphinx disabled Program generate_iga64_codes found: YES (/builds/gfx-ci/igt-ci-tags/scripts/generate_iga64_codes) lib/meson.build:172: WARNING: libdrm <= 2.4.99 found, amdgpu_cs_query_reset_state2 not applicable Configuring i915-perf.pc using configuration Configuring xe-oa.pc using configuration tests/meson.build:426:1: ERROR: File intel/kms_mst_helper.c does not exist. A full log can be found at /builds/gfx-ci/igt-ci-tags/build/meson-logs/meson-log.txt section_end:1737620016:step_script section_start:1737620016:cleanup_file_variables Cleaning up project directory and file based variables section_end:1737620017:cleanup_file_variables ERROR: Job failed: exit code 1 build:tests-debian-meson-arm64 has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/69822702): Checking whether type "struct sysinfo" has member "totalram" : YES Checking for function "memfd_create" : YES Configuring config.h using configuration Program python3 found: YES (/usr/bin/python3) Program igt_doc.py found: YES (/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py) Program gen_rst_index skipped: feature sphinx disabled Program generate_iga64_codes found: YES (/builds/gfx-ci/igt-ci-tags/scripts/generate_iga64_codes) lib/meson.build:172: WARNING: libdrm <= 2.4.99 found, amdgpu_cs_query_reset_state2 not applicable Configuring i915-perf.pc using configuration Configuring xe-oa.pc using configuration tests/meson.build:426:1: ERROR: File intel/kms_mst_helper.c does not exist. A full log can be found at /builds/gfx-ci/igt-ci-tags/build/meson-logs/meson-log.txt section_end:1737620016:step_script section_start:1737620016:cleanup_file_variables Cleaning up project directory and file based variables section_end:1737620016:cleanup_file_variables ERROR: Job failed: exit code 1 build:tests-debian-meson-armhf has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/69822701): Checking whether type "struct sysinfo" has member "totalram" : YES Checking for function "memfd_create" : YES Configuring config.h using configuration Program python3 found: YES (/usr/bin/python3) Program igt_doc.py found: YES (/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py) Program gen_rst_index skipped: feature sphinx disabled Program generate_iga64_codes found: YES (/builds/gfx-ci/igt-ci-tags/scripts/generate_iga64_codes) lib/meson.build:172: WARNING: libdrm <= 2.4.99 found, amdgpu_cs_query_reset_state2 not applicable Configuring i915-perf.pc using configuration Configuring xe-oa.pc using configuration tests/meson.build:426:1: ERROR: File intel/kms_mst_helper.c does not exist. A full log can be found at /builds/gfx-ci/igt-ci-tags/build/meson-logs/meson-log.txt section_end:1737620033:step_script section_start:1737620033:cleanup_file_variables Cleaning up project directory and file based variables section_end:1737620034:cleanup_file_variables ERROR: Job failed: exit code 1 build:tests-debian-meson-mips has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/69822703): Checking whether type "struct sysinfo" has member "totalram" : YES Checking for function "memfd_create" : YES Configuring config.h using configuration Program python3 found: YES (/usr/bin/python3) Program igt_doc.py found: YES (/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py) Program gen_rst_index skipped: feature sphinx disabled Program generate_iga64_codes found: YES (/builds/gfx-ci/igt-ci-tags/scripts/generate_iga64_codes) lib/meson.build:172: WARNING: libdrm <= 2.4.99 found, amdgpu_cs_query_reset_state2 not applicable Configuring i915-perf.pc using configuration Configuring xe-oa.pc using configuration tests/meson.build:426:1: ERROR: File intel/kms_mst_helper.c does not exist. A full log can be found at /builds/gfx-ci/igt-ci-tags/build/meson-logs/meson-log.txt section_end:1737620040:step_script section_start:1737620040:cleanup_file_variables Cleaning up project directory and file based variables section_end:1737620040:cleanup_file_variables ERROR: Job failed: exit code 1 build:tests-fedora has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/69822694): Header <unistd.h> has symbol "gettid" : YES Checking whether type "struct sysinfo" has member "totalram" : YES Checking for function "memfd_create" : YES Configuring config.h using configuration Program python3 found: YES (/usr/bin/python3) Program igt_doc.py found: YES (/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py) Program gen_rst_index skipped: feature sphinx disabled Program generate_iga64_codes found: YES (/builds/gfx-ci/igt-ci-tags/scripts/generate_iga64_codes) Configuring i915-perf.pc using configuration Configuring xe-oa.pc using configuration tests/meson.build:426:1: ERROR: File intel/kms_mst_helper.c does not exist. A full log can be found at /builds/gfx-ci/igt-ci-tags/build/meson-logs/meson-log.txt section_end:1737620042:step_script section_start:1737620042:cleanup_file_variables Cleaning up project directory and file based variables section_end:1737620043:cleanup_file_variables ERROR: Job failed: exit code 1 build:tests-fedora-clang has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/69822698): Header <unistd.h> has symbol "gettid" : YES Checking whether type "struct sysinfo" has member "totalram" : YES Checking for function "memfd_create" : YES Configuring config.h using configuration Program python3 found: YES (/usr/bin/python3) Program igt_doc.py found: YES (/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py) Program gen_rst_index skipped: feature sphinx disabled Program generate_iga64_codes found: YES (/builds/gfx-ci/igt-ci-tags/scripts/generate_iga64_codes) Configuring i915-perf.pc using configuration Configuring xe-oa.pc using configuration tests/meson.build:426:1: ERROR: File intel/kms_mst_helper.c does not exist. A full log can be found at /builds/gfx-ci/igt-ci-tags/build/meson-logs/meson-log.txt section_end:1737620013:step_script section_start:1737620013:cleanup_file_variables Cleaning up project directory and file based variables section_end:1737620014:cleanup_file_variables ERROR: Job failed: exit code 1 build:tests-fedora-no-libdrm-nouveau has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/69822697): Header <unistd.h> has symbol "gettid" : YES Checking whether type "struct sysinfo" has member "totalram" : YES Checking for function "memfd_create" : YES Configuring config.h using configuration Program python3 found: YES (/usr/bin/python3) Program igt_doc.py found: YES (/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py) Program gen_rst_index skipped: feature sphinx disabled Program generate_iga64_codes found: YES (/builds/gfx-ci/igt-ci-tags/scripts/generate_iga64_codes) Configuring i915-perf.pc using configuration Configuring xe-oa.pc using configuration tests/meson.build:426:1: ERROR: File intel/kms_mst_helper.c does not exist. A full log can be found at /builds/gfx-ci/igt-ci-tags/build/meson-logs/meson-log.txt section_end:1737620027:step_script section_start:1737620027:cleanup_file_variables Cleaning up project directory and file based variables section_end:1737620027:cleanup_file_variables ERROR: Job failed: exit code 1 build:tests-fedora-no-libunwind has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/69822695): Header <unistd.h> has symbol "gettid" : YES Checking whether type "struct sysinfo" has member "totalram" : YES Checking for function "memfd_create" : YES Configuring config.h using configuration Program python3 found: YES (/usr/bin/python3) Program igt_doc.py found: YES (/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py) Program gen_rst_index skipped: feature sphinx disabled Program generate_iga64_codes found: YES (/builds/gfx-ci/igt-ci-tags/scripts/generate_iga64_codes) Configuring i915-perf.pc using configuration Configuring xe-oa.pc using configuration tests/meson.build:426:1: ERROR: File intel/kms_mst_helper.c does not exist. A full log can be found at /builds/gfx-ci/igt-ci-tags/build/meson-logs/meson-log.txt section_end:1737620036:step_script section_start:1737620036:cleanup_file_variables Cleaning up project directory and file based variables section_end:1737620036:cleanup_file_variables ERROR: Job failed: exit code 1 build:tests-fedora-oldest-meson has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/69822696): Header <unistd.h> has symbol "gettid": YES Checking whether type "struct sysinfo" has member "totalram" : YES Checking for function "memfd_create" : YES Configuring config.h using configuration Program python3 found: YES (/usr/bin/python3) Program igt_doc.py found: YES (/builds/gfx-ci/igt-ci-tags/scripts/igt_doc.py) Program gen_rst_index skipped: feature sphinx disabled Program generate_iga64_codes found: YES (/builds/gfx-ci/igt-ci-tags/scripts/generate_iga64_codes) Configuring i915-perf.pc using configuration Configuring xe-oa.pc using configuration tests/meson.build:426:1: ERROR: File intel/kms_mst_helper.c does not exist. A full log can be found at /builds/gfx-ci/igt-ci-tags/build/meson-logs/meson-log.txt section_end:1737620044:step_script section_start:1737620044:cleanup_file_variables Cleaning up project directory and file based variables section_end:1737620045:cleanup_file_variables ERROR: Job failed: exit code 1 == Logs == For more details see: https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/1350699 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH i-g-t 0/3] add dsc-fallback test @ 2025-01-27 6:29 Kunal Joshi 2025-01-27 6:29 ` [PATCH i-g-t 2/3] tests/intel/kms_dp_linktrain_fallback: " Kunal Joshi 0 siblings, 1 reply; 10+ messages in thread From: Kunal Joshi @ 2025-01-27 6:29 UTC (permalink / raw) To: igt-dev; +Cc: Kunal Joshi Add test to check we fallback to dsc when current link params cannot accomadate bw required by the current mode. Kunal Joshi (3): tests/intel/kms_mst_helper: Add helper for MST-related functions tests/intel/kms_dp_linktrain_fallback: add dsc-fallback test HAX: Do not merge tests/intel-ci/fast-feedback.testlist | 3 +- tests/intel-ci/xe-fast-feedback.testlist | 3 +- tests/intel/kms_dp_linktrain_fallback.c | 380 +++++++++++++++++++---- tests/intel/kms_mst_helper.c | 48 +++ tests/intel/kms_mst_helper.h | 10 + tests/meson.build | 3 + 6 files changed, 377 insertions(+), 70 deletions(-) create mode 100644 tests/intel/kms_mst_helper.c create mode 100644 tests/intel/kms_mst_helper.h -- 2.25.1 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH i-g-t 2/3] tests/intel/kms_dp_linktrain_fallback: add dsc-fallback test 2025-01-27 6:29 [PATCH i-g-t 0/3] " Kunal Joshi @ 2025-01-27 6:29 ` Kunal Joshi 2025-01-27 9:17 ` Sharma, Swati2 2025-02-10 9:56 ` Nautiyal, Ankit K 0 siblings, 2 replies; 10+ messages in thread From: Kunal Joshi @ 2025-01-27 6:29 UTC (permalink / raw) To: igt-dev; +Cc: Kunal Joshi, Ankit Nautiyal add new dsc-fallback test which finds a mode which can be driven without DSC at current link params and reduces link param till we have combination (link_rate, lane_count) which requires DSC to be enabled. Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com> Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com> --- tests/intel/kms_dp_linktrain_fallback.c | 352 +++++++++++++++++++++--- tests/meson.build | 4 +- 2 files changed, 311 insertions(+), 45 deletions(-) diff --git a/tests/intel/kms_dp_linktrain_fallback.c b/tests/intel/kms_dp_linktrain_fallback.c index b10946781..471381f1d 100644 --- a/tests/intel/kms_dp_linktrain_fallback.c +++ b/tests/intel/kms_dp_linktrain_fallback.c @@ -17,10 +17,14 @@ #include "igt.h" #include "kms_mst_helper.h" +#include "kms_dsc_helper.h" /** * SUBTEST: dp-fallback * Description: Test fallback on DP connectors + * + * SUBTEST: dsc-fallback + * Description: Test we fallback to DSC when BW isn't sufficient */ #define RETRAIN_COUNT 1 @@ -238,16 +242,124 @@ static int check_condition_with_timeout(int drm_fd, igt_output_t *output, } } +/* + * Force a link training failure followed by link retrain, then + * block until the driver has no further pending retrain/failure. + * Returns false if we time out waiting. + */ +static bool force_failure_and_wait(data_t *data, + igt_output_t *output, + int failure_type, + int retrain_count, + double interval, + double timeout) +{ + igt_force_lt_failure(data->drm_fd, output, failure_type); + igt_force_link_retrain(data->drm_fd, output, retrain_count); + + /* Wait until there's no pending retrain */ + if (check_condition_with_timeout(data->drm_fd, output, + igt_get_dp_pending_retrain, + interval, timeout)) { + igt_info("Timed out waiting for pending retrain.\n"); + return false; + } + + /* Wait until there's no pending LT failures */ + if (check_condition_with_timeout(data->drm_fd, output, + igt_get_dp_pending_lt_failures, + interval, timeout)) { + igt_info("Timed out waiting for pending LT failures.\n"); + return false; + } + + return true; +} + +/* + * Waits for a hotplug event, then checks that the link-status is BAD. + * Returns false if the link-status isn't BAD or no hotplug arrives in time. + */ +static bool wait_for_hotplug_and_check_bad(int drm_fd, + data_t *data, + igt_output_t *output, + struct udev_monitor *mon, + double hotplug_timeout) +{ + uint32_t link_status_prop_id; + uint64_t link_status_value; + drmModePropertyPtr link_status_prop; + + if (!igt_hotplug_detected(mon, hotplug_timeout)) { + igt_info("No hotplug event within %.2f seconds.\n", hotplug_timeout); + return false; + } + + kmstest_get_property(drm_fd, + output->config.connector->connector_id, + DRM_MODE_OBJECT_CONNECTOR, + "link-status", + &link_status_prop_id, &link_status_value, + &link_status_prop); + + if (link_status_value != DRM_MODE_LINK_STATUS_BAD) { + igt_info("Expected link-status=BAD but got %" PRIu64 "\n", + link_status_value); + return false; + } + + return true; +} + +/* + * Sets link status=GOOD for the specified outputs, then calls + * validate_modeset_for_outputs() to re-commit. Returns false + * if the re-commit fails. + */ +static bool fix_link_status_and_recommit(data_t *data, + igt_output_t *outputs[], + int *output_count, + drmModeModeInfo * modes[], + struct igt_fb fbs[], + struct igt_plane *primarys[]) +{ + int i; + igt_output_t *out; + + /* Set link-status=GOOD on each tested output */ + for_each_connected_output(&data->display, out) { + for (i = 0; i < *output_count; i++) { + if (out->id == outputs[i]->id) { + igt_output_set_prop_value( + out, IGT_CONNECTOR_LINK_STATUS, + DRM_MODE_LINK_STATUS_GOOD); + } + } + } + + if (!validate_modeset_for_outputs(data, outputs, output_count, + modes, fbs, primarys)) { + igt_info("Modeset validation failed after forcing link-status=GOOD.\n"); + return false; + } + + if (igt_display_try_commit_atomic(&data->display, + DRM_MODE_ATOMIC_ALLOW_MODESET, + NULL) != 0) { + igt_info("Commit failed after restoring link-status=GOOD.\n"); + return false; + } + + return true; +} + static void test_fallback(data_t *data, bool is_mst) { int output_count, retries; int max_link_rate, curr_link_rate, prev_link_rate; int max_lane_count, curr_lane_count, prev_lane_count; igt_output_t *outputs[IGT_MAX_PIPES]; - uint32_t link_status_prop_id; - uint64_t link_status_value; - drmModeModeInfo *modes[IGT_MAX_PIPES]; - drmModePropertyPtr link_status_prop; + drmModeModeInfo * modes[IGT_MAX_PIPES]; struct igt_fb fbs[IGT_MAX_PIPES]; struct igt_plane *primarys[IGT_MAX_PIPES]; struct udev_monitor *mon; @@ -256,71 +368,71 @@ static void test_fallback(data_t *data, bool is_mst) igt_display_reset(&data->display); igt_reset_link_params(data->drm_fd, data->output); - if (!setup_outputs(data, is_mst, outputs, - &output_count, modes, fbs, - primarys)) + igt_force_link_retrain(data->drm_fd, data->output, 1); + + if (!setup_outputs(data, is_mst, outputs, &output_count, + modes, fbs, primarys)) return; igt_info("Testing link training fallback on %s\n", igt_output_name(data->output)); max_link_rate = igt_get_max_link_rate(data->drm_fd, data->output); max_lane_count = igt_get_max_lane_count(data->drm_fd, data->output); + prev_link_rate = igt_get_current_link_rate(data->drm_fd, data->output); prev_lane_count = igt_get_current_lane_count(data->drm_fd, data->output); - while (!igt_get_dp_link_retrain_disabled(data->drm_fd, - data->output)) { + while (!igt_get_dp_link_retrain_disabled(data->drm_fd, data->output)) { igt_info("Current link rate: %d, Current lane count: %d\n", - prev_link_rate, - prev_lane_count); + prev_link_rate, prev_lane_count); + mon = igt_watch_uevents(); - igt_force_lt_failure(data->drm_fd, data->output, - LT_FAILURE_REDUCED_CAPS); - igt_force_link_retrain(data->drm_fd, data->output, - RETRAIN_COUNT); - - igt_assert_eq(check_condition_with_timeout(data->drm_fd, - data->output, - igt_get_dp_pending_retrain, - 1.0, 20.0), 0); - igt_assert_eq(check_condition_with_timeout(data->drm_fd, - data->output, - igt_get_dp_pending_lt_failures, - 1.0, 20.0), 0); + + /* Force link failure, wait for retrain to clear */ + igt_assert_f(force_failure_and_wait(data, data->output, + LT_FAILURE_REDUCED_CAPS, + RETRAIN_COUNT, + 1.0, 20.0), + "Link training failure steps timed out\n"); if (igt_get_dp_link_retrain_disabled(data->drm_fd, data->output)) { igt_reset_connectors(); + igt_flush_uevents(mon); return; } - igt_assert_f(igt_hotplug_detected(mon, 20), - "Didn't get hotplug for force link training failure\n"); - - kmstest_get_property(data->drm_fd, - data->output->config.connector->connector_id, - DRM_MODE_OBJECT_CONNECTOR, "link-status", - &link_status_prop_id, &link_status_value, - &link_status_prop); - igt_assert_eq(link_status_value, DRM_MODE_LINK_STATUS_BAD); + /* Wait for hotplug + check link-status=BAD */ + igt_assert_f(wait_for_hotplug_and_check_bad(data->drm_fd, + data, + data->output, + mon, + 20.0), + "Didn't get hotplug or link-status=BAD\n"); igt_flush_uevents(mon); - set_connector_link_status_good(data, outputs, &output_count); - igt_assert_f(validate_modeset_for_outputs(data, + + /* Set link-status=GOOD and re-commit */ + igt_assert_f(fix_link_status_and_recommit(data, outputs, &output_count, modes, fbs, primarys), "modeset failed\n"); - igt_display_commit2(&data->display, COMMIT_ATOMIC); - igt_assert_eq(data->output->values[IGT_CONNECTOR_LINK_STATUS], DRM_MODE_LINK_STATUS_GOOD); - curr_link_rate = igt_get_current_link_rate(data->drm_fd, data->output); - curr_lane_count = igt_get_current_lane_count(data->drm_fd, data->output); + /* Ensure link-status is GOOD again */ + igt_assert_eq(data->output->values[IGT_CONNECTOR_LINK_STATUS], + DRM_MODE_LINK_STATUS_GOOD); + + curr_link_rate = igt_get_current_link_rate(data->drm_fd, + data->output); + curr_lane_count = igt_get_current_lane_count(data->drm_fd, + data->output); igt_assert_f((curr_link_rate < prev_link_rate || - curr_lane_count < prev_lane_count) || - ((curr_link_rate == max_link_rate && curr_lane_count == max_lane_count) && --retries), + curr_lane_count < prev_lane_count) || + ((curr_link_rate == max_link_rate && + curr_lane_count == max_lane_count) && --retries), "Fallback unsuccessful\n"); prev_link_rate = curr_link_rate; @@ -328,7 +440,117 @@ static void test_fallback(data_t *data, bool is_mst) } } -static bool run_test(data_t *data) +static void test_dsc_sst_fallback(data_t *data) +{ + bool non_dsc_mode_found = false; + bool dsc_fallback_successful = false; + int ret; + struct udev_monitor *mon; + drmModeModeInfo *mode_to_check; + igt_output_t *outputs[IGT_MAX_PIPES]; + int output_count = 0; + + igt_info("Checking DSC fallback on %s\n", igt_output_name(data->output)); + data->pipe = PIPE_A; + + igt_display_reset(&data->display); + igt_reset_link_params(data->drm_fd, data->output); + igt_force_link_retrain(data->drm_fd, data->output, 1); + + /* Find a mode that doesn't require DSC initially */ + for_each_connector_mode(data->output) { + data->mode = &data->output->config.connector->modes[j__]; + igt_create_color_fb(data->drm_fd, data->mode->hdisplay, + data->mode->vdisplay, DRM_FORMAT_XRGB8888, + DRM_FORMAT_MOD_LINEAR, 0.0, 1.0, 0.0, + &data->fb); + igt_output_override_mode(data->output, data->mode); + igt_output_set_pipe(data->output, data->pipe); + data->primary = igt_output_get_plane_type(data->output, + DRM_PLANE_TYPE_PRIMARY); + igt_plane_set_fb(data->primary, &data->fb); + + ret = igt_display_try_commit_atomic(&data->display, + DRM_MODE_ATOMIC_TEST_ONLY | + DRM_MODE_ATOMIC_ALLOW_MODESET, + NULL); + if (ret != 0) { + igt_info("Skipping mode %dx%d@%d on %s\n", + data->mode->hdisplay, data->mode->vdisplay, + data->mode->vrefresh, + igt_output_name(data->output)); + continue; + } + igt_display_commit2(&data->display, COMMIT_ATOMIC); + + if (!igt_is_dsc_enabled(data->drm_fd, + data->output->name)) { + drmModeModeInfo *non_dsc_mode + = igt_output_get_mode(data->output); + igt_info("Found mode %dx%d@%d %s that doesn't need DSC with link rate %d and lane count %d\n", + non_dsc_mode->hdisplay, non_dsc_mode->vdisplay, + non_dsc_mode->vrefresh, non_dsc_mode->name, + igt_get_current_link_rate(data->drm_fd, data->output), + igt_get_current_lane_count(data->drm_fd, data->output)); + non_dsc_mode_found = true; + break; + } + } + igt_require_f(non_dsc_mode_found, + "No non-DSC mode found on %s\n", + igt_output_name(data->output)); + + + /* Repeatedly force link failure until DSC is required (or link is disabled) */ + while (!igt_get_dp_link_retrain_disabled(data->drm_fd, data->output)) { + mon = igt_watch_uevents(); + + igt_assert_f(force_failure_and_wait(data, data->output, + LT_FAILURE_REDUCED_CAPS, + RETRAIN_COUNT, 1.0, 20.0), + "Forcing DSC fallback timed out\n"); + + if (igt_get_dp_link_retrain_disabled(data->drm_fd, + data->output)) { + igt_reset_connectors(); + igt_flush_uevents(mon); + return; + } + + igt_assert_f(wait_for_hotplug_and_check_bad(data->drm_fd, + data, + data->output, + mon, + 20.0), + "Didn't get hotplug or link-status=BAD for DSC\n"); + igt_flush_uevents(mon); + + outputs[output_count++] = data->output; + set_connector_link_status_good(data, outputs, &output_count); + igt_display_commit2(&data->display, COMMIT_ATOMIC); + + mode_to_check = igt_output_get_mode(data->output); + + if (igt_is_dsc_enabled(data->drm_fd, data->output->name)) { + igt_info("mode %dx%d@%d now requires DSC with link rate %d and lane count %d\n", + mode_to_check->hdisplay, mode_to_check->vdisplay, + mode_to_check->vrefresh, + igt_get_current_link_rate(data->drm_fd, data->output), + igt_get_current_lane_count(data->drm_fd, data->output)); + igt_info("DSC fallback successful on %s\n", + igt_output_name(data->output)); + dsc_fallback_successful = true; + break; + } else { + igt_info("mode %dx%d@%d still doesn't require DSC\n", + mode_to_check->hdisplay, mode_to_check->vdisplay, + mode_to_check->vrefresh); + } + } + igt_assert_f(dsc_fallback_successful, "DSC fallback unsuccessful\n"); +} + +static bool run_lt_fallback_test(data_t *data) { bool ran = false; igt_output_t *output; @@ -366,6 +588,43 @@ static bool run_test(data_t *data) return ran; } +static bool run_dsc_sst_fallaback_test(data_t *data) +{ + bool ran = false; + igt_output_t *output; + + if (!is_dsc_supported_by_source(data->drm_fd)) { + igt_info("DSC not supported by source.\n"); + return ran; + } + + for_each_connected_output(&data->display, output) { + data->output = output; + + if (!igt_has_force_link_training_failure_debugfs(data->drm_fd, + data->output)) { + igt_info("Output %s doesn't support forcing link training.\n", + igt_output_name(data->output)); + continue; + } + + if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) { + igt_info("Skipping output %s as it's not DP\n", output->name); + continue; + } + + if (!is_dsc_supported_by_sink(data->drm_fd, data->output)) { + igt_info("Skipping output %s as DSC not supported by sink\n", + igt_output_name(data->output)); + continue; + } + + ran = true; + test_dsc_sst_fallback(data); + } + return ran; +} + igt_main { data_t data = {}; @@ -381,8 +640,13 @@ igt_main } igt_subtest("dp-fallback") { - igt_require_f(run_test(&data), - "Skipping test as no output found or none supports fallback\n"); + igt_require_f(run_lt_fallback_test(&data), + "Skipping test as no DP output found or none supports forcing link fail\n"); + } + + igt_subtest("dsc-fallback") { + igt_require_f(run_dsc_sst_fallaback_test(&data), + "Skipping test: DSC fallback conditions not met.\n"); } igt_fixture { diff --git a/tests/meson.build b/tests/meson.build index 2cbd21c2a..dd75976dd 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -367,7 +367,9 @@ extra_sources = { 'kms_chamelium_frames': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ], 'kms_chamelium_hpd': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ], 'kms_dsc': [ join_paths ('intel', 'kms_dsc_helper.c') ], - 'kms_dp_linktrain_fallback': [join_paths ('intel', 'kms_mst_helper.c')], + 'kms_dp_linktrain_fallback': [ + join_paths ('intel', 'kms_mst_helper.c'), + join_paths ('intel', 'kms_dsc_helper.c')], 'kms_psr2_sf': [ join_paths ('intel', 'kms_dsc_helper.c') ], } -- 2.25.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH i-g-t 2/3] tests/intel/kms_dp_linktrain_fallback: add dsc-fallback test 2025-01-27 6:29 ` [PATCH i-g-t 2/3] tests/intel/kms_dp_linktrain_fallback: " Kunal Joshi @ 2025-01-27 9:17 ` Sharma, Swati2 2025-02-10 9:56 ` Nautiyal, Ankit K 1 sibling, 0 replies; 10+ messages in thread From: Sharma, Swati2 @ 2025-01-27 9:17 UTC (permalink / raw) To: Kunal Joshi, igt-dev; +Cc: Ankit Nautiyal Hi Kunal, Please have consistency in subject of your patches. Either start subject with capital letter or small letter. Also, please update igt_test_description() On 27-01-2025 11:59 am, Kunal Joshi wrote: > add new dsc-fallback test which finds a mode %s add/Add > which can be driven without DSC at current link > params and reduces link param till we have > combination (link_rate, lane_count) which requires > DSC to be enabled. > > Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com> > Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com> > --- > tests/intel/kms_dp_linktrain_fallback.c | 352 +++++++++++++++++++++--- > tests/meson.build | 4 +- > 2 files changed, 311 insertions(+), 45 deletions(-) > > diff --git a/tests/intel/kms_dp_linktrain_fallback.c b/tests/intel/kms_dp_linktrain_fallback.c > index b10946781..471381f1d 100644 > --- a/tests/intel/kms_dp_linktrain_fallback.c > +++ b/tests/intel/kms_dp_linktrain_fallback.c > @@ -17,10 +17,14 @@ > > #include "igt.h" > #include "kms_mst_helper.h" > +#include "kms_dsc_helper.h" > > /** > * SUBTEST: dp-fallback > * Description: Test fallback on DP connectors > + * > + * SUBTEST: dsc-fallback > + * Description: Test we fallback to DSC when BW isn't sufficient Remove "we" > */ > > #define RETRAIN_COUNT 1 > @@ -238,16 +242,124 @@ static int check_condition_with_timeout(int drm_fd, igt_output_t *output, > } > } > > +/* > + * Force a link training failure followed by link retrain, then > + * block until the driver has no further pending retrain/failure. > + * Returns false if we time out waiting. > + */ > +static bool force_failure_and_wait(data_t *data, > + igt_output_t *output, > + int failure_type, > + int retrain_count, > + double interval, > + double timeout) > +{ > + igt_force_lt_failure(data->drm_fd, output, failure_type); > + igt_force_link_retrain(data->drm_fd, output, retrain_count); > + > + /* Wait until there's no pending retrain */ > + if (check_condition_with_timeout(data->drm_fd, output, > + igt_get_dp_pending_retrain, > + interval, timeout)) { > + igt_info("Timed out waiting for pending retrain.\n"); > + return false; > + } > + > + /* Wait until there's no pending LT failures */ > + if (check_condition_with_timeout(data->drm_fd, output, > + igt_get_dp_pending_lt_failures, > + interval, timeout)) { > + igt_info("Timed out waiting for pending LT failures.\n"); > + return false; > + } > + > + return true; > +} > + > +/* > + * Waits for a hotplug event, then checks that the link-status is BAD. > + * Returns false if the link-status isn't BAD or no hotplug arrives in time. > + */ > +static bool wait_for_hotplug_and_check_bad(int drm_fd, > + data_t *data, > + igt_output_t *output, > + struct udev_monitor *mon, > + double hotplug_timeout) > +{ > + uint32_t link_status_prop_id; > + uint64_t link_status_value; > + drmModePropertyPtr link_status_prop; > + > + if (!igt_hotplug_detected(mon, hotplug_timeout)) { > + igt_info("No hotplug event within %.2f seconds.\n", hotplug_timeout); > + return false; > + } > + > + kmstest_get_property(drm_fd, > + output->config.connector->connector_id, > + DRM_MODE_OBJECT_CONNECTOR, > + "link-status", > + &link_status_prop_id, &link_status_value, > + &link_status_prop); > + > + if (link_status_value != DRM_MODE_LINK_STATUS_BAD) { > + igt_info("Expected link-status=BAD but got %" PRIu64 "\n", > + link_status_value); > + return false; > + } > + > + return true; > +} > + > +/* > + * Sets link status=GOOD for the specified outputs, then calls > + * validate_modeset_for_outputs() to re-commit. Returns false > + * if the re-commit fails. > + */ > +static bool fix_link_status_and_recommit(data_t *data, > + igt_output_t *outputs[], > + int *output_count, > + drmModeModeInfo * modes[], > + struct igt_fb fbs[], > + struct igt_plane *primarys[]) > +{ > + int i; > + igt_output_t *out; > + > + /* Set link-status=GOOD on each tested output */ > + for_each_connected_output(&data->display, out) { > + for (i = 0; i < *output_count; i++) { > + if (out->id == outputs[i]->id) { > + igt_output_set_prop_value( > + out, IGT_CONNECTOR_LINK_STATUS, > + DRM_MODE_LINK_STATUS_GOOD); > + } > + } > + } > + > + if (!validate_modeset_for_outputs(data, outputs, output_count, > + modes, fbs, primarys)) { > + igt_info("Modeset validation failed after forcing link-status=GOOD.\n"); > + return false; > + } > + > + if (igt_display_try_commit_atomic(&data->display, > + DRM_MODE_ATOMIC_ALLOW_MODESET, > + NULL) != 0) { > + igt_info("Commit failed after restoring link-status=GOOD.\n"); > + return false; > + } > + > + return true; > +} > + > static void test_fallback(data_t *data, bool is_mst) > { > int output_count, retries; > int max_link_rate, curr_link_rate, prev_link_rate; > int max_lane_count, curr_lane_count, prev_lane_count; > igt_output_t *outputs[IGT_MAX_PIPES]; > - uint32_t link_status_prop_id; > - uint64_t link_status_value; > - drmModeModeInfo *modes[IGT_MAX_PIPES]; > - drmModePropertyPtr link_status_prop; > + drmModeModeInfo * modes[IGT_MAX_PIPES]; > struct igt_fb fbs[IGT_MAX_PIPES]; > struct igt_plane *primarys[IGT_MAX_PIPES]; > struct udev_monitor *mon; > @@ -256,71 +368,71 @@ static void test_fallback(data_t *data, bool is_mst) > > igt_display_reset(&data->display); > igt_reset_link_params(data->drm_fd, data->output); > - if (!setup_outputs(data, is_mst, outputs, > - &output_count, modes, fbs, > - primarys)) > + igt_force_link_retrain(data->drm_fd, data->output, 1); > + > + if (!setup_outputs(data, is_mst, outputs, &output_count, > + modes, fbs, primarys)) > return; > > igt_info("Testing link training fallback on %s\n", > igt_output_name(data->output)); > max_link_rate = igt_get_max_link_rate(data->drm_fd, data->output); > max_lane_count = igt_get_max_lane_count(data->drm_fd, data->output); > + > prev_link_rate = igt_get_current_link_rate(data->drm_fd, data->output); > prev_lane_count = igt_get_current_lane_count(data->drm_fd, data->output); > > - while (!igt_get_dp_link_retrain_disabled(data->drm_fd, > - data->output)) { > + while (!igt_get_dp_link_retrain_disabled(data->drm_fd, data->output)) { > igt_info("Current link rate: %d, Current lane count: %d\n", > - prev_link_rate, > - prev_lane_count); > + prev_link_rate, prev_lane_count); > + > mon = igt_watch_uevents(); > - igt_force_lt_failure(data->drm_fd, data->output, > - LT_FAILURE_REDUCED_CAPS); > - igt_force_link_retrain(data->drm_fd, data->output, > - RETRAIN_COUNT); > - > - igt_assert_eq(check_condition_with_timeout(data->drm_fd, > - data->output, > - igt_get_dp_pending_retrain, > - 1.0, 20.0), 0); > - igt_assert_eq(check_condition_with_timeout(data->drm_fd, > - data->output, > - igt_get_dp_pending_lt_failures, > - 1.0, 20.0), 0); > + > + /* Force link failure, wait for retrain to clear */ > + igt_assert_f(force_failure_and_wait(data, data->output, > + LT_FAILURE_REDUCED_CAPS, > + RETRAIN_COUNT, > + 1.0, 20.0), > + "Link training failure steps timed out\n"); > > if (igt_get_dp_link_retrain_disabled(data->drm_fd, > data->output)) { > igt_reset_connectors(); > + igt_flush_uevents(mon); > return; > } > > - igt_assert_f(igt_hotplug_detected(mon, 20), > - "Didn't get hotplug for force link training failure\n"); > - > - kmstest_get_property(data->drm_fd, > - data->output->config.connector->connector_id, > - DRM_MODE_OBJECT_CONNECTOR, "link-status", > - &link_status_prop_id, &link_status_value, > - &link_status_prop); > - igt_assert_eq(link_status_value, DRM_MODE_LINK_STATUS_BAD); > + /* Wait for hotplug + check link-status=BAD */ > + igt_assert_f(wait_for_hotplug_and_check_bad(data->drm_fd, > + data, > + data->output, > + mon, > + 20.0), > + "Didn't get hotplug or link-status=BAD\n"); > igt_flush_uevents(mon); > - set_connector_link_status_good(data, outputs, &output_count); > - igt_assert_f(validate_modeset_for_outputs(data, > + > + /* Set link-status=GOOD and re-commit */ > + igt_assert_f(fix_link_status_and_recommit(data, > outputs, > &output_count, > modes, > fbs, > primarys), > "modeset failed\n"); > - igt_display_commit2(&data->display, COMMIT_ATOMIC); > > - igt_assert_eq(data->output->values[IGT_CONNECTOR_LINK_STATUS], DRM_MODE_LINK_STATUS_GOOD); > - curr_link_rate = igt_get_current_link_rate(data->drm_fd, data->output); > - curr_lane_count = igt_get_current_lane_count(data->drm_fd, data->output); > + /* Ensure link-status is GOOD again */ > + igt_assert_eq(data->output->values[IGT_CONNECTOR_LINK_STATUS], > + DRM_MODE_LINK_STATUS_GOOD); > + > + curr_link_rate = igt_get_current_link_rate(data->drm_fd, > + data->output); > + curr_lane_count = igt_get_current_lane_count(data->drm_fd, > + data->output); > > igt_assert_f((curr_link_rate < prev_link_rate || > - curr_lane_count < prev_lane_count) || > - ((curr_link_rate == max_link_rate && curr_lane_count == max_lane_count) && --retries), > + curr_lane_count < prev_lane_count) || > + ((curr_link_rate == max_link_rate && > + curr_lane_count == max_lane_count) && --retries), > "Fallback unsuccessful\n"); > > prev_link_rate = curr_link_rate; > @@ -328,7 +440,117 @@ static void test_fallback(data_t *data, bool is_mst) > } > } > > -static bool run_test(data_t *data) > +static void test_dsc_sst_fallback(data_t *data) > +{ > + bool non_dsc_mode_found = false; > + bool dsc_fallback_successful = false; > + int ret; > + struct udev_monitor *mon; > + drmModeModeInfo *mode_to_check; > + igt_output_t *outputs[IGT_MAX_PIPES]; > + int output_count = 0; > + > + igt_info("Checking DSC fallback on %s\n", igt_output_name(data->output)); > + data->pipe = PIPE_A; > + > + igt_display_reset(&data->display); > + igt_reset_link_params(data->drm_fd, data->output); Fix indentation here. > + igt_force_link_retrain(data->drm_fd, data->output, 1); > + > + /* Find a mode that doesn't require DSC initially */ > + for_each_connector_mode(data->output) { > + data->mode = &data->output->config.connector->modes[j__]; > + igt_create_color_fb(data->drm_fd, data->mode->hdisplay, > + data->mode->vdisplay, DRM_FORMAT_XRGB8888, > + DRM_FORMAT_MOD_LINEAR, 0.0, 1.0, 0.0, > + &data->fb); > + igt_output_override_mode(data->output, data->mode); > + igt_output_set_pipe(data->output, data->pipe); > + data->primary = igt_output_get_plane_type(data->output, > + DRM_PLANE_TYPE_PRIMARY); > + igt_plane_set_fb(data->primary, &data->fb); > + > + ret = igt_display_try_commit_atomic(&data->display, > + DRM_MODE_ATOMIC_TEST_ONLY | > + DRM_MODE_ATOMIC_ALLOW_MODESET, > + NULL); > + if (ret != 0) { > + igt_info("Skipping mode %dx%d@%d on %s\n", > + data->mode->hdisplay, data->mode->vdisplay, > + data->mode->vrefresh, > + igt_output_name(data->output)); > + continue; > + } > + igt_display_commit2(&data->display, COMMIT_ATOMIC); > + > + if (!igt_is_dsc_enabled(data->drm_fd, > + data->output->name)) { > + drmModeModeInfo *non_dsc_mode > + = igt_output_get_mode(data->output); > + igt_info("Found mode %dx%d@%d %s that doesn't need DSC with link rate %d and lane count %d\n", > + non_dsc_mode->hdisplay, non_dsc_mode->vdisplay, > + non_dsc_mode->vrefresh, non_dsc_mode->name, > + igt_get_current_link_rate(data->drm_fd, data->output), > + igt_get_current_lane_count(data->drm_fd, data->output)); > + non_dsc_mode_found = true; > + break; > + } > + } > + igt_require_f(non_dsc_mode_found, > + "No non-DSC mode found on %s\n", > + igt_output_name(data->output)); > + > + Remove extra new line > + /* Repeatedly force link failure until DSC is required (or link is disabled) */ > + while (!igt_get_dp_link_retrain_disabled(data->drm_fd, data->output)) { > + mon = igt_watch_uevents(); > + > + igt_assert_f(force_failure_and_wait(data, data->output, > + LT_FAILURE_REDUCED_CAPS, > + RETRAIN_COUNT, 1.0, 20.0), > + "Forcing DSC fallback timed out\n"); > + > + if (igt_get_dp_link_retrain_disabled(data->drm_fd, > + data->output)) { > + igt_reset_connectors(); > + igt_flush_uevents(mon); > + return; > + } > + > + igt_assert_f(wait_for_hotplug_and_check_bad(data->drm_fd, > + data, > + data->output, > + mon, > + 20.0), > + "Didn't get hotplug or link-status=BAD for DSC\n"); > + igt_flush_uevents(mon); > + > + outputs[output_count++] = data->output; > + set_connector_link_status_good(data, outputs, &output_count); > + igt_display_commit2(&data->display, COMMIT_ATOMIC); > + > + mode_to_check = igt_output_get_mode(data->output); > + > + if (igt_is_dsc_enabled(data->drm_fd, data->output->name)) { > + igt_info("mode %dx%d@%d now requires DSC with link rate %d and lane count %d\n", > + mode_to_check->hdisplay, mode_to_check->vdisplay, > + mode_to_check->vrefresh, > + igt_get_current_link_rate(data->drm_fd, data->output), > + igt_get_current_lane_count(data->drm_fd, data->output)); > + igt_info("DSC fallback successful on %s\n", > + igt_output_name(data->output)); > + dsc_fallback_successful = true; > + break; > + } else { > + igt_info("mode %dx%d@%d still doesn't require DSC\n", > + mode_to_check->hdisplay, mode_to_check->vdisplay, > + mode_to_check->vrefresh); > + } > + } > + igt_assert_f(dsc_fallback_successful, "DSC fallback unsuccessful\n"); > +} > + > +static bool run_lt_fallback_test(data_t *data) > { > bool ran = false; > igt_output_t *output; > @@ -366,6 +588,43 @@ static bool run_test(data_t *data) > return ran; > } > > +static bool run_dsc_sst_fallaback_test(data_t *data) > +{ > + bool ran = false; > + igt_output_t *output; > + > + if (!is_dsc_supported_by_source(data->drm_fd)) { > + igt_info("DSC not supported by source.\n"); > + return ran; > + } > + > + for_each_connected_output(&data->display, output) { > + data->output = output; > + > + if (!igt_has_force_link_training_failure_debugfs(data->drm_fd, > + data->output)) { > + igt_info("Output %s doesn't support forcing link training.\n", > + igt_output_name(data->output)); > + continue; > + } > + > + if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) { > + igt_info("Skipping output %s as it's not DP\n", output->name); > + continue; > + } > + > + if (!is_dsc_supported_by_sink(data->drm_fd, data->output)) { > + igt_info("Skipping output %s as DSC not supported by sink\n", > + igt_output_name(data->output)); > + continue; > + } > + > + ran = true; > + test_dsc_sst_fallback(data); > + } > + return ran; > +} > + > igt_main > { > data_t data = {}; > @@ -381,8 +640,13 @@ igt_main > } > > igt_subtest("dp-fallback") { > - igt_require_f(run_test(&data), > - "Skipping test as no output found or none supports fallback\n"); > + igt_require_f(run_lt_fallback_test(&data), > + "Skipping test as no DP output found or none supports forcing link fail\n"); This rename and update of skip message should have been a separate patch. > + } > + > + igt_subtest("dsc-fallback") { > + igt_require_f(run_dsc_sst_fallaback_test(&data), > + "Skipping test: DSC fallback conditions not met.\n"); This should be in this patch only. > } > > igt_fixture { > diff --git a/tests/meson.build b/tests/meson.build > index 2cbd21c2a..dd75976dd 100644 > --- a/tests/meson.build > +++ b/tests/meson.build > @@ -367,7 +367,9 @@ extra_sources = { > 'kms_chamelium_frames': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ], > 'kms_chamelium_hpd': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ], > 'kms_dsc': [ join_paths ('intel', 'kms_dsc_helper.c') ], > - 'kms_dp_linktrain_fallback': [join_paths ('intel', 'kms_mst_helper.c')], > + 'kms_dp_linktrain_fallback': [ > + join_paths ('intel', 'kms_mst_helper.c'), > + join_paths ('intel', 'kms_dsc_helper.c')], > 'kms_psr2_sf': [ join_paths ('intel', 'kms_dsc_helper.c') ], > } > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH i-g-t 2/3] tests/intel/kms_dp_linktrain_fallback: add dsc-fallback test 2025-01-27 6:29 ` [PATCH i-g-t 2/3] tests/intel/kms_dp_linktrain_fallback: " Kunal Joshi 2025-01-27 9:17 ` Sharma, Swati2 @ 2025-02-10 9:56 ` Nautiyal, Ankit K 1 sibling, 0 replies; 10+ messages in thread From: Nautiyal, Ankit K @ 2025-02-10 9:56 UTC (permalink / raw) To: Kunal Joshi, igt-dev On 1/27/2025 11:59 AM, Kunal Joshi wrote: > add new dsc-fallback test which finds a mode > which can be driven without DSC at current link > params and reduces link param till we have > combination (link_rate, lane_count) which requires > DSC to be enabled. This does not specify what the test_dsc_fallback is validating or why a new test is required. What perhaps should be mentioned is that we want to check whether DSC automatically kicks in while falling back to a lower rate/lane. And then the above lines make sense. > > Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com> > Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com> > --- > tests/intel/kms_dp_linktrain_fallback.c | 352 +++++++++++++++++++++--- > tests/meson.build | 4 +- > 2 files changed, 311 insertions(+), 45 deletions(-) > > diff --git a/tests/intel/kms_dp_linktrain_fallback.c b/tests/intel/kms_dp_linktrain_fallback.c > index b10946781..471381f1d 100644 > --- a/tests/intel/kms_dp_linktrain_fallback.c > +++ b/tests/intel/kms_dp_linktrain_fallback.c > @@ -17,10 +17,14 @@ > > #include "igt.h" > #include "kms_mst_helper.h" > +#include "kms_dsc_helper.h" > > /** > * SUBTEST: dp-fallback > * Description: Test fallback on DP connectors > + * > + * SUBTEST: dsc-fallback > + * Description: Test we fallback to DSC when BW isn't sufficient > */ > > #define RETRAIN_COUNT 1 > @@ -238,16 +242,124 @@ static int check_condition_with_timeout(int drm_fd, igt_output_t *output, > } > } > > +/* > + * Force a link training failure followed by link retrain, then > + * block until the driver has no further pending retrain/failure. > + * Returns false if we time out waiting. > + */ > +static bool force_failure_and_wait(data_t *data, > + igt_output_t *output, > + int failure_type, > + int retrain_count, > + double interval, > + double timeout) > +{ > + igt_force_lt_failure(data->drm_fd, output, failure_type); > + igt_force_link_retrain(data->drm_fd, output, retrain_count); > + > + /* Wait until there's no pending retrain */ > + if (check_condition_with_timeout(data->drm_fd, output, > + igt_get_dp_pending_retrain, > + interval, timeout)) { > + igt_info("Timed out waiting for pending retrain.\n"); > + return false; > + } > + > + /* Wait until there's no pending LT failures */ > + if (check_condition_with_timeout(data->drm_fd, output, > + igt_get_dp_pending_lt_failures, > + interval, timeout)) { > + igt_info("Timed out waiting for pending LT failures.\n"); > + return false; > + } > + > + return true; > +} > + > +/* > + * Waits for a hotplug event, then checks that the link-status is BAD. > + * Returns false if the link-status isn't BAD or no hotplug arrives in time. > + */ > +static bool wait_for_hotplug_and_check_bad(int drm_fd, > + data_t *data, > + igt_output_t *output, > + struct udev_monitor *mon, > + double hotplug_timeout) > +{ > + uint32_t link_status_prop_id; > + uint64_t link_status_value; > + drmModePropertyPtr link_status_prop; > + > + if (!igt_hotplug_detected(mon, hotplug_timeout)) { > + igt_info("No hotplug event within %.2f seconds.\n", hotplug_timeout); > + return false; > + } > + > + kmstest_get_property(drm_fd, > + output->config.connector->connector_id, > + DRM_MODE_OBJECT_CONNECTOR, > + "link-status", > + &link_status_prop_id, &link_status_value, > + &link_status_prop); > + > + if (link_status_value != DRM_MODE_LINK_STATUS_BAD) { > + igt_info("Expected link-status=BAD but got %" PRIu64 "\n", > + link_status_value); > + return false; > + } > + > + return true; > +} > + > +/* > + * Sets link status=GOOD for the specified outputs, then calls > + * validate_modeset_for_outputs() to re-commit. Returns false > + * if the re-commit fails. > + */ > +static bool fix_link_status_and_recommit(data_t *data, > + igt_output_t *outputs[], > + int *output_count, > + drmModeModeInfo * modes[], > + struct igt_fb fbs[], > + struct igt_plane *primarys[]) > +{ > + int i; > + igt_output_t *out; > + > + /* Set link-status=GOOD on each tested output */ > + for_each_connected_output(&data->display, out) { > + for (i = 0; i < *output_count; i++) { > + if (out->id == outputs[i]->id) { > + igt_output_set_prop_value( > + out, IGT_CONNECTOR_LINK_STATUS, > + DRM_MODE_LINK_STATUS_GOOD); > + } > + } > + } > + > + if (!validate_modeset_for_outputs(data, outputs, output_count, > + modes, fbs, primarys)) { > + igt_info("Modeset validation failed after forcing link-status=GOOD.\n"); > + return false; > + } > + > + if (igt_display_try_commit_atomic(&data->display, > + DRM_MODE_ATOMIC_ALLOW_MODESET, > + NULL) != 0) { > + igt_info("Commit failed after restoring link-status=GOOD.\n"); > + return false; > + } > + > + return true; > +} > + > static void test_fallback(data_t *data, bool is_mst) > { > int output_count, retries; > int max_link_rate, curr_link_rate, prev_link_rate; > int max_lane_count, curr_lane_count, prev_lane_count; > igt_output_t *outputs[IGT_MAX_PIPES]; > - uint32_t link_status_prop_id; > - uint64_t link_status_value; > - drmModeModeInfo *modes[IGT_MAX_PIPES]; > - drmModePropertyPtr link_status_prop; > + drmModeModeInfo * modes[IGT_MAX_PIPES]; > struct igt_fb fbs[IGT_MAX_PIPES]; > struct igt_plane *primarys[IGT_MAX_PIPES]; > struct udev_monitor *mon; > @@ -256,71 +368,71 @@ static void test_fallback(data_t *data, bool is_mst) > > igt_display_reset(&data->display); > igt_reset_link_params(data->drm_fd, data->output); > - if (!setup_outputs(data, is_mst, outputs, > - &output_count, modes, fbs, > - primarys)) > + igt_force_link_retrain(data->drm_fd, data->output, 1); This is new. Not sure why this is required now in the test_fallback. > + > + if (!setup_outputs(data, is_mst, outputs, &output_count, > + modes, fbs, primarys)) Formatting or style change should not be fixed with functional change. > return; > > igt_info("Testing link training fallback on %s\n", > igt_output_name(data->output)); > max_link_rate = igt_get_max_link_rate(data->drm_fd, data->output); > max_lane_count = igt_get_max_lane_count(data->drm_fd, data->output); > + > prev_link_rate = igt_get_current_link_rate(data->drm_fd, data->output); > prev_lane_count = igt_get_current_lane_count(data->drm_fd, data->output); > > - while (!igt_get_dp_link_retrain_disabled(data->drm_fd, > - data->output)) { > + while (!igt_get_dp_link_retrain_disabled(data->drm_fd, data->output)) { This change is not required. > igt_info("Current link rate: %d, Current lane count: %d\n", > - prev_link_rate, > - prev_lane_count); > + prev_link_rate, prev_lane_count); > + These changes are not required. > mon = igt_watch_uevents(); > - igt_force_lt_failure(data->drm_fd, data->output, > - LT_FAILURE_REDUCED_CAPS); > - igt_force_link_retrain(data->drm_fd, data->output, > - RETRAIN_COUNT); > - > - igt_assert_eq(check_condition_with_timeout(data->drm_fd, > - data->output, > - igt_get_dp_pending_retrain, > - 1.0, 20.0), 0); > - igt_assert_eq(check_condition_with_timeout(data->drm_fd, > - data->output, > - igt_get_dp_pending_lt_failures, > - 1.0, 20.0), 0); This change should be a separate patch. Basically one patch to introduce force_failure_and_wait and use it in this test. Then add new dsc fallback test where this is re-used. > + > + /* Force link failure, wait for retrain to clear */ > + igt_assert_f(force_failure_and_wait(data, data->output, > + LT_FAILURE_REDUCED_CAPS, > + RETRAIN_COUNT, > + 1.0, 20.0), > + "Link training failure steps timed out\n"); > > if (igt_get_dp_link_retrain_disabled(data->drm_fd, > data->output)) { > igt_reset_connectors(); > + igt_flush_uevents(mon); > return; > } > > - igt_assert_f(igt_hotplug_detected(mon, 20), > - "Didn't get hotplug for force link training failure\n"); > - > - kmstest_get_property(data->drm_fd, > - data->output->config.connector->connector_id, > - DRM_MODE_OBJECT_CONNECTOR, "link-status", > - &link_status_prop_id, &link_status_value, > - &link_status_prop); > - igt_assert_eq(link_status_value, DRM_MODE_LINK_STATUS_BAD); > + /* Wait for hotplug + check link-status=BAD */ > + igt_assert_f(wait_for_hotplug_and_check_bad(data->drm_fd, > + data, > + data->output, > + mon, > + 20.0), > + "Didn't get hotplug or link-status=BAD\n"); > igt_flush_uevents(mon); > - set_connector_link_status_good(data, outputs, &output_count); > - igt_assert_f(validate_modeset_for_outputs(data, > + > + /* Set link-status=GOOD and re-commit */ > + igt_assert_f(fix_link_status_and_recommit(data, > outputs, > &output_count, > modes, > fbs, > primarys), > "modeset failed\n"); > - igt_display_commit2(&data->display, COMMIT_ATOMIC); > > - igt_assert_eq(data->output->values[IGT_CONNECTOR_LINK_STATUS], DRM_MODE_LINK_STATUS_GOOD); > - curr_link_rate = igt_get_current_link_rate(data->drm_fd, data->output); > - curr_lane_count = igt_get_current_lane_count(data->drm_fd, data->output); > + /* Ensure link-status is GOOD again */ > + igt_assert_eq(data->output->values[IGT_CONNECTOR_LINK_STATUS], > + DRM_MODE_LINK_STATUS_GOOD); > + > + curr_link_rate = igt_get_current_link_rate(data->drm_fd, > + data->output); > + curr_lane_count = igt_get_current_lane_count(data->drm_fd, > + data->output); > > igt_assert_f((curr_link_rate < prev_link_rate || > - curr_lane_count < prev_lane_count) || > - ((curr_link_rate == max_link_rate && curr_lane_count == max_lane_count) && --retries), > + curr_lane_count < prev_lane_count) || > + ((curr_link_rate == max_link_rate && > + curr_lane_count == max_lane_count) && --retries), > "Fallback unsuccessful\n"); > > prev_link_rate = curr_link_rate; > @@ -328,7 +440,117 @@ static void test_fallback(data_t *data, bool is_mst) > } > } > > -static bool run_test(data_t *data) > +static void test_dsc_sst_fallback(data_t *data) > +{ > + bool non_dsc_mode_found = false; > + bool dsc_fallback_successful = false; > + int ret; > + struct udev_monitor *mon; > + drmModeModeInfo *mode_to_check; > + igt_output_t *outputs[IGT_MAX_PIPES]; > + int output_count = 0; > + > + igt_info("Checking DSC fallback on %s\n", igt_output_name(data->output)); > + data->pipe = PIPE_A; > + > + igt_display_reset(&data->display); > + igt_reset_link_params(data->drm_fd, data->output); > + igt_force_link_retrain(data->drm_fd, data->output, 1); > + > + /* Find a mode that doesn't require DSC initially */ > + for_each_connector_mode(data->output) { > + data->mode = &data->output->config.connector->modes[j__]; > + igt_create_color_fb(data->drm_fd, data->mode->hdisplay, > + data->mode->vdisplay, DRM_FORMAT_XRGB8888, > + DRM_FORMAT_MOD_LINEAR, 0.0, 1.0, 0.0, > + &data->fb); > + igt_output_override_mode(data->output, data->mode); > + igt_output_set_pipe(data->output, data->pipe); > + data->primary = igt_output_get_plane_type(data->output, > + DRM_PLANE_TYPE_PRIMARY); > + igt_plane_set_fb(data->primary, &data->fb); > + > + ret = igt_display_try_commit_atomic(&data->display, > + DRM_MODE_ATOMIC_TEST_ONLY | > + DRM_MODE_ATOMIC_ALLOW_MODESET, > + NULL); > + if (ret != 0) { > + igt_info("Skipping mode %dx%d@%d on %s\n", > + data->mode->hdisplay, data->mode->vdisplay, > + data->mode->vrefresh, > + igt_output_name(data->output)); IMO, this can be igt_debug. It might flood with lots of messages while iterating through the modes. The new subtest looks fine to me. Regards, Ankit > + continue; > + } > + igt_display_commit2(&data->display, COMMIT_ATOMIC); > + > + if (!igt_is_dsc_enabled(data->drm_fd, > + data->output->name)) { > + drmModeModeInfo *non_dsc_mode > + = igt_output_get_mode(data->output); > + igt_info("Found mode %dx%d@%d %s that doesn't need DSC with link rate %d and lane count %d\n", > + non_dsc_mode->hdisplay, non_dsc_mode->vdisplay, > + non_dsc_mode->vrefresh, non_dsc_mode->name, > + igt_get_current_link_rate(data->drm_fd, data->output), > + igt_get_current_lane_count(data->drm_fd, data->output)); > + non_dsc_mode_found = true; > + break; > + } > + } > + igt_require_f(non_dsc_mode_found, > + "No non-DSC mode found on %s\n", > + igt_output_name(data->output)); > + > + > + /* Repeatedly force link failure until DSC is required (or link is disabled) */ > + while (!igt_get_dp_link_retrain_disabled(data->drm_fd, data->output)) { > + mon = igt_watch_uevents(); > + > + igt_assert_f(force_failure_and_wait(data, data->output, > + LT_FAILURE_REDUCED_CAPS, > + RETRAIN_COUNT, 1.0, 20.0), > + "Forcing DSC fallback timed out\n"); > + > + if (igt_get_dp_link_retrain_disabled(data->drm_fd, > + data->output)) { > + igt_reset_connectors(); > + igt_flush_uevents(mon); > + return; > + } > + > + igt_assert_f(wait_for_hotplug_and_check_bad(data->drm_fd, > + data, > + data->output, > + mon, > + 20.0), > + "Didn't get hotplug or link-status=BAD for DSC\n"); > + igt_flush_uevents(mon); > + > + outputs[output_count++] = data->output; > + set_connector_link_status_good(data, outputs, &output_count); > + igt_display_commit2(&data->display, COMMIT_ATOMIC); > + > + mode_to_check = igt_output_get_mode(data->output); > + > + if (igt_is_dsc_enabled(data->drm_fd, data->output->name)) { > + igt_info("mode %dx%d@%d now requires DSC with link rate %d and lane count %d\n", > + mode_to_check->hdisplay, mode_to_check->vdisplay, > + mode_to_check->vrefresh, > + igt_get_current_link_rate(data->drm_fd, data->output), > + igt_get_current_lane_count(data->drm_fd, data->output)); > + igt_info("DSC fallback successful on %s\n", > + igt_output_name(data->output)); > + dsc_fallback_successful = true; > + break; > + } else { > + igt_info("mode %dx%d@%d still doesn't require DSC\n", > + mode_to_check->hdisplay, mode_to_check->vdisplay, > + mode_to_check->vrefresh); > + } > + } > + igt_assert_f(dsc_fallback_successful, "DSC fallback unsuccessful\n"); > +} > + > +static bool run_lt_fallback_test(data_t *data) > { > bool ran = false; > igt_output_t *output; > @@ -366,6 +588,43 @@ static bool run_test(data_t *data) > return ran; > } > > +static bool run_dsc_sst_fallaback_test(data_t *data) > +{ > + bool ran = false; > + igt_output_t *output; > + > + if (!is_dsc_supported_by_source(data->drm_fd)) { > + igt_info("DSC not supported by source.\n"); > + return ran; > + } > + > + for_each_connected_output(&data->display, output) { > + data->output = output; > + > + if (!igt_has_force_link_training_failure_debugfs(data->drm_fd, > + data->output)) { > + igt_info("Output %s doesn't support forcing link training.\n", > + igt_output_name(data->output)); > + continue; > + } > + > + if (output->config.connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) { > + igt_info("Skipping output %s as it's not DP\n", output->name); > + continue; > + } > + > + if (!is_dsc_supported_by_sink(data->drm_fd, data->output)) { > + igt_info("Skipping output %s as DSC not supported by sink\n", > + igt_output_name(data->output)); > + continue; > + } > + > + ran = true; > + test_dsc_sst_fallback(data); > + } > + return ran; > +} > + > igt_main > { > data_t data = {}; > @@ -381,8 +640,13 @@ igt_main > } > > igt_subtest("dp-fallback") { > - igt_require_f(run_test(&data), > - "Skipping test as no output found or none supports fallback\n"); > + igt_require_f(run_lt_fallback_test(&data), > + "Skipping test as no DP output found or none supports forcing link fail\n"); > + } > + > + igt_subtest("dsc-fallback") { > + igt_require_f(run_dsc_sst_fallaback_test(&data), > + "Skipping test: DSC fallback conditions not met.\n"); > } > > igt_fixture { > diff --git a/tests/meson.build b/tests/meson.build > index 2cbd21c2a..dd75976dd 100644 > --- a/tests/meson.build > +++ b/tests/meson.build > @@ -367,7 +367,9 @@ extra_sources = { > 'kms_chamelium_frames': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ], > 'kms_chamelium_hpd': [ join_paths ('chamelium', 'kms_chamelium_helper.c') ], > 'kms_dsc': [ join_paths ('intel', 'kms_dsc_helper.c') ], > - 'kms_dp_linktrain_fallback': [join_paths ('intel', 'kms_mst_helper.c')], > + 'kms_dp_linktrain_fallback': [ > + join_paths ('intel', 'kms_mst_helper.c'), > + join_paths ('intel', 'kms_dsc_helper.c')], > 'kms_psr2_sf': [ join_paths ('intel', 'kms_dsc_helper.c') ], > } > ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-02-10 9:56 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-01-23 7:36 [PATCH i-g-t 0/3] add dsc-fallback test Kunal Joshi 2025-01-23 7:36 ` [PATCH i-g-t 1/3] tests/intel/kms_mst_helper: Add helper for MST-related functions Kunal Joshi 2025-01-27 7:17 ` Sharma, Swati2 2025-01-27 8:04 ` Joshi, Kunal1 2025-01-23 7:37 ` [PATCH i-g-t 2/3] tests/intel/kms_dp_linktrain_fallback: add dsc-fallback test Kunal Joshi 2025-01-23 7:37 ` [PATCH i-g-t 3/3] HAX: Do not merge Kunal Joshi 2025-01-23 8:22 ` ✗ GitLab.Pipeline: warning for add dsc-fallback test Patchwork -- strict thread matches above, loose matches on Subject: below -- 2025-01-27 6:29 [PATCH i-g-t 0/3] " Kunal Joshi 2025-01-27 6:29 ` [PATCH i-g-t 2/3] tests/intel/kms_dp_linktrain_fallback: " Kunal Joshi 2025-01-27 9:17 ` Sharma, Swati2 2025-02-10 9:56 ` Nautiyal, Ankit K
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox